Six OFAC-sanctioned transactions missing
A pool from Asia is the first to comply with US sanctions?
Monday, November 20, 2023My project, miningpool-observer, aims to detect when Bitcoin mining pools are not mining transactions they could have been mining. Over the past few weeks, it detected six missing transactions spending from OFAC-sanctioned addresses. This post examines whether these transactions were intentionally filtered because they spent from OFAC-sanctioned addresses or if there are other possible explanations for these transactions to be missing from blocks. I conclude that four out of six transactions were likely filtered.
In September and October 2023, the RSS feed of my miningpool-observer instance reported six blocks missing an OFAC-sanctioned transaction. One block was mined by the ViaBTC mining pool, another by the Foundry USA pool, and four by F2Pool. An OFAC-sanctioned transaction is a transaction spending from or paying to an address sanctioned by the US Department of the Treasury’s Office of Foreign Assets Control. I maintain a tool to extract a list of OFAC-sanctioned addresses from the Specially Designated Nationals (SDN) list published by the OFAC.
Several reasons could explain why a transaction might be absent from a block. Generally, transactions do not propagate equally through the network, and there is no global mempool to pick transactions from. Each node has its own set of valid transactions. A pool might also prioritize transactions for which it received an out-of-band payment. However, it might also deprioritize or filter transactions.
The goal here is to determine if the mining pool filtered any of these six OFAC-sanctioned transactions or if there are other possible explanations for their absence from the block1. Note that mining pools are free to choose which transactions to include and which to leave out. However, to analyze Bitcoin’s censorship-resistant properties, it’s crucial to understand which pools and how many of them are filtering transactions.
I conclude that the reports from miningpool-observer indicating sanctioned transactions missing from blocks by ViaBTC and Foundry are likely false-positives and not the result of filtering. The transactions missing from F2Pool’s blocks are, however, likely filtered. All missing transactions have been picked up by other miners 2.
Block 808660 by ViaBTC
Block 808660 ..866c79c5
3, mined by ViaBTC on September 21, 2023,
did not include transaction 262025e7..
4. This transaction
consolidates 100 inputs into one output. One of these inputs spends an output
paid to 1ECeZBxCVJ8Wm2JSN3Cyc6rge2gnvD3W5K
. This address was added
to the OFAC’s SDN list on September 21st, 2021.
The transaction has a size of 14.7 kvB and pays a feerate of 25.18 sat/vByte. The output spent from the sanctioned address is 0.0002 BTC (20k sat) and was only created a day before. When ViaBTC mined block 808660, the transaction had been in my node’s mempool for about 75 minutes. It did not have any dependency on in-mempool transactions.
Examining the feerate distribution of block 808660 on miningpool.observer, reveals that ViaBTC occupied about 1 MWU worth of block space, of a total of 4 MWU, with prioritized transactions. These likely stem from the ViaBTC Bitcoin Transaction Accelerator. Prioritizing some transactions means that lower feerate transactions, such as the transaction spending from the sanctioned address here, don’t make it into the block. For this ViaBTC block, my miningpool-observer instance lists 24 large consolidation transactions at the end of the template that didn’t make it into this block.
This leads to the conclusion that ViaBTC did not filter this transaction. It got displaced by other, prioritized transactions. This is supported by the fact that, three days later, ViaBTC mined a transaction 5 spending an output from the same sanctioned address in block 809181.
Block 813231 by Foundry USA
Block 813231 ..0a8528b6
6, mined by Foundry USA on October 21st,
2023, did not include the transaction c9b57191..
7. This transaction
consolidates 150 inputs into one output. One of the inputs spends an output
paid to 3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML
8. This address was
added to the OFAC’s SDN list on April 14th, 2023.
As most of the 150 inputs are 2-of-3 multisig P2SH scripts, the missing transaction is large at 43842 vByte. It pays a feerate of 5.09 sat/vByte and had no dependencies on in-mempool transactions. This feerate was enough to place it at position 161 out of 2215 transactions in the template constructed by my Bitcoin Core node. However, this transaction, along with 18 other transactions, had only been in my mempool for around 30 seconds when I learned about block 812331 by Foundry USA. This makes it likely that Foundry didn’t have a chance to include the transaction in their block because they didn’t know about it yet.
It might take a few seconds for the transaction to propagate. Additionally, most pools only push new block templates to miners every 30 seconds, which then take a while to switch to the new job. Furthermore, the miningpool-observer tool requests new block templates every few seconds and does best-effort matching based on the minimum difference in missing and extra transactions (see Methodology in the FAQ). This makes false-positives for young transactions, probably up to around 60 seconds, possible.
The mempool.space block explorer also keeps track of differences between block
templates and the final blocks broadcast by miners. They show that c9b57191..
is
included in their template but missing from the actual block. The transaction is
tagged “recently broadcasted” by them too.
This leads to the conclusion that Foundry USA did not filter this transaction. The transaction was broadcast too late to be included in the mining job that ended up finding block 813231. In addition, Foundry USA also mined the next block at height 813232 and included the sanctioned transaction there.
Blocks 810727, 811791, 811920, and 813357 by F2Pool
F2Pool mined the block 810727 ..ccda1498
on October 5th, 2023, the blocks
811791 ..af4453d6
and 811920 ..00badf62
on October 12th, and the block
813357 ..63ac1669
on October 22nd 9. Each block is missing one
sanctioned transaction10. Each of these transactions consolidates 150
2-of-3 multisig inputs into one output. For each transaction, one of the inputs
spends an output paid to 3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML
. This is the same
consolidation pattern and address as discussed in the previous section. None of
the missing transactions had a dependency on in-mempool transactions.
Block 810727
In block 810727, F2Pool did not include the transaction c6a66836..
10,
which spends a sanctioned output. Due to the 150 2-of-3 multisig inputs, the
transaction is rather large at 44017 vBytes. It pays a fee of 446260 sat and
had been in my node’s mempool for nearly 4 hours when F2Pool mined block 810727.
Instead of c6a66836..
, F2Pool chose to include the transaction 907e1f45..
11.
This transaction is also a consolidation transaction with 150 inputs and
one output, but does not spend from a sanctioned output. It pays the
same fee of 446260 sat but happens to be 3 vByte larger12
at 44020 vByte. This means the missing transaction c6a66836..
has a
slightly higher feerate than 907e1f45..
. When strictly sorting by feerate,
the missing transaction should have been included. However, in practice, it’s
unlikely that 3 vByte of additional block space will make a difference in the
total fees in the block.
Block 811791
The sanctioned transaction aa001ce6..
10 is missing from F2Pools
block 811791. Similar to the previous consolidation transactions, this
transaction has a size of 42459 vBytes (169836 WU). With a fee of 446260 sat
it pays a feerate of 10.5 sat/vByte. When block 811791 arrived at the
miningpool-observer node, the transaction had been in its mempool for four
minutes.
In this block, it’s notable that five transactions with OP_RETURN Stacks block commitments are missing. F2Pool has, however, inserted their own Stacks block commitment. This happens regularly and has been reported before. Additionally, F2Pool is including two large, zero-fee transactions in their block. One consolidates previous F2Pool coinbase outputs, and the other is a payout transaction to miners. This is common behavior for blocks mined by F2Pool.
While these extra transactions take up more than 400 kWU of block space, there
would still have been enough space to include transaction aa001ce6..
. The block
includes 2.86 MWU of transactions below aa001ce6..
’s feerate of 10.5
sat/vByte. This transaction, with about 170 kWU, would have fit into the block.
On mempool.space, this transaction is marked as “removed”,
which negatively affects their block health metric.
Block 811920
In block 811920, F2Pool did not include transaction 1cb3d6bc..
10,
which spends a sanctioned output. This transaction is a large consolidation
transaction as well. It has a size of 43630 vBytes (169836 WU) and, with a fee
of 44660 sat it pays a feerate of 10.23 sat/vByte. When block 811920
arrived at the miningpool-observer node, the transaction had been in the node’s
mempool for close to 2 minutes.
In block 811920, 1.44 MWU of transactions pay less than 10.23 sat/vByte.
The 170 kWU transaction 1cb3d6bc..
would have fit into the block. As
the transaction was in my node’s mempool for only close to two minutes, there
is a possibility that it didn’t yet propagate to F2Pool when they were
building their block template. The transaction is shown as “recently broadcast”
on mempool.space, too. Usually, mining pools
try to have good connectivity to the Bitcoin network. There is a high likelihood
that the transaction was in F2Pool’s mempool if it was in mempool.space’s and
miningpool.observer’s mempool.
Block 813357
In F2Pool’s block 813357, the transaction e49cdb60..
10,
which spends a sanctioned output, is missing. This consolidation transaction
has a size of 43053 vBytes (172209 WU). With a fee of 178504 sat it pays
a feerate of 4.15 sat/vByte. When block 813357 arrived at the
miningpool-observer node, the transaction had been in the node’s mempool for
more than 25 minutes.
There are 684 kWU of transactions paying below 4.15 sat/vByte in block 813357.
The 172 kWU transaction e49cdb60..
would have fit into the block. As the
transaction was in my node’s mempool for more than 25 minutes, it’s unlikely that
the transaction didn’t propagate to one of F2Pools nodes yet. The transaction
was included in mempool-space’s template for block 813357
too.
Conclusion on F2Pools blocks
The sanctioned transaction missing from block 810727 had a slightly higher feerate because it’s 3 vByte smaller than the included transaction. While, in this case, these 3 vBytes of extra block space wouldn’t have made a difference in total fees, the Bitcoin Core block templating algorithm would have chosen the transaction with the higher feerate. The large extra transactions included in block 811791 wouldn’t have had an effect on the sanctioned transaction missing from block 811791. It has likely been filtered from the block. The block audit on mempool.space agrees with this. There is a chance that F2Pool didn’t yet know about the missing sanctioned transaction from block 811920. However, 2 minutes should be enough for a large pool to receive a transaction. Especially since mempool.space and miningpool.observer knew about this transaction. It’s likely that this sanctioned transaction is missing because F2Pool filtered it. Similar to the missing transaction from block 811791, the missing transaction from block 813357 has likely been filtered by F2Pool.
These four missing sanctioned transactions lead to the conclusion that F2Pool
is currently filtering transactions. Since we’ve only seen transactions spending
from the single OFAC-sanctioned address 3PKiHs4GY4rFg8dpppNVPXGPqMX6K2cBML
missing, we can’t tell if F2Pool is filtering this single address or all OFAC-
sanctioned addresses.
Conclusion
This post discusses six Bitcoin transactions spending from OFAC-sanctioned addresses that the miningpool-observer tool detected as missing from blocks. The two transactions missing from the ViaBTC and Foundry USA pool blocks are false-positives and not filtered. The four OFAC-sanctioned transactions missing from the F2Pool blocks are likely filtered. This raises the question of why F2Pool, a pool with origins in Asia, is the first pool to filter transactions based on US OFAC sanctions.
The Bitcoin network, however, continues to work as normal. A single pool filtering transactions does not affect the censorship resistance of the Bitcoin network as a whole. Further monitoring of the transaction selection of mining pools allows identifying when more pools start to filter transactions based on, for example, OFAC sanctions. It also allows miners pointing their hashrate to these pools to make an informed decision on switching to a different pool if they don’t agree with a pool’s (unannounced) filtering policies.
Update 2023-11-23
After publishing this blog post, F2Pool Co-Founder @satofishi tweeted that F2Pool was indeed filtering these transactions. He followed up with a statement that F2Pool would disable the filtering for now. Both tweets have since been deleted. The second tweet is archived on archive.ph. After deleting the tweet that the transaction filtering patch is disabled for now, it is unclear if F2Pool is still filtering transactions. 2
As all blocks with missing transactions didn’t come close to the sigop limit of 80.000, these aren’t discussed here. ↩︎
ViaBTC block 808660:
000000000000000000017c18a76632d9e39e8c388ee1e4028ec75e50866c79c5
Transaction missing from block 808660:
262025e73812fc68b6514ea366abf463147176c7867e5853f117aded58c30e0e
The transaction
cb9f2592..
mined in block 809181 by ViaBTC is an Omnilayer transaction transferring 1528 USDT deposited to this address in September, 2020. The output to the sanctioned address1ECeZBxCVJ8Wm2JSN3Cyc6rge2gnvD3W5K
for this transaction was created similarly to the transaction262025e7..
missing from block 808660 ind11019a2..
.I checked a few of these addresses and they all contained USDT balances on OmniLayer which were swept in these transactions. While this is a guess, it seems someone wanted to sweep the remaining USDT on a bunch of addresses, sent 20k sats to each of them, and messed up the sweep by consolidating the newly created outputs again in
262025e7..
. They then retried withd11019a2..
and successfully swept it withcb9f2592..
.If that’s the case, then OFAC is likely missing a bunch of addresses by the same entity on their list. ↩︎
Block 813231 mined by Foundry has the header hash:
00000000000000000001740d5fbb8bbc0b93d4bf46ca2011f642e92a0a8528b6
Missing sanctioned transaction from block 813231 has the txid:
c9b5719131bfeac6378749243731c5e70f1ce56deabb7006a2b6539710866420
Based on OXT.me data, this address belongs to an OKEX wallet. The consolidation transaction
↩︎c9b57191..
is OKEX consolidating deposits. The output being consolidated is, according to OXT.me, a Hydra darknet market payout. Additional information can be found here.Block hashes:
- 810727:
0000000000000000000350ae5ee08a4415146612af59a20021efeaf2ccda1498
- 811791:
00000000000000000001631243b00b6c1019c0d833b6738e0c591dacaf4453d6
- 811920:
00000000000000000002efd0fc8801b149f505b125308a35c584ed2600badf62
- 813357:
00000000000000000000519c33dcdf5ca386524b2cbacb561f767e9663ac1669
- 810727:
Missing, sanctioned transactions:
- 810727:
c6a668364f19df0f2977f8ad7d0a3a73c5e32b55b6a7c650cafa37a5ab4b19f2
- 811791:
aa001ce6e262b8b9042645ecdec9c84e9e2ad06f56dff6dd5ae42005fdea8da9
- 811920:
1cb3d6bcc650c2891b68e7b205d601bcf5158e30e1926d0fd0c8385cb456b37b
- 813357:
e49cdb6075c49b8fc37b3e922038e2a3205d75a9a1fb4b69f3568707594c2d3e
- 810727:
Slightly larger and thus lower feerate transaction F2Pool picked for block 810727:
907e1f45334652dd344cf846639f3f9a2ee11b5489e2ffc2660ea543881b1bce
Likely because it has fewer low-r nonces in the signatures which makes the signatures larger. ↩︎