diff --git a/assertions-book/assertions/ass01-impl-addr-change.mdx b/assertions-book/assertions/ass01-impl-addr-change.mdx index b3f60a6..f6b1a93 100644 --- a/assertions-book/assertions/ass01-impl-addr-change.mdx +++ b/assertions-book/assertions/ass01-impl-addr-change.mdx @@ -15,7 +15,7 @@ For example, it's possible to define a whitelist of allowed implementations - an Monitors changes to the implementation address storage slot in proxy contracts using: -- `ph.forkPreState()` / `ph.forkPostState()`: Compare implementation address before and after transaction +- `ph.forkPreTx()` / `ph.forkPostTx()`: Compare implementation address before and after transaction - `getStateChangesAddress()`: Track all changes to the implementation slot during transaction execution - `registerStorageChangeTrigger()`: Trigger when implementation address changes diff --git a/assertions-book/assertions/ass05-ownership-change.mdx b/assertions-book/assertions/ass05-ownership-change.mdx index 9194ef6..2c46cc3 100644 --- a/assertions-book/assertions/ass05-ownership-change.mdx +++ b/assertions-book/assertions/ass05-ownership-change.mdx @@ -15,7 +15,7 @@ For example, in the [Radiant Capital hack](/assertions-book/previous-hacks/hack1 Monitors changes to the owner address storage slot in contracts using: -- `ph.forkPreState()` / `ph.forkPostState()`: Compare owner address before and after transaction +- `ph.forkPreTx()` / `ph.forkPostTx()`: Compare owner address before and after transaction - `getStateChangesAddress()`: Track all changes to the owner address slot during transaction execution - `registerStorageChangeTrigger()`: Trigger when owner address changes diff --git a/assertions-book/assertions/ass06-constant-product.mdx b/assertions-book/assertions/ass06-constant-product.mdx index 4a93036..2aeed17 100644 --- a/assertions-book/assertions/ass06-constant-product.mdx +++ b/assertions-book/assertions/ass06-constant-product.mdx @@ -15,7 +15,7 @@ The constant product formula is fundamental to many AMM designs - any deviation Monitors the product of reserves (k) in AMM pools to ensure it remains constant after transactions using: -- `forkPreState()` / `forkPostState()`: Compare reserve product before and after transaction +- `forkPreTx()` / `forkPostTx()`: Compare reserve product before and after transaction - `getStateChanges()`: Monitor reserve changes throughout transaction callstack - Direct validation that k = reserve0 * reserve1 remains unchanged diff --git a/assertions-book/assertions/ass07-lending-health-factor.mdx b/assertions-book/assertions/ass07-lending-health-factor.mdx index 82e9447..9834925 100644 --- a/assertions-book/assertions/ass07-lending-health-factor.mdx +++ b/assertions-book/assertions/ass07-lending-health-factor.mdx @@ -17,7 +17,7 @@ Monitors health factors of positions during specific lending operations using: - `getCallInputs()`: Track all function calls to specified protocol functions - `registerCallTrigger()`: Trigger on lending operations (supply, borrow, withdraw, repay) -- `forkPostState()`: Verify health factor after each operation (used by default if no pre-state specified) +- `forkPostTx()`: Verify health factor after each operation (used by default if no pre-state specified) The assertion checks each lending operation individually to ensure positions affected by these operations remain healthy. diff --git a/assertions-book/assertions/ass08-sum-of-all-positions.mdx b/assertions-book/assertions/ass08-sum-of-all-positions.mdx index effaada..c5337eb 100644 --- a/assertions-book/assertions/ass08-sum-of-all-positions.mdx +++ b/assertions-book/assertions/ass08-sum-of-all-positions.mdx @@ -21,7 +21,7 @@ Since direct iteration over all positions isn't currently supported, this assert 4. Verify that the new total supply equals the pre-state total supply plus the sum of position changes Uses these cheatcodes: -- `ph.forkPreState()` / `ph.forkPostState()`: Capture total supply before and after transaction +- `ph.forkPreTx()` / `ph.forkPostTx()`: Capture total supply before and after transaction - `ph.getCallInputs()`: Track function calls that modify positions - `registerCallTrigger()`: Trigger on position-modifying functions diff --git a/assertions-book/assertions/ass09-timelock-verification.mdx b/assertions-book/assertions/ass09-timelock-verification.mdx index eafa4e8..448c72e 100644 --- a/assertions-book/assertions/ass09-timelock-verification.mdx +++ b/assertions-book/assertions/ass09-timelock-verification.mdx @@ -15,7 +15,7 @@ Timelocks provide a buffer against malicious governance actions - without proper Verifies timelock integrity by comparing timelock state and parameters before and after transactions: -- `forkPreState()` / `forkPostState()`: Compare timelock state before and after transaction +- `forkPreTx()` / `forkPostTx()`: Compare timelock state before and after transaction - `registerStorageChangeTrigger()`: Monitor changes to timelock storage slot - Ensures timelock delay is within acceptable bounds (1 day to 2 weeks) - Confirms timelock activation follows proper procedures diff --git a/assertions-book/assertions/ass10-oracle-validation.mdx b/assertions-book/assertions/ass10-oracle-validation.mdx index f21277a..f7404b5 100644 --- a/assertions-book/assertions/ass10-oracle-validation.mdx +++ b/assertions-book/assertions/ass10-oracle-validation.mdx @@ -18,7 +18,7 @@ Stale oracle data can indicate service disruption or attacks on oracle infrastru Monitors oracle timestamp updates when critical protocol functions are called: -- `forkPostState()`: Check oracle's last update time after transaction +- `forkPostTx()`: Check oracle's last update time after transaction - `registerCallTrigger()`: Trigger on functions that rely on oracle data (e.g., DEX swaps) - Verify oracle's last update time is within defined maximum time window diff --git a/assertions-book/assertions/ass11-twap-deviation.mdx b/assertions-book/assertions/ass11-twap-deviation.mdx index 03cd2e2..9b3d6dd 100644 --- a/assertions-book/assertions/ass11-twap-deviation.mdx +++ b/assertions-book/assertions/ass11-twap-deviation.mdx @@ -15,7 +15,7 @@ Sudden price deviations could indicate manipulation through flash loan attacks o Monitors TWAP price changes using a two-stage approach to ensure price stability: -- `ph.forkPreState()` / `ph.forkPostState()`: Compare post-transaction price against pre-transaction TWAP +- `ph.forkPreTx()` / `ph.forkPostTx()`: Compare post-transaction price against pre-transaction TWAP - `getStateChangesUint()`: Track all price changes during transaction execution - `registerStorageChangeTrigger()`: Trigger when price storage slot changes diff --git a/assertions-book/assertions/ass15-price-within-ticks.mdx b/assertions-book/assertions/ass15-price-within-ticks.mdx index 683b1c4..3636d88 100644 --- a/assertions-book/assertions/ass15-price-within-ticks.mdx +++ b/assertions-book/assertions/ass15-price-within-ticks.mdx @@ -15,7 +15,7 @@ If attackers could push prices outside valid tick ranges, they could execute tra Implements focused tick integrity verification: -- `ph.forkPreState()` / `ph.forkPostState()`: Capture tick state before and after transaction +- `ph.forkPreTx()` / `ph.forkPostTx()`: Capture tick state before and after transaction - `registerStorageChangeTrigger()`: Monitor changes to tick-related storage slots - Verify ticks stay within global bounds (-887272 to 887272) - Ensure ticks align with pool's tick spacing requirements diff --git a/assertions-book/assertions/ass16-liquidation-health-factor.mdx b/assertions-book/assertions/ass16-liquidation-health-factor.mdx index 18415d8..d4edd0e 100644 --- a/assertions-book/assertions/ass16-liquidation-health-factor.mdx +++ b/assertions-book/assertions/ass16-liquidation-health-factor.mdx @@ -15,8 +15,8 @@ Incorrect health factor validation could lead to unfair liquidations, protocol i Implements multi-layered liquidation health factor verification: -- **Pre-liquidation**: `forkPreState()` captures health factor before liquidation, verifies position is actually unhealthy -- **Post-liquidation**: `forkPostState()` verifies health factor improves after liquidation +- **Pre-liquidation**: `forkPreTx()` captures health factor before liquidation, verifies position is actually unhealthy +- **Post-liquidation**: `forkPostTx()` verifies health factor improves after liquidation - **Parameter validation**: `getCallInputs()` monitors liquidation calls, validates seized assets and repaid shares are non-zero, enforces maximum liquidation amounts - `registerCallTrigger()`: Triggers on liquidation function calls diff --git a/assertions-book/assertions/ass17-panic-state-validation.mdx b/assertions-book/assertions/ass17-panic-state-validation.mdx index 300262f..dffba02 100644 --- a/assertions-book/assertions/ass17-panic-state-validation.mdx +++ b/assertions-book/assertions/ass17-panic-state-validation.mdx @@ -15,7 +15,7 @@ Improper handling of pause states can lead to fund lockups, unauthorized access, Monitors protocol balance and pause state to ensure proper emergency behavior using a multi-layered approach: -- `ph.forkPreState()` / `ph.forkPostState()`: Capture protocol state before and after transaction +- `ph.forkPreTx()` / `ph.forkPostTx()`: Capture protocol state before and after transaction - `getStateChangesUint()`: Track all state changes during transaction - `registerCallTrigger()`: Monitor all function calls to the contract - Verify protocol balance can only decrease when paused (allowing withdrawals) diff --git a/assertions-book/assertions/ass18-harvest-increases-balance.mdx b/assertions-book/assertions/ass18-harvest-increases-balance.mdx index 60efa91..87a1116 100644 --- a/assertions-book/assertions/ass18-harvest-increases-balance.mdx +++ b/assertions-book/assertions/ass18-harvest-increases-balance.mdx @@ -15,7 +15,7 @@ Incorrect harvest implementations could lead to loss of user funds, price per sh Implements multi-layered approach to verify harvest operations: -- `forkPreState()` / `forkPostState()`: Capture vault balance and price per share before/after harvest +- `forkPreTx()` / `forkPostTx()`: Capture vault balance and price per share before/after harvest - `getStateChangesUint()`: Monitor all balance changes during transaction execution - `registerCallTrigger()`: Trigger on harvest function calls - Ensures balance hasn't decreased (can stay same if harvested recently) diff --git a/assertions-book/assertions/ass19-tokens-borrowed-invariant.mdx b/assertions-book/assertions/ass19-tokens-borrowed-invariant.mdx index a5f40d0..73bbc04 100644 --- a/assertions-book/assertions/ass19-tokens-borrowed-invariant.mdx +++ b/assertions-book/assertions/ass19-tokens-borrowed-invariant.mdx @@ -15,7 +15,7 @@ Violating this invariant could lead to protocol insolvency, loss of user funds, Implements straightforward verification that total tokens borrowed never exceed total tokens deposited: -- `ph.forkPostState()`: Capture protocol state after transaction to verify invariant holds +- `ph.forkPostTx()`: Capture protocol state after transaction to verify invariant holds - `registerStorageChangeTrigger()`: Trigger on storage slots tracking supply and borrow totals - Check total supply of assets (tokens deposited) and total borrowed assets - Assert total supply ≥ total borrowed assets diff --git a/assertions-book/assertions/ass20-erc20-drain.mdx b/assertions-book/assertions/ass20-erc20-drain.mdx index d74173f..fb92622 100644 --- a/assertions-book/assertions/ass20-erc20-drain.mdx +++ b/assertions-book/assertions/ass20-erc20-drain.mdx @@ -15,7 +15,7 @@ By limiting outflow rates, protocols gain valuable time to respond to security i Implements percentage-based limit on token outflows in a single transaction: -- `forkPreState()` / `forkPostState()`: Capture token balance before and after transaction +- `forkPreTx()` / `forkPostTx()`: Capture token balance before and after transaction - `registerCallTrigger()`: Trigger on every transaction without specifying particular function signature - Calculate percentage of tokens withdrawn in transaction - Revert if withdrawal percentage exceeds configured threshold diff --git a/assertions-book/assertions/ass21-ether-drain.mdx b/assertions-book/assertions/ass21-ether-drain.mdx index 817cc60..7b527ea 100644 --- a/assertions-book/assertions/ass21-ether-drain.mdx +++ b/assertions-book/assertions/ass21-ether-drain.mdx @@ -17,7 +17,7 @@ Malicious actors often attempt to extract all available ETH in a single transact Implements tiered protection strategy to detect rapid ETH draining: -- `forkPreState()` / `forkPostState()`: Capture contract's ETH balance and whitelist balances before/after transaction +- `forkPreTx()` / `forkPostTx()`: Capture contract's ETH balance and whitelist balances before/after transaction - `registerBalanceChangeTrigger()`: Trigger when ETH balances change - For small withdrawals (below threshold): Allow regardless of destination - For large withdrawals (above threshold): Require destination to be whitelisted address diff --git a/assertions-book/assertions/ass28-intra-tx-oracle-deviation.mdx b/assertions-book/assertions/ass28-intra-tx-oracle-deviation.mdx index 1b98cd0..7ed4f16 100644 --- a/assertions-book/assertions/ass28-intra-tx-oracle-deviation.mdx +++ b/assertions-book/assertions/ass28-intra-tx-oracle-deviation.mdx @@ -15,7 +15,7 @@ Intra-transaction price manipulations can lead to flash loan attacks, theft of f Implements approach to verify oracle price updates using both pre/post state comparison and intra-transaction inspection: -- `forkPreState()` / `forkPostState()`: Capture oracle price before and after transaction, compare for deviations +- `forkPreTx()` / `forkPostTx()`: Capture oracle price before and after transaction, compare for deviations - `getCallInputs()`: Monitor all price update function calls within transaction - `registerCallTrigger()`: Trigger when oracle price update is detected - Verify each update's price parameter against initial price diff --git a/assertions-book/previous-hacks/bybit-safe-ui.mdx b/assertions-book/previous-hacks/bybit-safe-ui.mdx index 7d100e6..f59aa1d 100644 --- a/assertions-book/previous-hacks/bybit-safe-ui.mdx +++ b/assertions-book/previous-hacks/bybit-safe-ui.mdx @@ -64,7 +64,7 @@ a transaction. PhEvm precompiles used: -- _forkPreState_ allowing to fork the state of the contract before a transaction +- _forkPreTx_ allowing to fork the state of the contract before a transaction - _load_ reading specific storage slots - _getStateChangesAddress_ getting all state changes within a transaction for a given slot @@ -89,7 +89,7 @@ contract SafeAssertion is Assertion { } function implementationAddressChange() external view { - ph.forkPreState(); + ph.forkPreTx(); address preImplementationAddress = address(uint160(uint256(ph.load(address(safe), bytes32(0x0))))); address[] memory addresses = getStateChangesAddress(address(safe), bytes32(0x0)); @@ -108,14 +108,14 @@ the balance of the whitelisted addresses increased with the respective amount. ```solidity function assertionSafeDrain() external { - ph.forkPreState(); + ph.forkPreTx(); uint256 preBalance = address(bybitSafeAddress).balance; uint256[] memory preWhitelistBalances = new uint256[](whitelistedAddresses.length); for (uint256 i = 0; i < whitelistedAddresses.length; i++) { preWhitelistBalances[i] = address(whitelistedAddresses[i]).balance; } - ph.forkPostState(); + ph.forkPostTx(); uint256 postBalance = address(bybitSafeAddress).balance; if (postBalance > preBalance) { return; // Balance increased, not a hack diff --git a/assertions-book/previous-hacks/cream-finance-2.mdx b/assertions-book/previous-hacks/cream-finance-2.mdx index 3ce2ce9..7d0bb55 100644 --- a/assertions-book/previous-hacks/cream-finance-2.mdx +++ b/assertions-book/previous-hacks/cream-finance-2.mdx @@ -56,7 +56,7 @@ function assertion_priceDeviation() public view { postPrices.push(priceOracle.getPrice(touchedAssets[i])); } - ph.forkPreState(); + ph.forkPreTx(); for (uint256 i = 0; i < touchedAssets.length; i++) { uint256 prePrice = priceOracle.getPrice(touchedAssets[i]); diff --git a/assertions-book/previous-hacks/euler-finance-donation-hack.mdx b/assertions-book/previous-hacks/euler-finance-donation-hack.mdx index 58447d8..3e197f2 100644 --- a/assertions-book/previous-hacks/euler-finance-donation-hack.mdx +++ b/assertions-book/previous-hacks/euler-finance-donation-hack.mdx @@ -63,7 +63,7 @@ Assuming we can check run assertions on each call in the transaction and that we ```solidity function assertionNoUnsafeDebt() external { - ph.forkPostState(); + ph.forkPostTx(); // Get all accounts that were modified in this tx address[] memory accounts = ph.getModifiedAccounts(); diff --git a/assertions-book/previous-hacks/gma-aum-jul25-hack.mdx b/assertions-book/previous-hacks/gma-aum-jul25-hack.mdx index d9bc512..a61cd16 100644 --- a/assertions-book/previous-hacks/gma-aum-jul25-hack.mdx +++ b/assertions-book/previous-hacks/gma-aum-jul25-hack.mdx @@ -77,11 +77,11 @@ function assertSimplifiedAUMBounds() external { // Core principle: AUM should closely track actual token flows // 1. Capture AUM before transaction - ph.forkPreState(); + ph.forkPreTx(); uint256 aumBefore = getAumInUsdg(true); // 2. Capture AUM after transaction - ph.forkPostState(); + ph.forkPostTx(); uint256 aumAfter = getAumInUsdg(true); // 3. Calculate AUM change diff --git a/assertions-book/previous-hacks/hack1-radiant-capital.mdx b/assertions-book/previous-hacks/hack1-radiant-capital.mdx index 419503a..fc9508c 100644 --- a/assertions-book/previous-hacks/hack1-radiant-capital.mdx +++ b/assertions-book/previous-hacks/hack1-radiant-capital.mdx @@ -49,9 +49,9 @@ contract LendingPoolAddressesProviderAssertions is Assertion { // return true indicates a valid state -> owner is the same // return false indicates an invalid state -> owner is different function assertionOwnerChange() external returns (bool) { - ph.forkPreState(); + ph.forkPreTx(); address prevOwner = lendingPoolAddressesProvider.owner(); - ph.forkPostState(); + ph.forkPostTx(); address newOwner = lendingPoolAddressesProvider.owner(); return prevOwner == newOwner; } @@ -60,9 +60,9 @@ contract LendingPoolAddressesProviderAssertions is Assertion { // return true indicates a valid state -> emergency admin is the same // return false indicates an invalid state -> emergency admin is different function assertionEmergencyAdminChange() external returns (bool) { - ph.forkPreState(); + ph.forkPreTx(); address prevEmergencyAdmin = lendingPoolAddressesProvider.getEmergencyAdmin(); - ph.forkPostState(); + ph.forkPostTx(); address newEmergencyAdmin = lendingPoolAddressesProvider.getEmergencyAdmin(); return prevEmergencyAdmin == newEmergencyAdmin; } @@ -71,9 +71,9 @@ contract LendingPoolAddressesProviderAssertions is Assertion { // return true indicates a valid state -> pool admin is the same // return false indicates an invalid state -> pool admin is different function assertionPoolAdminChange() external returns (bool) { - ph.forkPreState(); + ph.forkPreTx(); address prevPoolAdmin = lendingPoolAddressesProvider.getPoolAdmin(); - ph.forkPostState(); + ph.forkPostTx(); address newPoolAdmin = lendingPoolAddressesProvider.getPoolAdmin(); return prevPoolAdmin == newPoolAdmin; } diff --git a/assertions-book/previous-hacks/hack2-vestra-dao.mdx b/assertions-book/previous-hacks/hack2-vestra-dao.mdx index 6b8e936..9d7dcba 100644 --- a/assertions-book/previous-hacks/hack2-vestra-dao.mdx +++ b/assertions-book/previous-hacks/hack2-vestra-dao.mdx @@ -56,7 +56,7 @@ contract VestraDAOHack is Assertion { // Check if the user has already unstaked for a maturity function assertionExample() external { - ph.forkPostState(); + ph.forkPostTx(); PhEvm.CallInputs[] memory unStakes = ph.getCallInputs(address(vestraDAO), vestraDAO.unStake.selector); for (uint256 i = 0; i < unStakes.length; i++) { diff --git a/assertions-book/previous-hacks/visor-finance-unrestricted-mint.mdx b/assertions-book/previous-hacks/visor-finance-unrestricted-mint.mdx index 8cd6ab7..618e556 100644 --- a/assertions-book/previous-hacks/visor-finance-unrestricted-mint.mdx +++ b/assertions-book/previous-hacks/visor-finance-unrestricted-mint.mdx @@ -37,7 +37,7 @@ function assertion_triggerDeposit_remainsSolvent() public view { uint256 postBalanceCollateral = visr.balanceOf(address(adopter)); uint256 postTotalSupplyRewards = vvisr.totalSupply(); uint256 postRatio = postBalanceCollateral / postTotalSupplyRewards; - ph.forkPreState(); + ph.forkPreTx(); uint256 preBalanceCollateral = visr.balanceOf(address(adopter)); uint256 preTotalSupplyRewards = vvisr.totalSupply(); diff --git a/credible/architecture-overview.mdx b/credible/architecture-overview.mdx index 1784c33..b3ef575 100644 --- a/credible/architecture-overview.mdx +++ b/credible/architecture-overview.mdx @@ -195,7 +195,7 @@ The [Credible Layer Contracts](/credible/credible-layer-contracts) are on-chain The Credible Layer can be implemented on different networks. The core concepts remain the same, but implementation details vary by network architecture. For specific implementation details, see: -- [OP Stack Implementation](/credible/architecture-op-stack) +- [OP Stack Implementation](/credible/network-integrations/architecture-op-stack) --- diff --git a/credible/faq.mdx b/credible/faq.mdx index 5d67514..2b69c7f 100644 --- a/credible/faq.mdx +++ b/credible/faq.mdx @@ -240,7 +240,7 @@ Our custom block builder enables the sequencer to check each transaction against This requires no changes to contracts as it is effectively middleware. **Learn More:** -- [Architecture - OP Stack Implementation](/credible/architecture-op-stack) +- [Architecture - OP Stack Implementation](/credible/network-integrations/architecture-op-stack) - [Glossary - Block Builder](/credible/glossary#block-builder) ### Can anyone write assertions for my contracts? diff --git a/credible/network-integration.mdx b/credible/network-integration.mdx index 56022aa..ef59600 100644 --- a/credible/network-integration.mdx +++ b/credible/network-integration.mdx @@ -42,13 +42,13 @@ Networks provide the following integration surfaces: - The enforcer runs alongside the block builder and does not change consensus rules - Enforcement is deterministic and only depends on on-chain state and assertion code -- Networks can stage assertion deployments before enforcing them in production +- dApps choose whether assertions are staged or enforced; networks honor the registry status during validation ## Integration Checklist (High Level) - Identify the block-building hook for transaction validation - Configure access to registry data and assertion bytecode -- Decide on staging vs production enforcement +- Ensure the enforcer respects staged vs enforced assertions as set by dApps - Set up monitoring and incident review workflows ## Integration Requirements (Public) @@ -64,13 +64,13 @@ Networks provide the following integration surfaces: Detailed system architecture and transaction flow - + Plugin-based integration pattern for Besu Sidecar validation flow and enforcement role - + OP Stack integration notes diff --git a/credible/architecture-linea.mdx b/credible/network-integrations/architecture-linea.mdx similarity index 97% rename from credible/architecture-linea.mdx rename to credible/network-integrations/architecture-linea.mdx index b02266d..33aa5e0 100644 --- a/credible/architecture-linea.mdx +++ b/credible/network-integrations/architecture-linea.mdx @@ -67,4 +67,4 @@ flowchart LR - [Network Integration Overview](/credible/network-integration) - [Assertion Enforcer](/credible/assertion-enforcer) - [Assertion DA](/credible/assertion-da) -- [OP Stack](/credible/architecture-op-stack) +- [OP Stack](/credible/network-integrations/architecture-op-stack) diff --git a/credible/architecture-op-stack.mdx b/credible/network-integrations/architecture-op-stack.mdx similarity index 99% rename from credible/architecture-op-stack.mdx rename to credible/network-integrations/architecture-op-stack.mdx index 6ad3a88..928afa6 100644 --- a/credible/architecture-op-stack.mdx +++ b/credible/network-integrations/architecture-op-stack.mdx @@ -10,7 +10,7 @@ For the general integration path, see [Network Integration Overview](/credible/n -Looking for the Besu/Linea pattern? See [Linea / Besu Integration](/credible/architecture-linea). +Looking for the Besu/Linea pattern? See [Linea / Besu Integration](/credible/network-integrations/architecture-linea). ## Architecture Diagram diff --git a/docs.json b/docs.json index 8378fd9..41a1d47 100644 --- a/docs.json +++ b/docs.json @@ -49,9 +49,14 @@ "group": "Integrations", "pages": [ "credible/network-integration", - "credible/dapp-integration", - "credible/architecture-linea", - "credible/architecture-op-stack" + { + "group": "Network Implementations", + "pages": [ + "credible/network-integrations/architecture-linea", + "credible/network-integrations/architecture-op-stack" + ] + }, + "credible/dapp-integration" ] }, {