# Staking Security API > Check caller-supplied EIP-3076 signing histories, validator deployment inventories, and withdrawal credentials. No network calls are made. Each POST has a fixed USDC price on Base, paid with the x402 exact scheme. The request is validated first, and payment settles only after a successful (2xx) result. Failed calls are not charged. 1. POST JSON matching the requestBody. Invalid input returns 400 with no payment challenge. 2. A valid unpaid call returns 402 with the exact amount and payTo. 3. Pay and retry with payment-signature. Payment settles only if the operation returns 2xx. A 4xx/5xx is not charged. - Product: https://www.brainiac.software/api/staking-security - Docs: https://www.brainiac.software/api/staking-security/docs - OpenAPI: https://www.brainiac.software/api/staking-security/openapi.json - Contact: support@brainiac.software (https://www.brainiac.software/contact) ## Operations ### POST /api/v1/staking-security/validator-slashing-protection-audit $0.05 USDC. Check caller-supplied EIP-3076 version 5 slashing-protection interchanges before validator history is imported or reused. A double proposal is two different blocks at the same slot. A double vote is two different attestations with the same target epoch. A surround vote has an earlier source epoch and a later target epoch than the vote it surrounds. audit_status is safe, conflicts_detected, warnings, invalid, or incomplete. risk_level is low, medium, high, or critical. Identical records without signing_root are not a confirmed slash. The export is not a complete signing history and does not protect against a later signature. No private key is accepted and no beacon node is queried. Inputs: interchange, comparison?, pubkeys?, network? Docs: https://www.brainiac.software/api/staking-security/docs#staking-security-validator-slashing-protection-audit Example request: ```json { "interchange": { "metadata": { "interchange_format_version": "5", "genesis_validators_root": "0x1111111111111111111111111111111111111111111111111111111111111111" }, "data": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "signed_blocks": [ { "slot": "8", "signing_root": "0x0101010101010101010101010101010101010101010101010101010101010101" }, { "slot": "8", "signing_root": "0x0202020202020202020202020202020202020202020202020202020202020202" } ], "signed_attestations": [ { "source_epoch": "1", "target_epoch": "10", "signing_root": "0x0303030303030303030303030303030303030303030303030303030303030303" }, { "source_epoch": "3", "target_epoch": "10", "signing_root": "0x0606060606060606060606060606060606060606060606060606060606060606" }, { "source_epoch": "4", "target_epoch": "6", "signing_root": "0x0404040404040404040404040404040404040404040404040404040404040404" }, { "source_epoch": "4", "target_epoch": "6", "signing_root": "0x0404040404040404040404040404040404040404040404040404040404040404" } ] } ] }, "comparison": { "metadata": { "interchange_format_version": "5", "genesis_validators_root": "0x1111111111111111111111111111111111111111111111111111111111111111" }, "data": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "signed_blocks": [], "signed_attestations": [ { "source_epoch": "2", "target_epoch": "3", "signing_root": "0x0505050505050505050505050505050505050505050505050505050505050505" } ] }, { "pubkey": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "signed_blocks": [ { "slot": "1", "signing_root": "0x0707070707070707070707070707070707070707070707070707070707070707" } ], "signed_attestations": [] } ] }, "pubkeys": [ "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ], "network": { "name": "mainnet", "genesisValidatorsRoot": "0x1111111111111111111111111111111111111111111111111111111111111111" } } ``` Example response: ```json { "audit_status": "conflicts_detected", "risk_level": "critical", "validators_analyzed": 2, "slashable_conflicts": [ { "kind": "surround", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "datasets": [ "interchange" ], "source_epochs": [ "1", "4" ], "target_epochs": [ "10", "6" ], "signing_roots": [ "0x0303030303030303030303030303030303030303030303030303030303030303", "0x0404040404040404040404040404040404040404040404040404040404040404" ], "detail": "The attestation with source epoch 1 and target epoch 10 surrounds the attestation with source epoch 4 and target epoch 6. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." }, { "kind": "surround", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "datasets": [ "interchange" ], "source_epochs": [ "3", "4" ], "target_epochs": [ "10", "6" ], "signing_roots": [ "0x0404040404040404040404040404040404040404040404040404040404040404", "0x0606060606060606060606060606060606060606060606060606060606060606" ], "detail": "The attestation with source epoch 3 and target epoch 10 surrounds the attestation with source epoch 4 and target epoch 6. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." }, { "kind": "surround", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "datasets": [ "interchange", "comparison" ], "source_epochs": [ "1", "2" ], "target_epochs": [ "10", "3" ], "signing_roots": [ "0x0303030303030303030303030303030303030303030303030303030303030303", "0x0505050505050505050505050505050505050505050505050505050505050505" ], "detail": "The attestation with source epoch 1 and target epoch 10 surrounds the attestation with source epoch 2 and target epoch 3. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." }, { "kind": "double_vote", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "datasets": [ "interchange" ], "source_epochs": [ "1", "3" ], "target_epochs": [ "10" ], "signing_roots": [ "0x0303030303030303030303030303030303030303030303030303030303030303", "0x0606060606060606060606060606060606060606060606060606060606060606" ], "detail": "Attestations for target epoch 10 are not the same vote. This is a Casper FFG double vote in the supplied records." }, { "kind": "double_proposal", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "datasets": [ "interchange" ], "slots": [ "8" ], "signing_roots": [ "0x0101010101010101010101010101010101010101010101010101010101010101", "0x0202020202020202020202020202020202020202020202020202020202020202" ], "detail": "Slot 8 has signed blocks with different signing roots. This is a proposer slashing condition in the supplied records." } ], "duplicate_records": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "kind": "attestation", "count": 2, "source_epoch": "4", "target_epoch": "6", "signing_root": "0x0404040404040404040404040404040404040404040404040404040404040404", "detail": "The same attestation for source epoch 4 and target epoch 6 is repeated 2 times. A repeated record is not a second vote." } ], "missing_records": [ { "pubkey": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "datasets": [ "interchange" ], "detail": "This public key is not in the interchange." } ], "conflicting_histories": [ { "kind": "surround", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "datasets": [ "interchange", "comparison" ], "source_epochs": [ "1", "2" ], "target_epochs": [ "10", "3" ], "signing_roots": [ "0x0303030303030303030303030303030303030303030303030303030303030303", "0x0505050505050505050505050505050505050505050505050505050505050505" ], "detail": "The attestation with source epoch 1 and target epoch 10 surrounds the attestation with source epoch 2 and target epoch 3. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." } ], "findings": [ { "code": "surround_vote", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The attestation with source epoch 1 and target epoch 10 surrounds the attestation with source epoch 4 and target epoch 6. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." }, { "code": "surround_vote", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The attestation with source epoch 3 and target epoch 10 surrounds the attestation with source epoch 4 and target epoch 6. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." }, { "code": "surround_vote", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The attestation with source epoch 1 and target epoch 10 surrounds the attestation with source epoch 2 and target epoch 3. The inner vote is surrounded. This is a Casper FFG surround vote in the supplied records." }, { "code": "double_vote", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "Attestations for target epoch 10 are not the same vote. This is a Casper FFG double vote in the supplied records." }, { "code": "double_proposal", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "Slot 8 has signed blocks with different signing roots. This is a proposer slashing condition in the supplied records." }, { "code": "duplicate_attestation", "severity": "medium", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The same attestation for source epoch 4 and target epoch 6 is repeated 2 times. A repeated record is not a second vote." }, { "code": "validator_missing", "severity": "medium", "pubkey": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "detail": "This public key is not in the interchange." }, { "code": "export_not_complete", "severity": "low", "detail": "The supplied interchange is not a complete signing history. This audit does not protect against a later signature or a signature that was left out of the file." } ], "limitations": [ "Only the supplied EIP-3076 records are checked. An export is not a complete signing history.", "This does not protect against a signature made after the export or omitted from it.", "A double proposal is two different blocks at the same slot. A double vote is two different attestations with the same target epoch. A surround vote has an earlier source epoch and a later target epoch than the vote it surrounds. These are the phase 0 proposer and Casper FFG attester conditions.", "signing_root is optional in EIP-3076. Identical slot or epoch records without a signing_root are not reported as a confirmed slash.", "Attestation slot, committee index, and beacon block root are not in the interchange. They are compared only when a signing_root is present.", "Public keys are checked as 48-byte hex. They are not checked as BLS12-381 points. Private keys are not accepted.", "No beacon node was queried and no signature is verified.", "network.name is a caller label. genesisValidatorsRoot is compared only with the roots in the request." ] } ``` ### POST /api/v1/staking-security/validator-key-deployment-conflict-audit $0.05 USDC. Compare a caller-supplied validator deployment inventory for duplicate active public keys, simultaneous primary and backup activation, overlapping activation windows, and failover rules that disagree. Windows are absolute instants, including offsets. An inactive standby covered by an exclusive failover rule is not treated as concurrent. audit_status is clean, conflicts_detected, warnings, or incomplete. risk_level is low, medium, high, or critical. Activation status is an assertion. No host is contacted and no private key is read. Inputs: deployments, maintenanceWindows?, failoverRules?, expectedTopology? Docs: https://www.brainiac.software/api/staking-security/docs#staking-security-validator-key-deployment-conflict-audit Example request: ```json { "deployments": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environment": "prod-a", "node": "cluster-a", "role": "primary", "activation": "active", "owner": "ops", "activationWindow": { "start": "2026-01-01T00:00:00Z", "end": "2026-01-02T00:00:00Z" } }, { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environment": "prod-b", "node": "cluster-b", "role": "backup", "activation": "active", "activationWindow": { "start": "2026-01-01T12:00:00+00:00", "end": "2026-01-01T20:00:00+01:00" } } ], "maintenanceWindows": [ { "environment": "prod-a", "start": "2026-02-01T00:00:00Z", "end": "2026-02-01T01:00:00Z" } ], "failoverRules": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environments": [ "prod-a", "prod-b" ], "exclusive": true } ], "expectedTopology": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environment": "prod-a", "node": "cluster-a", "role": "primary", "activation": "active" } ] } ``` Example response: ```json { "audit_status": "conflicts_detected", "risk_level": "critical", "duplicate_validator_keys": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environments": [ "prod-a", "prod-b" ], "nodes": [ "cluster-a", "cluster-b" ], "roles": [ "backup", "primary" ], "detail": "The inventory marks a primary and a backup, standby, or recovery deployment active at the same time. Activation status is an assertion, not a live process check." } ], "concurrent_deployments": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environments": [ "prod-a", "prod-b" ], "nodes": [ "cluster-a", "cluster-b" ], "roles": [ "backup", "primary" ], "activations": [ "active" ], "detail": "The inventory marks a primary and a backup, standby, or recovery deployment active at the same time. Activation status is an assertion, not a live process check." } ], "overlapping_activation_windows": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environments": [ "prod-a", "prod-b" ], "windows": [ { "environment": "prod-a", "start": "2026-01-01T00:00:00Z", "end": "2026-01-02T00:00:00Z" }, { "environment": "prod-b", "start": "2026-01-01T12:00:00+00:00", "end": "2026-01-01T20:00:00+01:00" } ], "detail": "Activation windows for prod-a and prod-b overlap. Instants include their offsets, and a shared endpoint is not an overlap. This does not show that a validator process is running." } ], "failover_conflicts": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "environments": [ "prod-a", "prod-b" ], "exclusive": true, "detail": "The inventory marks more than one covered environment active while the failover rule requires exclusive activation." } ], "affected_environments": [ { "environment": "prod-a", "pubkeys": [ "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ], "detail": "This environment is named on a conflicting inventory record. Activation status is an assertion, not a live process check." }, { "environment": "prod-b", "pubkeys": [ "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ], "detail": "This environment is named on a conflicting inventory record. Activation status is an assertion, not a live process check." } ], "findings": [ { "code": "duplicate_validator_key", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The inventory marks a primary and a backup, standby, or recovery deployment active at the same time. Activation status is an assertion, not a live process check." }, { "code": "concurrent_activation", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The inventory marks a primary and a backup, standby, or recovery deployment active at the same time. Activation status is an assertion, not a live process check." }, { "code": "activation_window_overlap", "severity": "high", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "Activation windows for prod-a and prod-b overlap. Instants include their offsets, and a shared endpoint is not an overlap. This does not show that a validator process is running." }, { "code": "failover_conflict", "severity": "high", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The inventory marks more than one covered environment active while the failover rule requires exclusive activation." }, { "code": "owner_missing", "severity": "medium", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The prod-b record has no environment owner." }, { "code": "topology_unexpected", "severity": "medium", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "prod-b has a backup record that is not in the expected topology." }, { "code": "inventory_not_live", "severity": "low", "detail": "These records are caller-supplied assertions. The audit does not show that a validator process is running or stopped." } ], "limitations": [ "This is an inventory comparison. Activation status does not mean a validator process is running or stopped.", "No host was contacted and no private key was read.", "Public keys are checked as 48-byte hex. They are not checked as BLS12-381 points.", "Activation windows are compared as absolute instants. A window that only touches another window at an endpoint does not overlap it.", "An inactive standby covered by an exclusive failover rule is not reported as a concurrent deployment.", "An overlap inside a maintenance window is not reported when an exclusive failover rule covers both environments.", "Expected topology is compared only when expectedTopology is supplied." ] } ``` ### POST /api/v1/staking-security/validator-withdrawal-credential-audit $0.05 USDC. Compare caller-supplied Ethereum validator withdrawal credentials with expected types, withdrawal addresses, and ownership mappings. 0x00 is a BLS credential and the other 31 bytes are a hash fragment, not an address. 0x01 and 0x02 decode an execution address only when the next 11 bytes are zero. audit_status is valid, mismatched, warnings, invalid, or incomplete. risk_level is low, medium, high, or critical. A match is not proof of control and was not read from a beacon node. Inputs: validators, expected, ownership?, network?, policy? Docs: https://www.brainiac.software/api/staking-security/docs#staking-security-validator-withdrawal-credential-audit Example request: ```json { "validators": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "withdrawalCredentials": "0x0100000000000000000000001111111111111111111111111111111111111111" }, { "pubkey": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "withdrawalCredentials": "0x0100000000000000000000001111111111111111111111111111111111111111" } ], "expected": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "credentialType": "execution", "address": "0x2222222222222222222222222222222222222222" }, { "pubkey": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "credentialType": "execution", "address": "0x1111111111111111111111111111111111111111" }, { "pubkey": "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "credentialType": "execution", "address": "0x2222222222222222222222222222222222222222" } ], "ownership": [ { "address": "0x1111111111111111111111111111111111111111", "operator": "treasury", "beneficiary": "ops" } ], "network": "mainnet", "policy": { "duplicateDestinations": "prohibit", "ownership": "require_listed", "operators": [ "treasury" ] } } ``` Example response: ```json { "audit_status": "mismatched", "risk_level": "critical", "credential_type_summary": [ { "type": "execution", "count": 2 } ], "withdrawal_destinations": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "credential_type": "execution", "detail": "The 0x01 credential has zero padding. The last 20 bytes are the execution withdrawal address in the supplied credential. This was not read from a beacon node.", "address": "0x1111111111111111111111111111111111111111", "operator": "treasury", "beneficiary": "ops", "matches_expected": false }, { "pubkey": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "credential_type": "execution", "detail": "The 0x01 credential has zero padding. The last 20 bytes are the execution withdrawal address in the supplied credential. This was not read from a beacon node.", "address": "0x1111111111111111111111111111111111111111", "operator": "treasury", "beneficiary": "ops", "matches_expected": true } ], "unexpected_destinations": [ { "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "credential_type": "execution", "address": "0x1111111111111111111111111111111111111111", "expected_address": "0x2222222222222222222222222222222222222222", "detail": "The execution address in the supplied credential is not the expected withdrawal address. This does not show who controls either address, and it was not read from a beacon node." } ], "duplicate_destinations": [ { "address": "0x1111111111111111111111111111111111111111", "pubkeys": [ "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ], "detail": "policy.duplicateDestinations is prohibit, and this execution address is the withdrawal destination for more than one supplied validator." } ], "missing_validators": [ { "pubkey": "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "detail": "This public key is in the expected list and is not in the supplied validator records." } ], "findings": [ { "code": "unexpected_destination", "severity": "critical", "pubkey": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "detail": "The execution address in the supplied credential is not the expected withdrawal address. This does not show who controls either address, and it was not read from a beacon node." }, { "code": "duplicate_destination", "severity": "high", "detail": "policy.duplicateDestinations is prohibit, and this execution address is the withdrawal destination for more than one supplied validator." }, { "code": "validator_missing", "severity": "medium", "pubkey": "0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "detail": "This public key is in the expected list and is not in the supplied validator records." }, { "code": "not_on_chain", "severity": "low", "detail": "These credentials were supplied in the request. They were not read from a beacon node, and a match does not show that the caller controls an address." } ], "limitations": [ "Withdrawal credentials are the bytes in the request. They were not read from a beacon node.", "A matching address is not proof that the caller controls that address.", "Ownership is taken only from the supplied mapping. Address format is not treated as ownership.", "Decoded types are 0x00 BLS, 0x01 execution, and 0x02 compounding. Other prefixes are unrecognized.", "An execution address is the last 20 bytes of an 0x01 or 0x02 credential only when the 11-byte padding is zero.", "An 0x00 credential does not contain an execution address. The other 31 bytes are a hash fragment.", "Duplicate destinations are reported only when policy.duplicateDestinations is prohibit.", "network is a label. It was not compared with a beacon chain." ] } ```