Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: check recipient against blocklist client in withdrawals #1428

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

MCJOHN974
Copy link
Collaborator

@MCJOHN974 MCJOHN974 commented Feb 24, 2025

Description

Closes: #1415

Changes

  • Now we check recipient against blocklist client in withdrawals, not sender as it was before.
  • Improved a bit error handling

Testing Information

  • I added no new tests but as I see same function for deposits also don't have such a test. Considering that this function is pretty small, simple, and can't lead to critical bug we probably ok with that

Checklist:

  • I have performed a self-review of my code
  • My changes generate no new warnings
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

@@ -607,11 +607,20 @@ pub enum Error {
/// Bitcoin error when attempting to construct an address from a
/// scriptPubKey.
#[error("bitcoin address parse error: {0}; txid {txid}, vout: {vout}", txid = .1.txid, vout = .1.vout)]
BitcoinAddressFromScript(
BitcoinAddressFromScriptWithOutpoint(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really happy with this naming but I don't really see which outpoint we can attach to withdrawals, thus it is okish I think

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For deposits it's not necessarily the "outpoint" itself that we're interested in, it's just that the outpoint is the unique identifier of the deposit request; for withdrawals, it's the request_id (+ its block_hash to identify it across forks). I might opt to name these WithdrawalBitcoinAddress and DepositBitcoinAddress or something along those lines, and have the withdrawal version accept its request id and block hash.

@MCJOHN974 MCJOHN974 marked this pull request as ready for review February 24, 2025 09:16
@MCJOHN974 MCJOHN974 self-assigned this Feb 24, 2025
@MCJOHN974
Copy link
Collaborator Author

Btw, about issue itself. I can see why we checking recipient is more important then sender:
transferring funds to blocklisted address can put transferrer in trouble, while locking & burning coins from blocklisted address probably is not so dangerous

But if my intuition is correct why we do not check recipient in deposits? Because we mint coins for them and not directly transfer?

And very final question: why don't we want to check both sender and recipient agains blocklist?

pinging @djordon as author of issue

@cylewitruk
Copy link
Member

cylewitruk commented Feb 24, 2025

Btw, about issue itself. I can see why we checking recipient is more important then sender: transferring funds to blocklisted address can put transferrer in trouble, while locking & burning coins from blocklisted address probably is not so dangerous

But if my intuition is correct why we do not check recipient in deposits? Because we mint coins for them and not directly transfer?

And very final question: why don't we want to check both sender and recipient agains blocklist?

The sender/recipient is always a stacks/bitcoin address pair and I'm not sure that there are any sanctions for Stacks addresses (at least in OFAC or the EU sanctions list). Nor am I sure if Chainalysis does any specific forensic/clustering analysis on the Stacks blockchain that would enable their screening service to properly screen Stacks addresses?

However, the blocklist client is intended to be able to be swapped out for a custom implementation, which may include a signer's own risk analysis/database supporting STX addresses, so I do think that we should eventually be sending the request for both and that our implementation simply filters out Stacks addresses for now. But in practice, all of the signers are using Chainalysis at the moment, so there's no direct demand for supporting STX addresses.

let receiver_address = bitcoin::Address::from_script(&receiver_pubkey, network.params())
.map_err(|err| Error::BitcoinAddressFromScript(err, receiver_pubkey.into()))?;

let can_accept = client
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we don't have them today or for deposits either, but I wouldn't be sad if a test or two popped up ensuring that this error is actually returned if the receiver pubkey is bad/network mismatch/etc.

@MCJOHN974
Copy link
Collaborator Author

However, the blocklist client is intended to be able to be swapped out for a custom implementation, which may include a signer's own risk analysis/database supporting STX addresses, so I do think that we should eventually be sending the request for both and that our implementation simply filters out Stacks addresses for now. But in practice, all of the signers are using Chainalysis at the moment, so there's no direct demand for supporting STX addresses.

Until our canonical blocklist implementation returns ok on addresses it don't know I think nothing stops us to test both stacks and bitcoin addresses now. However, delaying it can lead to forgetting, thus I'd suggest to implement it now

@MCJOHN974
Copy link
Collaborator Author

Hey, @cylewitruk, I added some test for both deposits and withdrawals. It is not isolating only this can_accept function, but it look nice I think

@MCJOHN974 MCJOHN974 requested a review from cylewitruk February 25, 2025 13:36
assert_eq!(decisions.len(), 1);
assert_eq!(decisions.last().unwrap().is_accepted, !is_blocked);
assert!(!votes.is_empty());
assert!(votes.iter().any(|vote| {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh a bit annoying that get_withdrawal_request_signer_votes and get_deposit_signer_decisions are different =)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is get_deposit_request_signer_votes(), is that maybe what you meant to use?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally it was test for deposits which I rebranded to both deposits and withdrawals. It was using get_deposit_signer_decisions, and get_deposit_signers. I keep them and tried to find the closest signer analogues, but get_withdrawal_signer_decisions doesn't exist. But anyway I think that this functions are fine and we extract what we want in both deposits and withdrawals

@djordon
Copy link
Collaborator

djordon commented Feb 26, 2025

Btw, about issue itself. I can see why we checking recipient is more important then sender: transferring funds to blocklisted address can put transferrer in trouble, while locking & burning coins from blocklisted address probably is not so dangerous

But if my intuition is correct why we do not check recipient in deposits? Because we mint coins for them and not directly transfer?

And very final question: why don't we want to check both sender and recipient agains blocklist?

pinging @djordon as author of issue

What Cyle wrote in #1428 (comment) is spot on. We don't check the Stacks side because we do not think that the signers need to. If that changed then we may have to change the code here.

@djordon djordon mentioned this pull request Feb 26, 2025
6 tasks
@djordon djordon added the sbtc signer binary The sBTC Bootstrap Signer. label Mar 3, 2025
@djordon djordon changed the title [feat]: check recipient against blocklist client in withdrawals fix: check recipient against blocklist client in withdrawals Mar 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sbtc signer binary The sBTC Bootstrap Signer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Fix up blocklist client interactions for withdrawals
3 participants