Ver código fonte

docs: Add NTT-related information to Accountant whitepaper (#4422)

* docs: Add NTT-related information to Accountant whitepaper
John Saigle 4 meses atrás
pai
commit
cce052c0a7
1 arquivos alterados com 153 adições e 55 exclusões
  1. 153 55
      whitepapers/0011_accountant.md

+ 153 - 55
whitepapers/0011_accountant.md

@@ -2,37 +2,43 @@
 
 This document describes the motivation, goals, and technical design of the "Global Accountant".
 
-The Global Accountant is a safety feature for registered token bridges.  It is implemented as an [Integrity Checker](0010_integrity_checkers.md) on Wormchain.
+The Global Accountant is a safety feature for registered token bridges and Native Token Transfer (NTT) deployments. It is implemented as an [Integrity Checker](0010_integrity_checkers.md) on Wormchain.
 
 ## Objectives
 
-Tightly limit the impact an exploit in a connected chain can have on a registered token bridge.  Ensure the number of wrapped tokens capable of being moved out of a chain never exceeds the number sent to that chain, even if that chain was compromised.
+Tightly limit the impact an exploit in a connected chain can have on registered token bridges and NTT deployments. Ensure the number of wrapped tokens capable of being moved out of a chain never exceeds the number sent to that chain, even if that chain was compromised.
 
 ## Background
 
+### Token Bridges
 Token Bridges built on Wormhole (e.g. [Portal](0003_token_bridge.md)) allow transferring tokens between any of the various blockchains connected to the bridge.
 
-A core feature of the token bridge is that xAssets are fungible across all chains.  ETH sent from Ethereum to Solana to Polygon is the same as the ETH sent from Ethereum to Aptos to Polygon.  Transfers work by locking native assets (or burning wrapped assets) on the source chain and emitting a Wormhole message that allows the minting of wrapped assets (or unlocking of native assets) on the destination chain.
+A core feature of these systems is that xAssets are fungible across all chains. ETH sent from Ethereum to Solana to Polygon is the same as the ETH sent from Ethereum to Aptos to Polygon. Transfers work by locking native assets (or burning wrapped assets) on the source chain and emitting a Wormhole message that allows the minting of wrapped assets (or unlocking of native assets) on the destination chain.
 
-It is unfortunately not practical to synchronize the state of the token bridge across all chains: If a transfer of Portal-wrapped ETH happens from Solana to Polygon, the token bridge contract on Ethereum is not aware of that transfer and therefore doesn't know where the wrapped assets are currently located.
+It is unfortunately not practical to synchronize the state of token bridges and NTT protocols across all chains: If a transfer of Portal-wrapped ETH happens from Solana to Polygon, the token bridge contract on Ethereum is not aware of that transfer and therefore doesn't know where the wrapped assets are currently located.
 
-If any connected chain gets compromised, e.g. through a bug in the rpc nodes, this could cause arbitrary minting of “unbacked” wrapped assets, i.e. wrapped assets that are not backed by native assets.  Those unbacked wrapped assets could then be transferred to the native chain.  Because wrapped assets are fungible, the smart contract on the native chain cannot distinguish those unbacked wrapped assets and would proceed with unlocking the native assets, effectively draining the bridge.
+If any connected chain gets compromised, e.g. through a bug in the RPC nodes, this could cause arbitrary minting of "unbacked" wrapped assets, i.e. wrapped assets that are not backed by native assets. Those unbacked wrapped assets could then be transferred to the native chain. Because wrapped assets are fungible, the smart contract on the native chain cannot distinguish those unbacked wrapped assets and would proceed with unlocking the native assets, effectively draining the bridge.
 
-The [Governor](0007_governor.md) limits the maximal impact of such an attack, but cannot fully prevent it.
+The [Governor](0007_governor.md) limits the maximal impact of such an attack on the token bridges, but cannot fully prevent it.
 
-The core of the issue is the differing trust assumptions and security program maturity of various blockchains.  By design, the Token Bridge is subject to the weakest link.  A holder of a wrapped asset should only be subject to security risks from the asset's native chain as well as the chain where the wrapped asset lives.  They should not be subject to security risks from other chains connected to the bridge.
+The core of the issue is the differing trust assumptions and security program maturity of various blockchains. By design, Token Bridges are subject to the weakest link. A holder of a wrapped asset should only be subject to security risks from the asset's native chain as well as the chain where the wrapped asset lives. They should not be subject to security risks from other chains connected to the bridge.
+
+### Native Token Transfers
+Native Token Transfer (NTT) deployments allow certain assets to be transferred across a subset of chains, according to the deployment details.
+Additional details can be found in that project's [README](https://github.com/wormhole-foundation/native-token-transfers/blob/main/README.md)
 
 ## Goals
 
 ### Primary Goals
 
 - Localize cross-chain risk by ensuring no more wrapped tokens can be moved out of a chain than have been sent to that chain, even if that chain was compromised.
+- Support both Token Bridge and Native Token Transfer (NTT) protocols with unified accounting principles.
 
 ### Nice-to-haves
 
 - Support any token bridge, not just Portal.
 - Provide ground-truth statistics for locked and minted assets per chain, transfer activity, etc.
-- Minimize smart contract changes.  Ideally, we won't need to change the Token Bridge smart contracts at all.
+- Minimize smart contract changes. Ideally, we won't need to change the Token Bridge or NTT smart contracts at all.
 
 ### Non-Goals
 
@@ -40,19 +46,60 @@ The core of the issue is the differing trust assumptions and security program ma
 
 ## Overview
 
-The `global-accountant` contract on wormchain acts as an [Integrity Checker](0010_integrity_checkers.md).  Guardians submit [pre-observations](0010_integrity_checker.md#pre-observations) to it and only finalize their observations if the `global-accountant` gives the go-ahead.
+The Global Accountant consists of two parallel accounting systems:
+
+1. **Base Accountant**: Handles traditional Token Bridge transfers (Portal)
+2. **NTT Accountant**: Handles Native Token Transfer protocol messages
 
-`global-accountant`keeps track of the tokens locked and minted on each connected blockchain.
+Both systems act as [Integrity Checkers](0010_integrity_checkers.md) on wormchain. Guardians submit [pre-observations](0010_integrity_checker.md#pre-observations) to the appropriate accountant and only finalize their observations if the accountant gives the go-ahead.
 
-Once a Token Bridge message has reached a quorum of pre-observations (i.e. 13 guardians have submitted a pre-observation), it attempts to apply the transfer to the account balances for each chain.  If the transfer doesn't result in a negative account balance, it is allowed to proceed.
+Each accountant keeps track of the tokens locked and minted on each connected blockchain for their respective message type.
+
+Once a transfer message has reached a quorum of pre-observations (i.e. 13 guardians have submitted a pre-observation), the appropriate accountant attempts to apply the transfer to the account balances for each chain. If the transfer doesn't result in a negative account balance, it is allowed to proceed.
 
 ## Detailed Design
 
-### Accountant Smart Contract
+### Architecture
+
+The Global Accountant supports both Token Bridge and NTT protocols through separate but parallel accounting systems:
+
+#### Base Accountant
+- Handles Token Bridge transfers (Portal)
+- Uses existing Token Bridge emitter detection logic
+- Maintains separate contract: `accountantContract`
+- Uses `accountantKeyPath` and `accountantKeyPassPhrase` for authentication
+
+#### NTT Accountant  
+- Handles Native Token Transfer protocol messages
+- Detects NTT messages through payload analysis and known emitter configurations
+- Maintains separate contract: `accountantNttContract`
+- Uses `accountantNttKeyPath` and `accountantNttKeyPassPhrase` for authentication
+- Supports both direct NTT endpoint transfers and Automatic Relayer (AR) forwarded transfers
+
+### Message Detection and Routing
+
+The accountant includes message detection logic to route transfers to the appropriate accounting system:
+
+#### Token Bridge Detection
+- Uses known Token Bridge emitter mappings
+- Validates payload format for Token Bridge transfers
+- Routes to Base Accountant for processing
+
+#### NTT Detection
+- **Direct NTT Transfers**: Detects messages from known NTT endpoint contracts by:
+  - Checking emitter chain/address against configured NTT emitters
+  - Validating NTT payload format (WH_PREFIX + NTT_PREFIX at specific offsets)
+- **Automatic Relayer Transfers**: Detects NTT messages forwarded through Automatic Relayers by:
+  - Checking if emitter is a known Automatic Relayer
+  - Parsing AR payload to extract original sender address
+  - Validating that sender is a known NTT emitter
+  - Extracting and validating embedded NTT payload
+
+### Accountant Smart Contracts
 
 #### Query methods for signature verification
 
-The global-accountant is a cosmwasm-based smart contract rather than a built-in native cosmos-sdk module.  It needs to expose query methods from the native wormhole module to cosmwasm (like getting the members of a guardian set).  Luckily, extending the contract interface is [fairly straightforward](https://docs.cosmwasm.com/docs/1.0/integration#extending-the-contract-interface).  The `x/wormhole` native module will expose the following query methods:
+Both accountants are cosmwasm-based smart contracts rather than built-in native cosmos-sdk modules. They expose query methods from the native wormhole module to cosmwasm. The `x/wormhole` native module exposes the following query methods:
 
 ```rust
 #[cw_serde]
@@ -81,110 +128,161 @@ pub enum WormholeQuery {
 
 #### Submitting observations to wormchain
 
-When a guardian observes a token transfer message from the registered tokenbridge on a particular chain, it submits the observation directly to the accountant.  The contract keeps track of pending token transfers and emits an event once it has received a quorum of observations.  If a quorum of guardians submit their observations within a single tendermint block then the token transfer only needs to wait for one round of tendermint consensus and one round of guardian consensus.
+When a guardian observes a transfer message, it first determines whether it's a Token Bridge or NTT transfer, then submits the observation to the appropriate accountant:
 
-When a guardian submits a transfer (observation) to the contract, the contract will perform several checks:
+- **Token Bridge transfers** → submitted to Base Accountant
+- **NTT transfers** → submitted to NTT Accountant
+
+Each accountant maintains separate:
+- Processing workers (`baseWorker` / `nttWorker`)
+- Event watchers (`baseWatcher` / `nttWatcher`) 
+- Submission channels and message prefixes
+- Per-emitter enforcement configurations
+
+The contract processing logic is the same for both accountants:
 
 - Check that the signature is valid and from a guardian in the current guardian set.
 - If the transfer does not yet have a quorum of signatures, return a `Pending` status and mark the transfer as having a signature from the guardian.
-- If a transfer with the same `(emitter_chain, emitter_address, sequence)` tuple has already been committed, then check that the digest of the transfer matches the digest of the committed transfer.  If they match return a `Committed` status; otherwise return an `Error` status and emit an `Error` event.
-- If the transfer has a quorum of signatures, parse the tokenbridge payload and commit the transfer.
-- If committing the transfer fails (for example, if one of the accounts does not have a sufficient balance), return an `Error` status and emit an `Error` event.  Otherwise return a `Committed` status and emit a `Committed` event.
+- If a transfer with the same `(emitter_chain, emitter_address, sequence)` tuple has already been committed, then check that the digest of the transfer matches the digest of the committed transfer. If they match return a `Committed` status; otherwise return an `Error` status and emit an `Error` event.
+- If the transfer has a quorum of signatures, parse the payload (Token Bridge or NTT format) and commit the transfer.
+- If committing the transfer fails (for example, if one of the accounts does not have a sufficient balance), return an `Error` status and emit an `Error` event. Otherwise return a `Committed` status and emit a `Committed` event.
 
-If the guardian receives a `Committed` status for a transfer then it can immediately proceed to signing the VAA.  If it receives an `Error` status, then it should halt further processing of the transfer (see the [Handling Rejections](#handling-rejections) section for more details).  If it receives a `Pending` status, then it should add the observation to a local database of pending transfers and wait for an event from the accountant.
+If the guardian receives a `Committed` status for a transfer then it can immediately proceed to signing the VAA. If it receives an `Error` status, then it should halt further processing of the transfer. If it receives a `Pending` status, then it should add the observation to a local database of pending transfers and wait for an event from the accountant.
 
 #### Observing Events from Wormchain
 
-Each guardian sets up a watcher for the accountant watching for events emitted signalling a determination on a transfer.  An event for a transfer is emitted when there is a quorum of pre-observations.
+Each guardian sets up watchers for both accountants, watching for events emitted signalling determinations on transfers. Events can come from either the Base Accountant or NTT Accountant depending on the transfer type.
 
-There are 2 types of events that the guardian must handle:
+There are 2 types of events that the guardian must handle from each accountant:
 
-- Transfer committed - This indicates that an observation has reached quorum and the transfer has been committed.  The guardian must verify the contents of the event and then sign the VAA if they match.  See [Threat Model](#threat-model) for more details.
-- Error - This indicates that the accountant ran into an error while processing an observation.  The guardian should halt further processing of the transfer.  See the [Handling Rejections](#handling-rejections) section for more details
+- Transfer committed - This indicates that an observation has reached quorum and the transfer has been committed. The guardian must verify the contents of the event and then sign the VAA if they match.
+- Error - This indicates that the accountant ran into an error while processing an observation. The guardian should halt further processing of the transfer.
 
 #### Handling stuck transfers
 
-It may be possible that some transfers don't receive enough observations to reach quorum.  This can happen if a number of guardians miss the transaction on the origin chain.  Since the accountant runs before the peer to peer gossip layer, it cannot take advantage of the existing automatic retry mechanisms that the guardian network uses.  To deal with this the accountant contract provides a `MissingObservations` query that returns a list of pending transfers for which the accountant does not have an observation from a particular guardian.
+It may be possible that some transfers don't receive enough observations to reach quorum. This can happen if a number of guardians miss the transaction on the origin chain. Since the accountant runs before the peer to peer gossip layer, it cannot take advantage of the existing automatic retry mechanisms that the guardian network uses. To deal with this, both accountant contracts provide a `MissingObservations` query that returns a list of pending transfers for which the accountant does not have an observation from a particular guardian.
+
+Guardians are expected to periodically run this query against both accountants and re-observe transactions for which the accountants are missing observations from them.
 
-Guardians are expected to periodically run this query and re-observe transactions for which the accountant is missing observations from them.
+#### Configuration and Deployment Flexibility
+
+The dual accountant system supports flexible deployment configurations:
+
+- **Base Only**: Only Token Bridge accounting enabled (`accountantContract` configured, `accountantNttContract` empty)
+- **NTT Only**: Only NTT accounting enabled (`accountantNttContract` configured, `accountantContract` empty)  
+- **Both**: Full accounting for both protocols (both contracts configured)
+- **Neither**: Accountant disabled entirely (both contracts empty)
+
+This allows for gradual rollout and protocol-specific deployments.
 
 #### Contract Upgrades
 
-Upgrading the contract is performed with a migrate contract governance action from the guardian network. Once quorum+1 guardians (13) have signed the migrate contract governance VAA, the [wormchain client migrate command](https://github.com/wormhole-foundation/wormhole/blob/a846036b6ebff3af6f12ff375f5c3801ada20291/wormchain/x/wormhole/client/cli/tx_wasmd.go#L148) can be ran by anyone with an authorized wallet to submit the valid governance vaa and updated wasm contract to wormchain.
+Upgrading either contract is performed with a migrate contract governance action from the guardian network. Once quorum+1 guardians (13) have signed the migrate contract governance VAA, the [wormchain client migrate command](https://github.com/wormhole-foundation/wormhole/blob/a846036b6ebff3af6f12ff375f5c3801ada20291/wormchain/x/wormhole/client/cli/tx_wasmd.go#L148) can be ran by anyone with an authorized wallet to submit the valid governance vaa and updated wasm contract to wormchain.
 
 ### Account Management
 
-The accountant keeps track of token balances for each blockchain ensuring they never become negative.  When committing a transfer, the accountant parses the tokenbridge payload to get the emitter chain, recipient chain, token chain, and token address.  These values are used to look up the relevant accounts and adjust the balances as needed.
+Both the Base and NTT Accountants use the same account management principles. Each accountant keeps track of token balances for each blockchain ensuring they never become negative. When committing a transfer, the accountant parses the respective payload format (Token Bridge or NTT) to get the emitter chain, recipient chain, token chain, and token address. These values are used to look up the relevant accounts and adjust the balances as needed.
 
-It will have the following accounts:
+Both accountants maintain the following accounts:
 
-- Accounts for native tokens ($SOL on solana, $ETH or $wETH on ethereum).  These are classified as assets because they represent actual tokens held by smart contracts on the various chains.  All tokens not issued by the token bridge are considered native tokens, even if they are wrapped tokens issued by another bridge.  If the token is held by the bridge contract rather than burned, it is an asset.  We'll call these "custody accounts".
-- Accounts for wormhole wrapped tokens (wrapped SOL on ethereum, wrapped ETH on solana).  These are classified as liabilities.  These tokens are not held by the smart contract and instead represent a liability for the bridge: if a user returns a wrapped token to the bridge, the bridge **must** be able to transfer the native token to that user on its native chain.  We'll call these “wrapped accounts”.
+- Accounts for native tokens -- not to be confused with Native Token Transfers -- include e.g. $SOL on Solana, and $ETH or $wETH on Ethereum. These are classified as assets because they represent actual tokens held by smart contracts on the various chains. All tokens not issued by the token bridge are considered native tokens, even if they are wrapped tokens issued by another bridge. If the token is held by the bridge contract rather than burned, it is an asset. We'll call these "custody accounts".
+- Accounts for wormhole wrapped tokens (wrapped SOL on Ethereum, wrapped ETH on Solana). These are classified as liabilities. These tokens are not held by the smart contract and instead represent a liability for the bridge: if a user returns a wrapped token to the bridge, the bridge **must** be able to transfer the native token to that user on its native chain. We'll call these "wrapped accounts".
 
-Transferring a native token across the tokenbridge (locking) increases the balance on both the custody account and wrapped account on the destination chain.  Transferring a wrapped token back across the tokenbridge (burning) and subsequently unlocking its native asset decreases the balance on both the wrapped and custody accounts.  Any transfer causing the balance of an account to become negative is invalid and gets rejected.
+Transferring a native token across either protocol (locking) increases the balance on both the custody account and wrapped account on the destination chain. Transferring a wrapped token back across either protocol (burning) and subsequently unlocking its native asset decreases the balance on both the wrapped and custody accounts. Any transfer causing the balance of an account to become negative is invalid and gets rejected.
 
-Each account is identified via a `(chain_id, token_chain, token_address)` tuple.  Custody accounts are those where `chain_id == token_chain`, while the rest are wrapped accounts. See the [governance](#governance) section below for further clarification.
+Each account is identified via a `(chain_id, token_chain, token_address)` tuple. Custody accounts are those where `chain_id == token_chain`, while the rest are wrapped accounts. See the [governance](#governance) section below for further clarification.
 
 #### Governance
 
-Account balances recorded by the accountant may end up inaccurate due to bugs in the program or exploits of the token bridge.  In these cases, the guardians may issue governance actions to manually modify the balances of the accounts.  These governance actions must be signed by a quorum of guardians.
+Account balances recorded by either accountant may end up inaccurate due to bugs in the program or exploits of the respective protocols. In these cases, the guardians may issue governance actions to manually modify the balances of the accounts in either the Base or NTT Accountant. These governance actions must be signed by a quorum of guardians.
 
 #### Examples
 
-Example 1: A user sends SOL from solana to ethereum.  In this transaction the  `(Solana, Solana, SOL)` account is debited and the `(Ethereum, Solana, SOL)` account is credited, increasing the balances of both accounts.
+Example 1: A user sends SOL from Solana to Ethereum. In this transaction the `(Solana, Solana, SOL)` account is debited and the `(Ethereum, Solana, SOL)` account is credited, increasing the balances of both accounts.
 
-Example 2: A user sends wrapped SOL from ethereum to solana.  In this transaction the `(Ethereum, Solana, SOL)` account is debited and the `(Solana, Solana, SOL)` account is credited, decreasing the balances of both accounts.
+Example 2: A user sends wrapped SOL from Ethereum to Solana. In this transaction the `(Ethereum, Solana, SOL)` account is debited and the `(Solana, Solana, SOL)` account is credited, decreasing the balances of both accounts.
 
-Example 3: An attacker exploits a bug in the solana contract to print fake wrapped ETH and transfers it over the bridge. This could drain real ETH from the ethereum contract. Thanks to the accounting contract, the total amount drained is limited by the total number of wrapped ETH issued by the solana token bridge contract.  Since the token bridge is still liable for all the legitimately issued wrapped ETH the account balances no longer reflect reality.
+Example 3: An attacker exploits a bug in the Solana contract to print fake wrapped ETH and transfers it over the bridge. This could drain real ETH from the Ethereum contract. Thanks to the accounting contract, the total amount drained is limited by the total number of wrapped ETH issued by the solana token bridge contract. Since the token bridge is still liable for all the legitimately issued wrapped ETH the account balances no longer reflect reality.
 
-Wormhole decides to cover the cost of the hack and transfers the ETH equivalent to the stolen amount to the token bridge contract on ethereum.  To update the accounts, the guardians must issue 2 governance actions: one to increase the balance of the `(Ethereum, Ethereum, ETH)` custody account and one to increase the balance of the `(Solana, Ethereum, ETH)` wrapped account.
+Wormhole decides to cover the cost of the hack and transfers the ETH equivalent to the stolen amount to the token bridge contract on Ethereum. To update the accounts, the guardians must issue 2 governance actions: one to increase the balance of the `(Ethereum, Ethereum, ETH)` custody account and one to increase the balance of the `(Solana, Ethereum, ETH)` wrapped account.
 
-Example 4: A user sends wrapped SOL from ethereum to polygon.  Even though SOL is not native to either chain, the transaction is still recorded the same way: the `(Ethereum, Solana, SOL)` wrapped account is debited and the `(Polygon, Solana, SOL)` wrapped account is credited.  The total liability of the token bridge has not changed and instead we have just moved some liability from ethereum to polygon.
+Example 4: A user sends wrapped SOL from Ethereum to Polygon. Even though SOL is not native to either chain, the transaction is still recorded the same way: the `(Ethereum, Solana, SOL)` wrapped account is debited and the `(Polygon, Solana, SOL)` wrapped account is credited. The total liability of the token bridge has not changed and instead we have just moved some liability from Ethereum to Polygon.
 
 #### Creating accounts
 
-Since users can send any arbitrary token over the token bridge, the accountant should automatically create accounts for any new token.  To determine whether the newly created account should be a custody account or a wrapped account, these steps are followed:
+Since users can send any arbitrary token over the token bridge, the accountant should automatically create accounts for any new token. To determine whether the newly created account should be a custody account or a wrapped account, these steps are followed:
 
 - If `emitter_chain == token_chain` and a custody account doesn't already exist, create one.
-- If `emitter_chain != token_chain` and a wrapped account doesn't already exist, reject the transaction.  The wrapped account should have been created when the tokens were originally transferred to `emitter_chain`.
+- If `emitter_chain != token_chain` and a wrapped account doesn't already exist, reject the transaction. The wrapped account should have been created when the tokens were originally transferred to `emitter_chain`.
 - If `token_chain != recipient_chain` and a wrapped account doesn't already exist, create one.
-- If `token_chain == recipient_chain` and a custody account doesn't already exist, reject the transaction.  The custody account should have been created when the tokens were first transferred from `recipient_chain`.
+- If `token_chain == recipient_chain` and a custody account doesn't already exist, reject the transaction. The custody account should have been created when the tokens were first transferred from `recipient_chain`.
+
+### Enforcement Configuration
+
+Both accountants support per-emitter enforcement configuration:
+
+- **Enforcing mode**: Guardians will not sign VAAs until the transfer is committed by the accountant
+- **Log-only mode**: Observations are submitted but VAAs are signed regardless of accountant status
+
+This allows for:
+- Gradual rollout of enforcement per protocol
+- Different security postures for different emitters
+- Testing and validation in production environments
 
 ### Bootstrapping / Backfills
 
-In order for the accountant to have accurate values for the balances of the various accounts it needs to replay all transactions since the initial launch of the token bridge.  Similarly, it may be necessary to backfill missing transfers if the accountant is disabled for any period of time.
+In order for each accountant to have accurate values for the balances of the various accounts, it needs to replay all transactions since the initial launch of the respective protocol. Similarly, it may be necessary to backfill missing transfers if either accountant is disabled for any period of time.
 
-To handle both issues, the accountant has the ability to directly process tokenbridge transfer VAAs.  As long as the VAAs are signed by a quorum of guardians from the latest guardian set, the accountant uses them to update its on-chain state of token balances.
+To handle both issues, each accountant has the ability to directly process transfer VAAs for their respective protocols. As long as the VAAs are signed by a quorum of guardians from the latest guardian set, the accountant uses them to update its on-chain state of token balances.
 
-Submitting VAAs does not disable any core checks: a VAA causing the balance of an account to become negative will still be rejected even if it has a quorum of signatures.  This can be used to catch problematic transfers after the fact.
+Submitting VAAs does not disable any core checks: a VAA causing the balance of an account to become negative will still be rejected even if it has a quorum of signatures. This can be used to catch problematic transfers after the fact.
 
 ### Handling Rejections
 
-Legitimate transactions should never be rejected so a rejection implies either a bug in the accountant or an actual attack on the bridge.  In both cases manual intervention is required.
+Legitimate transactions should never be rejected so a rejection implies either a bug in the accountant or an actual attack on the bridge. In both cases manual intervention is required.
 
 #### Alerting
 
-Whenever a guardian observes an error (either via an observation response or via an error event), it will increase a prometheus error counter.  Guardians will be encouraged to set up alerts whenever these metrics change so that they can be notified when an error occurs.
+Whenever a guardian observes an error (either via an observation response or via an error event), it will increase a Prometheus error counter. Guardians will be encouraged to set up alerts whenever these metrics change so that they can be notified when an error occurs from either accountant.
 
 ## Deployment Plan
 
-- Deploy wormchain and have a quorum of guardians bring their nodes online.
-- Deploy the accountant contract to wormchain and backfill it with all the tokenbridge transfer VAAs that have been emitted since inception.
-- Enable the accountant in log-only mode.  In this mode, each guardian will submit its observations to the accountant but will not wait for the transfer to commit before signing the VAA.  This allows time to shake out any remaining implementation issues without impacting the network.
-- After confidence is achieved the accountant is running correctly in log-only mode, switch to enforcing mode.  In this mode, guardians will not sign VAAs for token transfers until the transfer is committed by the accountant.  As long as at least a quorum of guardians submit their observations to the accountant, only a super-minority (1/3) is needed to turn on enforcing-mode for it to be effective.
+- Deploy Wormchain and have a quorum of guardians bring their nodes online.
+- Deploy both accountant contracts to Wormchain and backfill them with their respective transfer VAAs that have been emitted since inception.
+- Enable both accountants in log-only mode. In this mode, each guardian will submit observations to the appropriate accountant but will not wait for transfers to commit before signing VAAs. This allows time to shake out any remaining implementation issues without impacting the network.
+- After confidence is achieved that both accountants are running correctly in log-only mode, switch to enforcing mode per protocol as needed. As long as at least a quorum of guardians submit their observations to the accountants, only a super-minority (1/3) is needed to turn on enforcing-mode for it to be effective.
 
 ## Security Considerations
 
 ### Threat Model
 
-Since the Global Accountant is implemented as an Integrity Checker, it inherits the threat model of Integrity Checkers. Therefore, it is only able to block messages and not create or modify messages.
+Since both Global Accountants are implemented as Integrity Checkers, they inherit the threat model of Integrity Checkers. Therefore, they are only able to block messages and not create or modify messages.
+
+### Protocol Isolation
+
+The dual accountant architecture provides protocol isolation benefits:
+
+- The Base and NTT accountants can be enabled independently
+- Token Bridge exploits cannot affect NTT accounting and vice versa
+- Each protocol can have different enforcement policies
+- Issues in one accountant don't necessarily impact the other
 
 ### Susceptibility to wormchain downtime
 
-Once all token transfers are gated on approval from the accountant, the uptime of the guardian network for those transfers becomes dependent on the uptime of wormchain itself.  Any downtime for wormchain would halt all token transfers until the network is back online (or 2/3+ of the guardians choose to disable the accountant).
+Once transfers are gated on approval from the respective accountants, the uptime of the guardian network for those transfers becomes dependent on the uptime of wormchain itself. Any downtime for wormchain would halt transfers until the network is back online (or 2/3+ of the guardians choose to disable the relevant accountant).
+
+In practice, cosmos chains are stable and wormchain is not particularly complex. However, once the accountants are live, attacking wormchain could shut down transfers for both protocols.
+
+### Token Bridge and NTT messages cannot reach quorum if 7 or more, but less than 13 Guardians decide to disable Accountant
+
+Due to the nature of the accountants, a guardian that chooses to enable them in enforcing-mode will refuse to sign a transfer until it sees that the transfer is committed by the appropriate accountant. If a super-minority of guardians choose to not enable an accountant at all (i.e. stop sending their observations to the contract) then we will end up with a stalemate: the guardians with the feature disabled will be unable to reach quorum because they don't have enough signatures while the guardians in enforcing-mode will never observe the transfer being committed by the accountant (and so will never sign the observation). This is very different from [the governor feature](0007_governor.md), where only a super-minority of guardians have to enable it to be effective.
+
+Note: this applies only to the enforcing mode. If the Guardians enable logging mode on the accountant(s) instead, this issue will not occur.
 
-In practice, cosmos chains are stable and wormchain is not particularly complex.  However, once the accountant is live, attacking wormchain could shut down all token transfers for the bridge.
+### Configuration Complexity
 
-### Token Bridge messages cannot reach quorum if 7 or more, but less than 13 Guardians decide to disable Accountant
+The dual accountant system introduces configuration complexity:
 
-Due to the nature of the accountant, a guardian that chooses to enable it in enforcing-mode will refuse to sign a token transfer until it sees that the transfer is committed by the accountant.  If a super-minority of guardians choose to not enable the accountant at all (i.e. stop sending their observations to the contract) then we will end up with a stalemate: the guardians with the feature disabled will be unable to reach quorum because they don't have enough signatures while the guardians in enforcing-mode will never observe the transfer being committed by the accountant (and so will never sign the observation).  This is very different from [the governor feature](0007_governor.md), where only a super-minority of guardians have to enable it to be effective.
+- Guardians must properly configure both accountants
+- Message routing logic must correctly identify transfer types
+- Monitoring and alerting must cover both systems