DoubleZero’s software, as released, contains centralized elements. Off-chain private keys control core smart contracts and are required to run mandatory parts of the system which are not on-chain.
DoubleZero has represented that a no-action letter from the SEC confirms that the 2Z token flows to contributors on the DoubleZero network are not subject to the registration requirements under the Securities Acts. This characterization appears to be inconsistent with the system as deployed.
DoubleZero’s SEC no-action relief appears to have been obtained based on representations that are inconsistent with the system as run today. The deployed system differs materially from the representations made by the DoubleZero team to the SEC and to the public.
The SEC’s letter applies only to systems that operate consistently with the claims in DoubleZero’s request letter. To the extent the real DoubleZero system is inconsistent with that letter no relief was granted.
We have written before about these sorts of problems with DoubleZero’s no-action letter request in general.
Now, as all of DoubleZero’s software code is public, we will start to examine the ways in which DoubleZero as implemented does not match the claims it made to the SEC in its no-action letter request.
This is Part 1 of N. DoubleZero is complex, and even a single issue regarding the representations that DoubleZero made to the SEC may be sufficient to render the SEC’s no-action relief inapplicable.
The Sentinel
The system architecture diagram does not label this component as “
“Sentinel”:

But there is a section in that diagram labelled “DZ Resource Contributors” and if you read the instructions under “Initiate a Connection Request in DoubleZero” you find this passage:
Use the request-validator-access command to create an account on Solana for the connection request. The DoubleZero Sentinel agent detects the new account, validates its identity and signature, and creates the access pass in DoubleZero so the server can establish a connection.
The Sentinel agent watches for access requests and executes them, corresponding to the functionality described in the top-left corner of the architecture diagram.
As it so happens, the code for Sentinel is available in a repository called doublezero-offchain that is a Github repo under the DoubleZero Foundation described as “Offchain components for the DoubleZero Network” and which should have something to do with the “DZ Resource Contributors.” Again, there is a lot of naming overlap between the repo and the diagram.
If you go through that code you find a “keypair” variable in the Sentinel:
/// The path to the keypair file authorized in the passport program on Solana
/// and holding the oboarding DZ ledger funds to credit authorized validators
keypair: PathBuf,
That keypair is used to set up Solana access and kicks off a software object called the PollingSentinel:
let sentinel = PollingSentinel {
dz_rpc_client: DzRpcClient::new(dz_rpc, keypair.clone(), serviceability_id),
sol_rpc_client: SolRpcClient::new(sol_rpc, keypair),
processed_cache: Arc::new(Cache::new()),
poll_interval: Duration::from_secs(15),
previous_leader_epochs: 0,
};Notice the RPC clients use the keypair. RPC stands for Remote Procedure Call. This is not new or peculiar to web3 and has been around for some time. This is how one computer calls a function that exists somewhere else.
In this case the code we are examining is calling functions that live on blockchains. Blockchains are built around private keys and the idea that possession of the keys conveys ownership or control. The RPC invocations from the Sentinel use private keys which convey such ownership or control. This follows standard software engineering patterns adapted for blockchain systems.
What does this accomplish?
The PollingSentinel, as the name suggests, sits in a loop checking for new access requests as:
for access_id in new_requests {
let request_pda = access_id.request_pda;
match self.handle_access_request(access_id).await {
Ok(_) => {
// Only cache after successful processing
self.processed_cache.insert(request_pda, Instant::now(), CACHE_TTL).await;
}
Err(err) => {
error!(?err, "error encountered validating network access request; will retry on next poll");
// Don't cache failures - allow retry on next poll cycle
}
}
}We have extracted representative code sections to illustrate how this works.
This means extracting blocks from the middle of functions. Some setup code in Rust can be difficult to parse without proper tooling, so we focus on the core logic.
PollingSentinel watches for access requests and uses private keys passed on the command line to service requests via handle_access_request which does what the name suggests.
Even if you cannot follow the code you can follow the comments and log messages:
async fn handle_access_request(&self, access_id: AccessId) -> Result<()> {
let service_key = match &access_id.mode {
AccessMode::SolanaValidator(a) => a.service_key,
AccessMode::SolanaValidatorWithBackupIds { attestation, .. } => attestation.service_key,
};
info!(%service_key, request_pda = %access_id.request_pda, "handling access request");
let validator_ips = self.verify_qualifiers(&access_id.mode).await?;
if !validator_ips.is_empty() {
// Issue access passes for all validators (primary + backups)
for (validator_id, validator_ip) in validator_ips {
rpc_with_retry(
|| async {
self.dz_rpc_client
.issue_access_pass(&service_key, &validator_ip, &validator_id)
.await
},
"issue_access_pass",
)
.await?;
info!(%validator_id, %validator_ip, user = %service_key, "access pass issued");
}
let signature = rpc_with_retry(
|| async {
self.sol_rpc_client
.grant_access(&access_id.request_pda, &access_id.rent_beneficiary_key)
.await
},
"grant_access",
)
.await?;
info!(%signature, user = %service_key, "access request granted");
metrics::counter!("doublezero_sentinel_access_granted").increment(1);
} else {
let signature = rpc_with_retry(
|| async {
self.sol_rpc_client
.deny_access(&access_id.request_pda)
.await
},
"deny_access",
)
.await?;
info!(%signature, user = %service_key, "access request denied");
metrics::counter!("doublezero_sentinel_access_denied").increment(1);
}
Ok(())
}The important thing to notice is that “handling [an] access request” has a bunch of logic and this always involves a bunch of RPC calls. Those are calls to functions that live either on Solana or the DoubleZero blockchain.
Yes, that’s right, DoubleZero runs on a mixture of Solana and their own DoubleZero Ledger that is a fork of Solana, plus off-chain dependencies.
The calls to dz_rpc_client (to the DZ chain) and sol_rpc_client (to Solana) in that function are signed by the private keys that grant access to the passport program. So when this code calls grant_access() and issue_access_pass() and similar all of that is derivative of whoever is running the Sentinel having access to the right private keys. This process is gated by private keys. Ergo it is centralized. A working Sentinel cannot be run without these specific private keys.
Now remember “the keypair file authorized in the passport program on Solana” from above? That implies there is a passport program somewhere that also knows about the special keys. And indeed there is. If we go look we can see this central control on the passport program side too. Here is a snippet from inside the code that processes access requests within the passport program. This is the other side of some of the above RPC calls.
// Account 0 must be the program config.
// Account 1 must be the DoubleZero Ledger sentinel.
//
// This call ensures that the DoubleZero Ledger sentinel is a signer and is
// the same sentinel encoded in the program config.
let authorized_use =
VerifiedProgramAuthority::try_next_accounts(&mut accounts_iter, Authority::Sentinel)?;
This code ensures the Sentinel (the off-chain component described above) was involved in initiating the request. Further, it checks that the Sentinel is “encoded in the [passport] program config.” This is not consistent with an open, permissionless system. The code includes interlocking checks that specific private keys were used to initiate access requests to a network that represents itself as open and permissionless. These private keys provide exclusive control over the onboarding process.
Rather than examining additional code, we can turn to DoubleZero’s own documentation, which is explicit:
The service key must be generated and securely stored by the contributor before it is submitted to the DoubleZero Foundation for authorization. This ensures that all CLI interactions can be cryptographically verified and associated with the correct contributor account. [here]
Step 2 of “‘How to connect to DoubleZero in IBRL Mode — for RPC nodes” states:
2. Contact the DoubleZero Foundation
The DoubleZero foundation. You will need to provide your DoubleZeroID, your Validator ID (node ID), and the public ipv4 address you will be connecting from.
The documentation makes clear that users must contact the DoubleZero Foundation as part of the connection process. This requirement is inconsistent with a permissionless system.
Even if DoubleZero’s stated policy is to ‘not exercise discretion’ over this process, the Foundation retains control over it.
The documentation and code together establish that:
- A direct reference to “the keypair file authorized in the passport program on Solana” in code that then interacts in a privileged manner with said passport program.
- A clear statement the Foundation does “authorization”
- A requirement that users “provide your DoubleZeroID, your Validator ID (node ID), and the public ipv4 address you will be connecting from” to the Foundation.
The documentation alone makes this clear, regardless of one’s ability to parse the code.
The team’s own representations to the SEC demonstrate their understanding of these issues.
The No-Action Letter
The letter submitted to the SEC requesting no-action treatment includes the following paragraph:
Altogether, the Network Providers are sophisticated, independent operators in this system. They are responsible for integrating their links with the Network, installing the relevant FPGA devices, setting and then meeting their service levels, maintaining their links and ultimately disconnecting from the Network if they choose. None of the Network Providers are affiliates of the Foundation and neither the Foundation nor any other contributor performs these efforts on their behalf (beyond educating them and coordinating among Network Providers).
The doc also includes a footnote to that paragraph as:
The Foundation plays a limited role in helping Network Providers physically connect new fiber optic links to the Network. The Foundation does not earn revenue for these services and, at Launch, will not exercise discretion in accepting or rejecting Network Providers. The Foundation intends that this process will become fully permissionless over time.
The footnote claim is explicitly limited to assistance with physical connections and addresses only physical infrastructure assistance.
Even construing ‘physically’ broadly to include logical connections, the representation remains inconsistent with the system as deployed.
The prior section establishes that the Foundation must take certain actions for anyone to integrate their links with the Network.
Someone must run the Sentinel program using a specific set of private keys for the system to function. Whether additional centralization exists beyond this will be addressed in subsequent analysis.
Let’s just punt on that for now.
The evidence shows the Foundation is the sole provider of certain critical steps in the onboarding process. The request for no-action relief represented that the Foundation is not a central provider of critical system functions. The letter specifically carves out assistance with physical connections, noting an intent to eventually make this permissionless.
If this matter is litigated, questions may arise regarding whether no-action relief should be granted based on representations about future system changes.
The system as deployed, rather than stated future intentions, should determine whether regulatory requirements apply.
One might characterize the above as ‘coordinating among Network Providers,’ but this coordination occurs via a contract controlled through the owner’s private key.
If this form of ‘coordination’ qualifies as decentralized, the distinction between centralized and decentralized systems becomes meaningless for regulatory purposes.
Where Is The Code?
Notably, there are no links to block explorers with pointers to code and on-chain events. That is because, as far as we can tell, the code is not verified on Solana and there are no public lists of deployment addresses.
Here is a revenue distribution program that is part of DoubleZero:

The code is not verified on the public explorer. The documentation does not contain the contract addresses, and there is no repository location with deployment artifacts as is standard practice. Additionally, the code is upgradeable.
The contract addresses are hard-coded into code in the doublezero-solana repo so we know:
- revenue-distribution: dzrevZC94tBLwuHw1dyynZxaXTWyp7yocsinyEVPtt4
- passport: dzpt2dM8g9qsLxpdddnVvKfjkCLVXd82jrrQVJigCPV
Neither of which is verified and both of which are upgradeable, and nowhere is this easy to find.
Standard practice would include verified contracts with clearly documented addresses. While this information can be found through code inspection, the lack of standard documentation practices is notable.
Discussion
This analysis indicates the granted no-action relief may not apply to DoubleZero as deployed.
Additional context is relevant because DoubleZero’s request got SEC Commissioner Peirce to describe the SEC’s role in all of this as:
Our job is to engage with innovators in good faith, listen carefully as they explain how their models work, and apply our statutory mandate thoughtfully and with precision.
She also described the project as one that “programmatically distribute[s] [] tokens to users who participate in the network in accordance with network rules” which is true as far as it goes.
However, given the Foundation’s control over the distribution process, the level of centralization appears similar to traditional centralized systems.
Pierce’s statement appears to accept DoubleZero’s characterization of itself as an ‘open and distributed peer-to-peer network’ without accounting for the centralized control mechanisms identified above.
The request for no-action relief appears to differ materially from the actual DoubleZero system as deployed, yet following the SEC’s grant of relief, DoubleZero publicized this outcome extensively.
If the representations to the SEC were inconsistent with the deployed system, this raises questions about the no-action process and whether additional clarity from the Commission would be appropriate.
We know the SEC is about disclosure not review.
We do not expect the SEC to review whether a no-action request like this matches the system in question. That is not the SEC’s job and the no-action letter, rightly, includes this caveat:
This position is based on the representations made to the Division in your letter. Any different facts or conditions might require the Division to reach a different conclusion.
The SEC’s disclosure-based approach does not preclude addressing situations where no-action relief may have been obtained based on materially inaccurate representations.
DoubleZero continues to rely on the no-action relief in its promotional activities. Any future enforcement action would likely involve questions about the applicability of the no-action relief to the system as deployed.
The longer the current situation persists, the more embedded the reliance on the no-action relief becomes.
The code is public and can be analyzed. Material discrepancies between the no-action request and the deployed system can be identified.
To the extent the system differs from the representations in the request letter, the relief may not apply. The team’s subjective belief about the relief’s applicability is distinct from the legal question of whether it applies.
What matters is that the team can go out and point to a no-action letter that does not apply to their project and make claims the average person cannot tell are transparently false because they lack the skills to make that kind of determination.
Regulatory action should be based on thorough investigation rather than third-party analysis.
Public clarification from the Commission regarding the applicability of no-action letters when material facts differ from representations would be invaluable.
Clarification regarding when materially inaccurate representations in no-action requests may warrant enhanced scrutiny would help establish clearer boundaries. Without such clarification, the utility of the no-action process for establishing regulatory compliance may be compromised.

DoubleZero Is Centralized And Misled The SEC: Part 1 of N was originally published in ChainArgos on Medium, where people are continuing the conversation by highlighting and responding to this story.





