Repository: centrifuge/protocol-v3
Pull request #373: Add `HubHelpers`
Author: login: hieronx
Created: 2025-05-14T19:49:01Z | Merged: 2025-05-15T12:07:20Z



Diff:
diff --git a/script/HubDeployer.s.sol b/script/HubDeployer.s.sol
index 489a0e937..3e6eebcc2 100644
--- a/script/HubDeployer.s.sol
+++ b/script/HubDeployer.s.sol
@@ -13,6 +13,7 @@ import {ShareClassManager} from "src/hub/ShareClassManager.sol";
 import {Holdings} from "src/hub/Holdings.sol";
 import {Accounting} from "src/hub/Accounting.sol";
 import {Hub} from "src/hub/Hub.sol";
+import {HubHelpers} from "src/hub/HubHelpers.sol";
 
 import "forge-std/Script.sol";
 import {CommonDeployer} from "script/CommonDeployer.s.sol";
@@ -23,6 +24,7 @@ contract HubDeployer is CommonDeployer {
     Accounting public accounting;
     Holdings public holdings;
     ShareClassManager public shareClassManager;
+    HubHelpers public hubHelpers;
     Hub public hub;
 
     // Utilities
@@ -39,7 +41,8 @@ contract HubDeployer is CommonDeployer {
         accounting = new Accounting(deployer);
         holdings = new Holdings(hubRegistry, deployer);
         shareClassManager = new ShareClassManager(hubRegistry, deployer);
-        hub = new Hub(shareClassManager, hubRegistry, accounting, holdings, gateway, deployer);
+        hubHelpers = new HubHelpers(holdings, accounting, hubRegistry, shareClassManager, deployer);
+        hub = new Hub(gateway, holdings, hubHelpers, accounting, hubRegistry, shareClassManager, deployer);
 
         _poolsRegister();
         _poolsRely();
@@ -64,6 +67,11 @@ contract HubDeployer is CommonDeployer {
         shareClassManager.rely(address(hub));
         gateway.rely(address(hub));
         messageDispatcher.rely(address(hub));
+        hubHelpers.rely(address(hub));
+
+        // Rely hub helpers
+        accounting.rely(address(hubHelpers));
+        shareClassManager.rely(address(hubHelpers));
 
         // Rely others on hub
         hub.rely(address(messageProcessor));
@@ -86,6 +94,8 @@ contract HubDeployer is CommonDeployer {
         hub.file("sender", address(messageDispatcher));
 
         guardian.file("hub", address(hub));
+
+        hubHelpers.file("hub", address(hub));
     }
 
     function _poolsInitialConfig() private {
diff --git a/src/hub/Hub.sol b/src/hub/Hub.sol
index 9168d3096..46329928a 100644
--- a/src/hub/Hub.sol
+++ b/src/hub/Hub.sol
@@ -22,6 +22,7 @@ import {IHubRegistry} from "src/hub/interfaces/IHubRegistry.sol";
 import {IShareClassManager} from "src/hub/interfaces/IShareClassManager.sol";
 import {IHoldings, HoldingAccount} from "src/hub/interfaces/IHoldings.sol";
 import {IHub, AccountType} from "src/hub/interfaces/IHub.sol";
+import {IHubHelpers} from "src/hub/interfaces/IHubHelpers.sol";
 
 /// @title  Hub
 /// @notice Central pool management contract, that brings together all functions in one place.
@@ -35,23 +36,26 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
 
     IGateway public gateway;
     IHoldings public holdings;
+    IHubHelpers public hubHelpers;
     IAccounting public accounting;
     IPoolMessageSender public sender;
     IShareClassManager public shareClassManager;
 
     constructor(
-        IShareClassManager shareClassManager_,
-        IHubRegistry hubRegistry_,
-        IAccounting accounting_,
-        IHoldings holdings_,
         IGateway gateway_,
+        IHoldings holdings_,
+        IHubHelpers hubHelpers_,
+        IAccounting accounting_,
+        IHubRegistry hubRegistry_,
+        IShareClassManager shareClassManager_,
         address deployer
     ) Auth(deployer) {
-        shareClassManager = shareClassManager_;
-        hubRegistry = hubRegistry_;
-        accounting = accounting_;
-        holdings = holdings_;
         gateway = gateway_;
+        holdings = holdings_;
+        hubHelpers = hubHelpers_;
+        accounting = accounting_;
+        hubRegistry = hubRegistry_;
+        shareClassManager = shareClassManager_;
     }
 
     modifier payTransaction() {
@@ -113,28 +117,8 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
         payable
         payTransaction
     {
-        uint128 totalPayoutShareAmount;
-        uint128 totalPaymentAssetAmount;
-        uint128 cancelledAssetAmount;
-
-        for (uint32 i = 0; i < maxClaims; i++) {
-            (uint128 payoutShareAmount, uint128 paymentAssetAmount, uint128 cancelled, bool canClaimAgain) =
-                shareClassManager.claimDeposit(poolId, scId, investor, assetId);
-
-            totalPayoutShareAmount += payoutShareAmount;
-            totalPaymentAssetAmount += paymentAssetAmount;
-
-            // Should be written at most once with non-zero amount iff the last claimable epoch was processed and
-            // the user had a pending cancellation
-            // NOTE: Purposely delaying corresponding message dispatch after deposit fulfillment message
-            if (cancelled > 0) {
-                cancelledAssetAmount = cancelled;
-            }
-
-            if (!canClaimAgain) {
-                break;
-            }
-        }
+        (uint128 totalPayoutShareAmount, uint128 totalPaymentAssetAmount, uint128 cancelledAssetAmount) =
+            hubHelpers.notifyDeposit(poolId, scId, assetId, investor, maxClaims);
 
         if (totalPaymentAssetAmount > 0 || cancelledAssetAmount > 0) {
             sender.sendFulfilledDepositRequest(
@@ -149,28 +133,8 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
         payable
         payTransaction
     {
-        uint128 totalPayoutAssetAmount;
-        uint128 totalPaymentShareAmount;
-        uint128 cancelledShareAmount;
-
-        for (uint32 i = 0; i < maxClaims; i++) {
-            (uint128 payoutAssetAmount, uint128 paymentShareAmount, uint128 cancelled, bool canClaimAgain) =
-                shareClassManager.claimRedeem(poolId, scId, investor, assetId);
-
-            totalPayoutAssetAmount += payoutAssetAmount;
-            totalPaymentShareAmount += paymentShareAmount;
-
-            // Should be written at most once with non-zero amount iff the last claimable epoch was processed and
-            // the user had a pending cancellation
-            // NOTE: Purposely delaying corresponding message dispatch after redemption fulfillment message
-            if (cancelled > 0) {
-                cancelledShareAmount = cancelled;
-            }
-
-            if (!canClaimAgain) {
-                break;
-            }
-        }
+        (uint128 totalPayoutAssetAmount, uint128 totalPaymentShareAmount, uint128 cancelledShareAmount) =
+            hubHelpers.notifyRedeem(poolId, scId, assetId, investor, maxClaims);
 
         if (totalPaymentShareAmount > 0 || cancelledShareAmount > 0) {
             sender.sendFulfilledRedeemRequest(
@@ -243,7 +207,7 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
     /// @inheritdoc IHub
     function notifyAssetPrice(PoolId poolId, ShareClassId scId, AssetId assetId) public payable payTransaction {
         _isManager(poolId);
-        D18 pricePoolPerAsset = _pricePoolPerAsset(poolId, scId, assetId);
+        D18 pricePoolPerAsset = hubHelpers.pricePoolPerAsset(poolId, scId, assetId);
         emit NotifyAssetPrice(assetId.centrifugeId(), poolId, scId, assetId, pricePoolPerAsset);
         sender.sendNotifyPricePoolPerAsset(poolId, scId, assetId, pricePoolPerAsset);
     }
@@ -336,7 +300,7 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
         uint128 approvedAssetAmount
     ) external payable payTransaction returns (uint128 pendingAssetAmount, uint128 approvedPoolAmount) {
         _isManager(poolId);
-        D18 pricePoolPerAsset = _pricePoolPerAsset(poolId, scId, depositAssetId);
+        D18 pricePoolPerAsset = hubHelpers.pricePoolPerAsset(poolId, scId, depositAssetId);
         (pendingAssetAmount, approvedPoolAmount) = shareClassManager.approveDeposits(
             poolId, scId, depositAssetId, nowDepositEpochId, approvedAssetAmount, pricePoolPerAsset
         );
@@ -354,7 +318,7 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
     ) external payable returns (uint128 pendingShareAmount) {
         _isManager(poolId);
 
-        D18 price = _pricePoolPerAsset(poolId, scId, payoutAssetId);
+        D18 price = hubHelpers.pricePoolPerAsset(poolId, scId, payoutAssetId);
         (pendingShareAmount) =
             shareClassManager.approveRedeems(poolId, scId, payoutAssetId, nowRedeemEpochId, approvedShareAmount, price);
     }
@@ -458,16 +422,17 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             IAccounting.AccountDoesNotExist()
         );
 
-        HoldingAccount[] memory accounts = new HoldingAccount[](4);
-        accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
-        accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
-        accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
-        accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
-
-        holdings.initialize(poolId, scId, assetId, valuation, false, accounts);
+        holdings.initialize(
+            poolId,
+            scId,
+            assetId,
+            valuation,
+            false,
+            hubHelpers.holdingAccounts(assetAccount, equityAccount, gainAccount, lossAccount)
+        );
 
         // If increase/decrease was called before initialize, we add journal entries for this
-        _updateAccountingAmount(poolId, scId, assetId, true, holdings.value(poolId, scId, assetId));
+        hubHelpers.updateAccountingAmount(poolId, scId, assetId, true, holdings.value(poolId, scId, assetId));
     }
 
     /// @inheritdoc IHub
@@ -487,44 +452,20 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             IAccounting.AccountDoesNotExist()
         );
 
-        HoldingAccount[] memory accounts = new HoldingAccount[](2);
-        accounts[0] = HoldingAccount(expenseAccount, uint8(AccountType.Expense));
-        accounts[1] = HoldingAccount(liabilityAccount, uint8(AccountType.Liability));
-
-        holdings.initialize(poolId, scId, assetId, valuation, true, accounts);
+        holdings.initialize(
+            poolId, scId, assetId, valuation, true, hubHelpers.liabilityAccounts(expenseAccount, liabilityAccount)
+        );
 
         // If increase/decrease was called before initialize, we add journal entries for this
-        _updateAccountingAmount(poolId, scId, assetId, true, holdings.value(poolId, scId, assetId));
+        hubHelpers.updateAccountingAmount(poolId, scId, assetId, true, holdings.value(poolId, scId, assetId));
     }
 
     /// @inheritdoc IHub
     function updateHoldingValue(PoolId poolId, ShareClassId scId, AssetId assetId) public payable {
         _isManager(poolId);
 
-        accounting.unlock(poolId);
-
         (bool isPositive, uint128 diff) = holdings.update(poolId, scId, assetId);
-
-        // Save a diff=0 update gas cost
-        if (isPositive && diff > 0) {
-            if (holdings.isLiability(poolId, scId, assetId)) {
-                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Liability)), diff);
-                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Expense)), diff);
-            } else {
-                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Gain)), diff);
-                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Asset)), diff);
-            }
-        } else if (diff > 0) {
-            if (holdings.isLiability(poolId, scId, assetId)) {
-                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Expense)), diff);
-                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Liability)), diff);
-            } else {
-                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Asset)), diff);
-                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Loss)), diff);
-            }
-        }
-
-        accounting.lock();
+        hubHelpers.updateAccountingValue(poolId, scId, assetId, isPositive, diff);
     }
 
     /// @inheritdoc IHub
@@ -641,7 +582,7 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             : holdings.decrease(poolId, scId, assetId, pricePoolPerAsset, amount);
 
         if (holdings.isInitialized(poolId, scId, assetId)) {
-            _updateAccountingAmount(poolId, scId, assetId, isIncrease, value);
+            hubHelpers.updateAccountingAmount(poolId, scId, assetId, isIncrease, value);
         }
     }
 
@@ -683,42 +624,4 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             gateway.endTransactionPayment();
         }
     }
-
-    /// @notice Create credit & debit entries for the increase or decrease in the holding amount
-    function _updateAccountingAmount(PoolId poolId, ShareClassId scId, AssetId assetId, bool isPositive, uint128 diff)
-        internal
-    {
-        if (diff == 0) return;
-
-        accounting.unlock(poolId);
-
-        bool isLiability = holdings.isLiability(poolId, scId, assetId);
-        AccountType debitAccountType = isLiability ? AccountType.Expense : AccountType.Asset;
-        AccountType creditAccountType = isLiability ? AccountType.Liability : AccountType.Equity;
-
-        if (isPositive) {
-            accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(debitAccountType)), diff);
-            accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(creditAccountType)), diff);
-        } else {
-            accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(creditAccountType)), diff);
-            accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(debitAccountType)), diff);
-        }
-
-        accounting.lock();
-    }
-
-    function _pricePoolPerAsset(PoolId poolId, ShareClassId scId, AssetId assetId) internal view returns (D18) {
-        AssetId poolCurrency = hubRegistry.currency(poolId);
-        // NOTE: We assume symmetric prices are provided by holdings valuation
-        IERC7726 valuation = holdings.valuation(poolId, scId, assetId);
-
-        // Retrieve amount of 1 asset unit in pool currency
-        uint128 assetUnitAmount = (10 ** hubRegistry.decimals(assetId.raw())).toUint128();
-        uint128 poolUnitAmount = (10 ** hubRegistry.decimals(poolCurrency.raw())).toUint128();
-        uint128 poolAmountPerAsset =
-            valuation.getQuote(assetUnitAmount, assetId.addr(), poolCurrency.addr()).toUint128();
-
-        // Retrieve price by normalizing by pool denomination
-        return d18(poolAmountPerAsset, poolUnitAmount);
-    }
 }
diff --git a/src/hub/HubHelpers.sol b/src/hub/HubHelpers.sol
new file mode 100644
index 000000000..07e2597ab
--- /dev/null
+++ b/src/hub/HubHelpers.sol
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: BUSL-1.1
+pragma solidity 0.8.28;
+
+import {D18, d18} from "src/misc/types/D18.sol";
+import {MathLib} from "src/misc/libraries/MathLib.sol";
+import {IERC7726} from "src/misc/interfaces/IERC7726.sol";
+import {Auth} from "src/misc/Auth.sol";
+
+import {ShareClassId} from "src/common/types/ShareClassId.sol";
+import {AssetId} from "src/common/types/AssetId.sol";
+import {AccountId} from "src/common/types/AccountId.sol";
+import {PoolId} from "src/common/types/PoolId.sol";
+
+import {IHubHelpers} from "src/hub/interfaces/IHubHelpers.sol";
+import {IAccounting} from "src/hub/interfaces/IAccounting.sol";
+import {IHubRegistry} from "src/hub/interfaces/IHubRegistry.sol";
+import {IShareClassManager} from "src/hub/interfaces/IShareClassManager.sol";
+import {IHub, AccountType} from "src/hub/interfaces/IHub.sol";
+import {IHoldings, HoldingAccount} from "src/hub/interfaces/IHoldings.sol";
+
+contract HubHelpers is Auth, IHubHelpers {
+    using MathLib for uint256;
+
+    IHoldings public immutable holdings;
+    IAccounting public immutable accounting;
+    IHubRegistry public immutable hubRegistry;
+    IShareClassManager public immutable shareClassManager;
+
+    IHub public hub;
+
+    constructor(
+        IHoldings holdings_,
+        IAccounting accounting_,
+        IHubRegistry hubRegistry_,
+        IShareClassManager shareClassManager_,
+        address deployer
+    ) Auth(deployer) {
+        holdings = holdings_;
+        accounting = accounting_;
+        hubRegistry = hubRegistry_;
+        shareClassManager = shareClassManager_;
+    }
+
+    /// @inheritdoc IHubHelpers
+    function file(bytes32 what, address data) external auth {
+        if (what == "hub") hub = IHub(data);
+        else revert FileUnrecognizedParam();
+
+        emit File(what, data);
+    }
+
+    //----------------------------------------------------------------------------------------------
+    //  Auth methods
+    //----------------------------------------------------------------------------------------------
+
+    /// @inheritdoc IHubHelpers
+    function notifyDeposit(PoolId poolId, ShareClassId scId, AssetId assetId, bytes32 investor, uint32 maxClaims)
+        external
+        auth
+        returns (uint128 totalPayoutShareAmount, uint128 totalPaymentAssetAmount, uint128 cancelledAssetAmount)
+    {
+        for (uint32 i = 0; i < maxClaims; i++) {
+            (uint128 payoutShareAmount, uint128 paymentAssetAmount, uint128 cancelled, bool canClaimAgain) =
+                shareClassManager.claimDeposit(poolId, scId, investor, assetId);
+
+            totalPayoutShareAmount += payoutShareAmount;
+            totalPaymentAssetAmount += paymentAssetAmount;
+
+            // Should be written at most once with non-zero amount iff the last claimable epoch was processed and
+            // the user had a pending cancellation
+            // NOTE: Purposely delaying corresponding message dispatch after deposit fulfillment message
+            if (cancelled > 0) {
+                cancelledAssetAmount = cancelled;
+            }
+
+            if (!canClaimAgain) {
+                break;
+            }
+        }
+    }
+
+    /// @inheritdoc IHubHelpers
+    function notifyRedeem(PoolId poolId, ShareClassId scId, AssetId assetId, bytes32 investor, uint32 maxClaims)
+        external
+        auth
+        returns (uint128 totalPayoutAssetAmount, uint128 totalPaymentShareAmount, uint128 cancelledShareAmount)
+    {
+        for (uint32 i = 0; i < maxClaims; i++) {
+            (uint128 payoutAssetAmount, uint128 paymentShareAmount, uint128 cancelled, bool canClaimAgain) =
+                shareClassManager.claimRedeem(poolId, scId, investor, assetId);
+
+            totalPayoutAssetAmount += payoutAssetAmount;
+            totalPaymentShareAmount += paymentShareAmount;
+
+            // Should be written at most once with non-zero amount iff the last claimable epoch was processed and
+            // the user had a pending cancellation
+            // NOTE: Purposely delaying corresponding message dispatch after redemption fulfillment message
+            if (cancelled > 0) {
+                cancelledShareAmount = cancelled;
+            }
+
+            if (!canClaimAgain) {
+                break;
+            }
+        }
+    }
+
+    /// @inheritdoc IHubHelpers
+    /// @notice Create credit & debit entries for the deposit or withdrawal of a holding.
+    ///         This updates the asset/expense as well as the equity/liability accounts.
+    function updateAccountingAmount(PoolId poolId, ShareClassId scId, AssetId assetId, bool isPositive, uint128 diff)
+        external
+        auth
+    {
+        if (diff == 0) return;
+
+        accounting.unlock(poolId);
+
+        bool isLiability = holdings.isLiability(poolId, scId, assetId);
+        AccountType debitAccountType = isLiability ? AccountType.Expense : AccountType.Asset;
+        AccountType creditAccountType = isLiability ? AccountType.Liability : AccountType.Equity;
+
+        if (isPositive) {
+            accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(debitAccountType)), diff);
+            accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(creditAccountType)), diff);
+        } else {
+            accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(creditAccountType)), diff);
+            accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(debitAccountType)), diff);
+        }
+
+        accounting.lock();
+    }
+
+    /// @inheritdoc IHubHelpers
+    /// @notice Create credit & debit entries for the increase or decrease in the value of a holding.
+    ///         This updates the asset/expense as well as the gain/loss accounts.
+    function updateAccountingValue(PoolId poolId, ShareClassId scId, AssetId assetId, bool isPositive, uint128 diff)
+        external
+        auth
+    {
+        if (diff == 0) return;
+
+        accounting.unlock(poolId);
+
+        // Save a diff=0 update gas cost
+        if (isPositive && diff > 0) {
+            if (holdings.isLiability(poolId, scId, assetId)) {
+                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Liability)), diff);
+                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Expense)), diff);
+            } else {
+                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Gain)), diff);
+                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Asset)), diff);
+            }
+        } else if (diff > 0) {
+            if (holdings.isLiability(poolId, scId, assetId)) {
+                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Expense)), diff);
+                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Liability)), diff);
+            } else {
+                accounting.addCredit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Asset)), diff);
+                accounting.addDebit(holdings.accountId(poolId, scId, assetId, uint8(AccountType.Loss)), diff);
+            }
+        }
+
+        accounting.lock();
+    }
+
+    //----------------------------------------------------------------------------------------------
+    //  View methods
+    //----------------------------------------------------------------------------------------------
+
+    /// @inheritdoc IHubHelpers
+    function holdingAccounts(
+        AccountId assetAccount,
+        AccountId equityAccount,
+        AccountId gainAccount,
+        AccountId lossAccount
+    ) external pure returns (HoldingAccount[] memory) {
+        HoldingAccount[] memory accounts = new HoldingAccount[](4);
+        accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
+        accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
+        accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
+        accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
+        return accounts;
+    }
+
+    /// @inheritdoc IHubHelpers
+    function liabilityAccounts(AccountId expenseAccount, AccountId liabilityAccount)
+        external
+        pure
+        returns (HoldingAccount[] memory)
+    {
+        HoldingAccount[] memory accounts = new HoldingAccount[](2);
+        accounts[0] = HoldingAccount(expenseAccount, uint8(AccountType.Expense));
+        accounts[1] = HoldingAccount(liabilityAccount, uint8(AccountType.Liability));
+        return accounts;
+    }
+
+    /// @inheritdoc IHubHelpers
+    function pricePoolPerAsset(PoolId poolId, ShareClassId scId, AssetId assetId) external view returns (D18) {
+        AssetId poolCurrency = hubRegistry.currency(poolId);
+        // NOTE: We assume symmetric prices are provided by holdings valuation
+        IERC7726 valuation = holdings.valuation(poolId, scId, assetId);
+
+        // Retrieve amount of 1 asset unit in pool currency
+        uint128 assetUnitAmount = (10 ** hubRegistry.decimals(assetId.raw())).toUint128();
+        uint128 poolUnitAmount = (10 ** hubRegistry.decimals(poolCurrency.raw())).toUint128();
+        uint128 poolAmountPerAsset =
+            valuation.getQuote(assetUnitAmount, assetId.addr(), poolCurrency.addr()).toUint128();
+
+        // Retrieve price by normalizing by pool denomination
+        return d18(poolAmountPerAsset, poolUnitAmount);
+    }
+}
diff --git a/src/hub/interfaces/IHubHelpers.sol b/src/hub/interfaces/IHubHelpers.sol
new file mode 100644
index 000000000..b6caf8751
--- /dev/null
+++ b/src/hub/interfaces/IHubHelpers.sol
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: BUSL-1.1
+pragma solidity >=0.5.0;
+
+import {D18} from "src/misc/types/D18.sol";
+
+import {ShareClassId} from "src/common/types/ShareClassId.sol";
+import {AssetId} from "src/common/types/AssetId.sol";
+import {PoolId} from "src/common/types/PoolId.sol";
+import {AccountId} from "src/common/types/AccountId.sol";
+
+import {HoldingAccount} from "src/hub/interfaces/IHoldings.sol";
+
+interface IHubHelpers {
+    /// @notice Emitted when a call to `file()` was performed.
+    event File(bytes32 what, address addr);
+
+    /// @notice Dispatched when the `what` parameter of `file()` is not supported by the implementation.
+    error FileUnrecognizedParam();
+
+    /// @notice Updates a contract parameter.
+    /// @param what Name of the parameter to update.
+    /// Accepts a `bytes32` representation of 'hub'
+    function file(bytes32 what, address data) external;
+
+    /// @notice Notify a deposit for an investor address located in the chain where the asset belongs
+    function notifyDeposit(PoolId poolId, ShareClassId scId, AssetId assetId, bytes32 investor, uint32 maxClaims)
+        external
+        returns (uint128 totalPayoutShareAmount, uint128 totalPaymentAssetAmount, uint128 cancelledAssetAmount);
+
+    /// @notice Notify a redemption for an investor address located in the chain where the asset belongs
+    function notifyRedeem(PoolId poolId, ShareClassId scId, AssetId assetId, bytes32 investor, uint32 maxClaims)
+        external
+        returns (uint128 totalPayoutAssetAmount, uint128 totalPaymentShareAmount, uint128 cancelledShareAmount);
+
+    function updateAccountingAmount(PoolId poolId, ShareClassId scId, AssetId assetId, bool isPositive, uint128 diff)
+        external;
+
+    function updateAccountingValue(PoolId poolId, ShareClassId scId, AssetId assetId, bool isPositive, uint128 diff)
+        external;
+
+    function holdingAccounts(
+        AccountId assetAccount,
+        AccountId equityAccount,
+        AccountId gainAccount,
+        AccountId lossAccount
+    ) external pure returns (HoldingAccount[] memory accounts);
+
+    function liabilityAccounts(AccountId expenseAccount, AccountId liabilityAccount)
+        external
+        pure
+        returns (HoldingAccount[] memory accounts);
+
+    function pricePoolPerAsset(PoolId poolId, ShareClassId scId, AssetId assetId) external view returns (D18);
+}
diff --git a/test/hub/unit/Hub.t.sol b/test/hub/unit/Hub.t.sol
index 820578e49..f11f26b3e 100644
--- a/test/hub/unit/Hub.t.sol
+++ b/test/hub/unit/Hub.t.sol
@@ -8,7 +8,6 @@ import {IERC7726} from "src/misc/interfaces/IERC7726.sol";
 import {IAuth} from "src/misc/interfaces/IAuth.sol";
 
 import {IGateway} from "src/common/interfaces/IGateway.sol";
-import {VaultUpdateKind} from "src/common/libraries/MessageLib.sol";
 
 import {PoolId} from "src/common/types/PoolId.sol";
 import {AssetId} from "src/common/types/AssetId.sol";
@@ -19,6 +18,7 @@ import {IHoldings} from "src/hub/interfaces/IHoldings.sol";
 import {IAccounting, JournalEntry} from "src/hub/interfaces/IAccounting.sol";
 import {IShareClassManager} from "src/hub/interfaces/IShareClassManager.sol";
 import {IHub} from "src/hub/interfaces/IHub.sol";
+import {IHubHelpers} from "src/hub/interfaces/IHubHelpers.sol";
 import {Hub} from "src/hub/Hub.sol";
 
 contract TestCommon is Test {
@@ -30,12 +30,13 @@ contract TestCommon is Test {
     JournalEntry[] EMPTY;
 
     IHubRegistry immutable hubRegistry = IHubRegistry(makeAddr("HubRegistry"));
+    IHubHelpers immutable hubHelpers = IHubHelpers(makeAddr("HubHelpers"));
     IHoldings immutable holdings = IHoldings(makeAddr("Holdings"));
     IAccounting immutable accounting = IAccounting(makeAddr("Accounting"));
     IShareClassManager immutable scm = IShareClassManager(makeAddr("ShareClassManager"));
     IGateway immutable gateway = IGateway(makeAddr("Gateway"));
 
-    Hub hub = new Hub(scm, hubRegistry, accounting, holdings, gateway, address(this));
+    Hub hub = new Hub(gateway, holdings, hubHelpers, accounting, hubRegistry, scm, address(this));
 
     function setUp() public {
         vm.mockCall(
diff --git a/test/hub/unit/HubHelpers.t.sol b/test/hub/unit/HubHelpers.t.sol
new file mode 100644
index 000000000..9d0e691f0
--- /dev/null
+++ b/test/hub/unit/HubHelpers.t.sol
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.28;
+
+import "forge-std/Test.sol";
+
+import {IAuth} from "src/misc/interfaces/IAuth.sol";
+
+import {PoolId} from "src/common/types/PoolId.sol";
+import {AssetId} from "src/common/types/AssetId.sol";
+import {ShareClassId} from "src/common/types/ShareClassId.sol";
+import {IHubRegistry} from "src/hub/interfaces/IHubRegistry.sol";
+import {IHoldings} from "src/hub/interfaces/IHoldings.sol";
+import {IAccounting} from "src/hub/interfaces/IAccounting.sol";
+import {IShareClassManager} from "src/hub/interfaces/IShareClassManager.sol";
+import {Hub} from "src/hub/Hub.sol";
+import {HubHelpers} from "src/hub/HubHelpers.sol";
+
+contract TestCommon is Test {
+    IHoldings immutable holdings = IHoldings(makeAddr("Holdings"));
+    IAccounting immutable accounting = IAccounting(makeAddr("Accounting"));
+    IHubRegistry immutable hubRegistry = IHubRegistry(makeAddr("HubRegistry"));
+    IShareClassManager immutable scm = IShareClassManager(makeAddr("ShareClassManager"));
+
+    HubHelpers hubHelpers = new HubHelpers(holdings, accounting, hubRegistry, scm, address(this));
+}
+
+contract TestMainMethodsChecks is TestCommon {
+    function testErrNotAuthotized() public {
+        vm.startPrank(makeAddr("noWard"));
+
+        vm.expectRevert(IAuth.NotAuthorized.selector);
+        hubHelpers.notifyDeposit(PoolId.wrap(0), ShareClassId.wrap(0), AssetId.wrap(0), bytes32(0), 0);
+
+        vm.expectRevert(IAuth.NotAuthorized.selector);
+        hubHelpers.notifyRedeem(PoolId.wrap(0), ShareClassId.wrap(0), AssetId.wrap(0), bytes32(0), 0);
+
+        vm.expectRevert(IAuth.NotAuthorized.selector);
+        hubHelpers.updateAccountingAmount(PoolId.wrap(0), ShareClassId.wrap(0), AssetId.wrap(0), true, 0);
+
+        vm.expectRevert(IAuth.NotAuthorized.selector);
+        hubHelpers.updateAccountingValue(PoolId.wrap(0), ShareClassId.wrap(0), AssetId.wrap(0), true, 0);
+
+        vm.stopPrank();
+    }
+}


Reviews:
user: login: lemunozm
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T21:29:15Z
user: login: wischli
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T06:58:29Z
user: login: hieronx
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T10:01:02Z
user: login: lemunozm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T10:38:21Z
user: login: hieronx
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T11:00:01Z
user: login: wischli
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T12:03:11Z
user: login: wischli
body: Merge train here we go!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T12:03:36Z

Review comments:
diff_hunk: @@ -458,16 +422,18 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             IAccounting.AccountDoesNotExist()
         );
 
-        HoldingAccount[] memory accounts = new HoldingAccount[](4);
-        accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
-        accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
-        accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
-        accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
+        {
+            HoldingAccount[] memory accounts = new HoldingAccount[](4);
+            accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
+            accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
+            accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
+            accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
path: src/hub/Hub.sol
user: login: wischli
body: Just a thought: Why don't we move the array initialization also to the hub helpers? IMO, this would align better with how we use the helper for other calls where the lower level logic is handled by the helper.
created_at: 2025-05-15T06:52:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -39,7 +41,8 @@ contract HubDeployer is CommonDeployer {
         accounting = new Accounting(deployer);
         holdings = new Holdings(hubRegistry, deployer);
         shareClassManager = new ShareClassManager(hubRegistry, deployer);
-        hub = new Hub(shareClassManager, hubRegistry, accounting, holdings, gateway, deployer);
+        hubHelpers = new HubHelpers(holdings, accounting, hubRegistry, shareClassManager, deployer);
+        hub = new Hub(shareClassManager, hubRegistry, accounting, hubHelpers, holdings, gateway, deployer);
path: script/HubDeployer.s.sol
user: login: wischli
body: Nit: I'd prefer to have the same order of contracts both for the helper and the hub.
created_at: 2025-05-15T06:52:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+// SPDX-License-Identifier: BUSL-1.1
+pragma solidity 0.8.28;
+
+import {D18, d18} from "src/misc/types/D18.sol";
+import {MathLib} from "src/misc/libraries/MathLib.sol";
+import {IERC7726} from "src/misc/interfaces/IERC7726.sol";
+import {Auth} from "src/misc/Auth.sol";
+
+import {ShareClassId} from "src/common/types/ShareClassId.sol";
+import {AssetId} from "src/common/types/AssetId.sol";
+import {AccountId} from "src/common/types/AccountId.sol";
+import {PoolId} from "src/common/types/PoolId.sol";
+
+import {IHubHelpers} from "src/hub/interfaces/IHubHelpers.sol";
+import {IAccounting} from "src/hub/interfaces/IAccounting.sol";
+import {IHubRegistry} from "src/hub/interfaces/IHubRegistry.sol";
+import {IShareClassManager} from "src/hub/interfaces/IShareClassManager.sol";
+import {IHoldings} from "src/hub/interfaces/IHoldings.sol";
+import {IHub, AccountType} from "src/hub/interfaces/IHub.sol";
+
+contract HubHelpers is Auth, IHubHelpers {
+    using MathLib for uint256;
+
+    IHoldings public immutable holdings;
+    IAccounting public immutable accounting;
+    IHubRegistry public immutable hubRegistry;
+    IShareClassManager public immutable shareClassManager;
path: src/hub/HubHelpers.sol
user: login: wischli
body: Maybe CR: Curious why for the helper these are set to `immutable` whereas for the hub that's not the case. Seems erroneous to me because they should in sync regarding mutability?
created_at: 2025-05-15T06:57:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,183 @@
+// SPDX-License-Identifier: BUSL-1.1
+pragma solidity 0.8.28;
+
+import {D18, d18} from "src/misc/types/D18.sol";
+import {MathLib} from "src/misc/libraries/MathLib.sol";
+import {IERC7726} from "src/misc/interfaces/IERC7726.sol";
+import {Auth} from "src/misc/Auth.sol";
+
+import {ShareClassId} from "src/common/types/ShareClassId.sol";
+import {AssetId} from "src/common/types/AssetId.sol";
+import {AccountId} from "src/common/types/AccountId.sol";
+import {PoolId} from "src/common/types/PoolId.sol";
+
+import {IHubHelpers} from "src/hub/interfaces/IHubHelpers.sol";
+import {IAccounting} from "src/hub/interfaces/IAccounting.sol";
+import {IHubRegistry} from "src/hub/interfaces/IHubRegistry.sol";
+import {IShareClassManager} from "src/hub/interfaces/IShareClassManager.sol";
+import {IHoldings} from "src/hub/interfaces/IHoldings.sol";
+import {IHub, AccountType} from "src/hub/interfaces/IHub.sol";
+
+contract HubHelpers is Auth, IHubHelpers {
+    using MathLib for uint256;
+
+    IHoldings public immutable holdings;
+    IAccounting public immutable accounting;
+    IHubRegistry public immutable hubRegistry;
+    IShareClassManager public immutable shareClassManager;
path: src/hub/HubHelpers.sol
user: login: hieronx
body: Making them `immutable` in the` Hub` increases the bytecode size :(
created_at: 2025-05-15T10:01:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -458,16 +422,18 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             IAccounting.AccountDoesNotExist()
         );
 
-        HoldingAccount[] memory accounts = new HoldingAccount[](4);
-        accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
-        accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
-        accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
-        accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
+        {
+            HoldingAccount[] memory accounts = new HoldingAccount[](4);
+            accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
+            accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
+            accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
+            accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
path: src/hub/Hub.sol
user: login: lemunozm
body: Same for liabilities
created_at: 2025-05-15T10:38:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -458,16 +422,18 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             IAccounting.AccountDoesNotExist()
         );
 
-        HoldingAccount[] memory accounts = new HoldingAccount[](4);
-        accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
-        accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
-        accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
-        accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
+        {
+            HoldingAccount[] memory accounts = new HoldingAccount[](4);
+            accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
+            accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
+            accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
+            accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
path: src/hub/Hub.sol
user: login: hieronx
body: Would you move just these 5 lines to `HubHelpers`, or the `initialize` call as well?

It seems to me we don't gain too much since you still need to pass all these params
created_at: 2025-05-15T11:00:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -458,16 +422,18 @@ contract Hub is Multicall, Auth, Recoverable, IHub, IHubGatewayHandler, IHubGuar
             IAccounting.AccountDoesNotExist()
         );
 
-        HoldingAccount[] memory accounts = new HoldingAccount[](4);
-        accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
-        accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
-        accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
-        accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
+        {
+            HoldingAccount[] memory accounts = new HoldingAccount[](4);
+            accounts[0] = HoldingAccount(assetAccount, uint8(AccountType.Asset));
+            accounts[1] = HoldingAccount(equityAccount, uint8(AccountType.Equity));
+            accounts[2] = HoldingAccount(gainAccount, uint8(AccountType.Gain));
+            accounts[3] = HoldingAccount(lossAccount, uint8(AccountType.Loss));
path: src/hub/Hub.sol
user: login: wischli
body: > Would you move just these 5 lines to `HubHelpers`, or the `initialize` call as well?
> 
> It seems to me we don't gain too much since you still need to pass all these params

Good point. I think I'd prefer moving the initialization to the helper then as well but no strong opinion - let's merge as is.
created_at: 2025-05-15T12:03:11Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-15T12:05:43Z
body: Coverage after merging <b>hub-helpers</b> into <b>fix/start-end-transactional-payment</b> will be<table><tbody><tr><th>89.73%</th></tr></tbody></table>

<details><summary>Coverage Report</summary><table><tbody><tr><th>File</th><th>Stmts</th><th>Branches</th><th>Funcs</th><th>Lines</th><th>Uncovered Lines</th></tr><tr><td colspan='6'><b>src/common</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/GasService.sol'>GasService.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Gateway.sol'>Gateway.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol'>Guardian.sol</a></td><td><b>70.15%</b></td><td><b>58.33%</b></td><td><b>73.33%</b></td><td><b>72.50%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L104'>104</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L108-L109'>108&ndash;109</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L124-L125'>124&ndash;125</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L48-L49'>48&ndash;49</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L49-L51'>49&ndash;51</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L86-L87'>86&ndash;87</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L91-L92'>91&ndash;92</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Guardian.sol#L96'>96</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol'>MessageDispatcher.sol</a></td><td><b>60.27%</b></td><td><b>53.03%</b></td><td><b>66.67%</b></td><td><b>62.50%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L117'>117</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L124-L125'>124&ndash;125</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L127'>127</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L140-L141'>140&ndash;141</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L141'>141</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L141-L142'>141&ndash;142</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L144'>144</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L236-L237'>236&ndash;237</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L263'>263</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L267'>267</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L267'>267</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L267-L268'>267&ndash;268</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L270'>270</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L352-L353'>352&ndash;353</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L370'>370</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L374'>374</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L374'>374</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L374-L375'>374&ndash;375</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L377'>377</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L390-L391'>390&ndash;391</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L391'>391</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L391-L392'>391&ndash;392</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L394'>394</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L401-L402'>401&ndash;402</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L402'>402</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L402-L403'>402&ndash;403</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L405'>405</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L414-L415'>414&ndash;415</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L415'>415</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L415-L416'>415&ndash;416</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L418'>418</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L426-L427'>426&ndash;427</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L427'>427</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L427-L428'>427&ndash;428</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L430'>430</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L435-L436'>435&ndash;436</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L436'>436</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L436-L437'>436&ndash;437</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L439'>439</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L444'>444</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L452'>452</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L452'>452</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L452-L453'>452&ndash;453</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L457'>457</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L470-L471'>470&ndash;471</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L507-L508'>507&ndash;508</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L528-L529'>528&ndash;529</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L548-L549'>548&ndash;549</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L593'>593</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L596'>596</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageDispatcher.sol#L65-L69'>65&ndash;69</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol'>MessageProcessor.sol</a></td><td><b>64.74%</b></td><td><b>39.39%</b></td><td>100%</td><td><b>79.41%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L104'>104</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L104-L106'>104&ndash;106</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L109'>109</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L109-L112'>109&ndash;112</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L112-L114'>112&ndash;114</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L117'>117</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L120'>120</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L125'>125</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L130'>130</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L135'>135</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L140'>140</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L145'>145</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L156'>156</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L167'>167</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L167-L169'>167&ndash;169</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L172'>172</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L182'>182</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L189'>189</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L198'>198</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L203'>203</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L213'>213</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L213'>213</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L213-L216'>213&ndash;216</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L216'>216</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L216-L219'>216&ndash;219</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L219'>219</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L219-L221'>219&ndash;221</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L223'>223</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L52-L56'>52&ndash;56</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L69'>69</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L72'>72</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L75'>75</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L75-L77'>75&ndash;77</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L80'>80</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L83'>83</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L85'>85</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L96'>96</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/MessageProcessor.sol#L99'>99</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Root.sol'>Root.sol</a></td><td><b>98.48%</b></td><td><b>91.67%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/Root.sol#L23'>23</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/TokenRecoverer.sol'>TokenRecoverer.sol</a></td><td><b>84.62%</b></td><td><b>50%</b></td><td>100%</td><td><b>88.89%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/TokenRecoverer.sol#L25-L26'>25&ndash;26</a></td></tr><tr><td colspan='6'><b>src/common/adapters</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/adapters/AxelarAdapter.sol'>AxelarAdapter.sol</a></td><td><b>90.91%</b></td><td><b>83.33%</b></td><td>100%</td><td><b>92.59%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/adapters/AxelarAdapter.sol#L43-L44'>43&ndash;44</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/adapters/AxelarAdapter.sol#L53-L54'>53&ndash;54</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/adapters/WormholeAdapter.sol'>WormholeAdapter.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/common/libraries</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol'>MessageLib.sol</a></td><td><b>87.69%</b></td><td><b>53.09%</b></td><td><b>97.73%</b></td><td><b>99.04%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L1020'>1020</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L1050'>1050</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L1078'>1078</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L1101'>1101</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L1121'>1121</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L124-L125'>124&ndash;125</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L130'>130</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L170'>170</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L187'>187</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L208'>208</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L232'>232</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L249'>249</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L272'>272</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L313'>313</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L343'>343</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L369'>369</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L395'>395</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L415'>415</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L439'>439</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L467'>467</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L489'>489</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L511'>511</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L532'>532</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L563'>563</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L590'>590</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L613'>613</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L635'>635</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L657'>657</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L680'>680</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L702'>702</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L729'>729</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L755'>755</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L780'>780</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L812'>812</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L856'>856</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L896'>896</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L935'>935</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L963'>963</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageLib.sol#L992'>992</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageProofLib.sol'>MessageProofLib.sol</a></td><td><b>88.89%</b></td><td><b>50%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/MessageProofLib.sol#L14'>14</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/PricingLib.sol'>PricingLib.sol</a></td><td><b>97.14%</b></td><td><b>85.71%</b></td><td>100%</td><td><b>98.15%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/common/libraries/PricingLib.sol#L102-L103'>102&ndash;103</a></td></tr><tr><td colspan='6'><b>src/hooks</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol'>FreezeOnly.sol</a></td><td><b>5.08%</b></td><td><b>0%</b></td><td><b>11.11%</b></td><td><b>5.26%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L101'>101</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L106-L107'>106&ndash;107</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L107'>107</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L107-L108'>107&ndash;108</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L108'>108</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L108'>108</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L110-L111'>110&ndash;111</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L113'>113</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L117-L119'>117&ndash;119</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L121'>121</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L125-L126'>125&ndash;126</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L134-L135'>134&ndash;135</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L45'>45</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L50'>50</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L50'>50</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L50-L51'>50&ndash;51</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L55'>55</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L62'>62</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L66'>66</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L71-L72'>71&ndash;72</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L72'>72</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L74'>74</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L77-L78'>77&ndash;78</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L78'>78</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L80'>80</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L83'>83</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L91-L92'>91&ndash;92</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L94'>94</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L94'>94</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L94-L97'>94&ndash;97</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L97'>97</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FreezeOnly.sol#L97-L99'>97&ndash;99</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FullRestrictions.sol'>FullRestrictions.sol</a></td><td><b>97.65%</b></td><td><b>90%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FullRestrictions.sol#L122'>122</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/FullRestrictions.sol#L146'>146</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol'>RedemptionRestrictions.sol</a></td><td><b>52.33%</b></td><td><b>25%</b></td><td><b>63.64%</b></td><td><b>60%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L107'>107</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L110'>110</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L110'>110</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L110-L113'>110&ndash;113</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L113'>113</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L113-L115'>113&ndash;115</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L117'>117</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L122-L123'>122&ndash;123</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L123'>123</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L123-L124'>123&ndash;124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L126-L127'>126&ndash;127</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L129'>129</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L133-L135'>133&ndash;135</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L137'>137</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L141'>141</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L146-L148'>146&ndash;148</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L53'>53</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L75'>75</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L77'>77</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L81'>81</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L83'>83</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L86'>86</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hooks/RedemptionRestrictions.sol#L88'>88</a></td></tr><tr><td colspan='6'><b>src/hub</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Accounting.sol'>Accounting.sol</a></td><td><b>93.75%</b></td><td><b>96%</b></td><td>100%</td><td><b>91.53%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Accounting.sol#L113-L114'>113&ndash;114</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Accounting.sol#L117-L118'>117&ndash;118</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Accounting.sol#L133'>133</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Accounting.sol#L136'>136</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Holdings.sol'>Holdings.sol</a></td><td><b>97.75%</b></td><td><b>88.89%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Holdings.sol#L180'>180</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Holdings.sol#L76'>76</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol'>Hub.sol</a></td><td><b>80.92%</b></td><td><b>45.95%</b></td><td><b>97.92%</b></td><td><b>83.33%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L106'>106</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L179'>179</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L181-L182'>181&ndash;182</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L193-L194'>193&ndash;194</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L223'>223</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L234'>234</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L245'>245</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L256'>256</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L267'>267</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L271'>271</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L273'>273</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L280'>280</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L376'>376</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L376'>376</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L376'>376</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L378-L379'>378&ndash;379</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L392'>392</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L419'>419</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L449-L450'>449&ndash;450</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L450'>450</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L450'>450</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L455'>455</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L460'>460</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L478'>478</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L488'>488</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L502'>502</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L509-L511'>509&ndash;511</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L552-L553'>552&ndash;553</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L564-L565'>564&ndash;565</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L612'>612</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L64'>64</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L75-L76'>75&ndash;76</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L76'>76</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L76-L77'>76&ndash;77</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L77'>77</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L77-L78'>77&ndash;78</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L78'>78</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L78-L79'>78&ndash;79</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L79'>79</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/Hub.sol#L79-L80'>79&ndash;80</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubHelpers.sol'>HubHelpers.sol</a></td><td><b>86.14%</b></td><td><b>80%</b></td><td><b>88.89%</b></td><td><b>87.01%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubHelpers.sol#L147-L149'>147&ndash;149</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubHelpers.sol#L155-L157'>155&ndash;157</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubHelpers.sol#L187'>187</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubHelpers.sol#L192-L195'>192&ndash;195</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubHelpers.sol#L46-L47'>46&ndash;47</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubRegistry.sol'>HubRegistry.sol</a></td><td><b>93.51%</b></td><td><b>79.17%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubRegistry.sol#L103'>103</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubRegistry.sol#L109'>109</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubRegistry.sol#L115'>115</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubRegistry.sol#L32'>32</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/HubRegistry.sol#L43'>43</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/hub/ShareClassManager.sol'>ShareClassManager.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/misc</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/Auth.sol'>Auth.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/BaseValuation.sol'>BaseValuation.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/ERC20.sol'>ERC20.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/IdentityValuation.sol'>IdentityValuation.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/Multicall.sol'>Multicall.sol</a></td><td><b>83.33%</b></td><td><b>33.33%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/Multicall.sol#L17'>17</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/Multicall.sol#L17'>17</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/Recoverable.sol'>Recoverable.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/ReentrancyProtection.sol'>ReentrancyProtection.sol</a></td><td><b>90%</b></td><td><b>75%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/ReentrancyProtection.sol#L22'>22</a></td></tr><tr><td colspan='6'><b>src/misc/libraries</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/ArrayLib.sol'>ArrayLib.sol</a></td><td><b>95.83%</b></td><td><b>75%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/ArrayLib.sol#L26'>26</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BitmapLib.sol'>BitmapLib.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol'>BytesLib.sol</a></td><td><b>89.72%</b></td><td><b>54.17%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L102'>102</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L113'>113</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L135'>135</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L146'>146</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L157'>157</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L168'>168</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L17'>17</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L179'>179</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L75'>75</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/BytesLib.sol#L80'>80</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/CastLib.sol'>CastLib.sol</a></td><td><b>95.12%</b></td><td><b>66.67%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/CastLib.sol#L31'>31</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/CastLib.sol#L7'>7</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/EIP712Lib.sol'>EIP712Lib.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol'>MathLib.sol</a></td><td><b>72.04%</b></td><td><b>64.71%</b></td><td>100%</td><td><b>70.59%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L100'>100</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L108'>108</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L111'>111</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L114'>114</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L117'>117</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L121'>121</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L126'>126</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L131-L136'>131&ndash;136</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L142-L143'>142&ndash;143</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L33-L34'>33&ndash;34</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L43'>43</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L45'>45</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L47'>47</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L49'>49</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L51'>51</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L86'>86</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L93'>93</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L96'>96</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/MathLib.sol#L99'>99</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/SafeTransferLib.sol'>SafeTransferLib.sol</a></td><td><b>96.97%</b></td><td><b>92.86%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/SafeTransferLib.sol#L59'>59</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/SignatureLib.sol'>SignatureLib.sol</a></td><td><b>95.24%</b></td><td><b>80%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/SignatureLib.sol#L17'>17</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/StringLib.sol'>StringLib.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/TransientArrayLib.sol'>TransientArrayLib.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/TransientBytesLib.sol'>TransientBytesLib.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/misc/libraries/TransientStorageLib.sol'>TransientStorageLib.sol</a></td><td>100%</td><td>100%</td><td>100%</td><td>100%</td><td></td></tr><tr><td colspan='6'><b>src/vaults</b></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol'>AsyncRequestManager.sol</a></td><td><b>97.69%</b></td><td><b>90.54%</b></td><td>100%</td><td>100%</td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L108'>108</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L214'>214</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L248'>248</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L356'>356</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L361'>361</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L398'>398</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncRequestManager.sol#L400'>400</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncVault.sol'>AsyncVault.sol</a></td><td><b>96.15%</b></td><td><b>83.33%</b></td><td><b>94.44%</b></td><td><b>98.15%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncVault.sol#L146'>146</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/AsyncVault.sol#L47'>47</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol'>BalanceSheet.sol</a></td><td><b>87.42%</b></td><td><b>80%</b></td><td><b>86.36%</b></td><td><b>89.72%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L105'>105</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L108'>108</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L218'>218</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L223'>223</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L228'>228</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L236-L237'>236&ndash;237</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L262'>262</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L264'>264</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L264-L265'>264&ndash;265</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L276'>276</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L280'>280</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L280-L281'>280&ndash;281</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L82'>82</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BalanceSheet.sol#L89'>89</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol'>BaseRequestManager.sol</a></td><td><b>78.46%</b></td><td><b>33.33%</b></td><td><b>90.91%</b></td><td><b>88.10%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L44-L45'>44&ndash;45</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L45'>45</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L45-L46'>45&ndash;46</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L46'>46</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L46-L48'>46&ndash;48</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L57-L58'>57&ndash;58</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseRequestManager.sol#L70-L71'>70&ndash;71</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol'>BaseVaults.sol</a></td><td><b>92.54%</b></td><td><b>80.77%</b></td><td><b>95.24%</b></td><td><b>93.98%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L137'>137</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L239'>239</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L313-L314'>313&ndash;314</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L400-L401'>400&ndash;401</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L85-L86'>85&ndash;86</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L86'>86</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/BaseVaults.sol#L86-L88'>86&ndash;88</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol'>Escrow.sol</a></td><td><b>87.04%</b></td><td><b>60%</b></td><td>100%</td><td><b>91.89%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol#L20'>20</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol#L22'>22</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol#L26-L27'>26&ndash;27</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol#L27'>27</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol#L27'>27</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/Escrow.sol#L29'>29</a></td></tr><tr><td>&nbsp; &nbsp;<a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol'>PoolManager.sol</a></td><td><b>88.77%</b></td><td><b>73.96%</b></td><td>100%</td><td><b>93.22%</b></td><td><a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L123'>123</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L123-L124'>123&ndash;124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L124'>124</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L152'>152</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L152-L153'>152&ndash;153</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L153'>153</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L157'>157</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L274'>274</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L328'>328</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L331'>331</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L343'>343</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L345'>345</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L348'>348</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L351'>351</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L351'>351</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L351-L353'>351&ndash;353</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L355-L356'>355&ndash;356</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L356'>356</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L356'>356</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L358-L361'>358&ndash;361</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L361'>361</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L361-L363'>361&ndash;363</a>, <a href='https://github.com/centrifuge/protocol-v3/blob/c1841643151e33ec43783354d1c1f83e0bbdf1bf/src/vaults/PoolManager.sol#L365'>365</a>, <a href='https://g
author_association: NONE