{"componentChunkName":"component---src-pages-sips-sip-markdown-remark-frontmatter-sip-tsx","path":"/sips/sip-187/","result":{"data":{"markdownRemark":{"fileAbsolutePath":"/vercel/path0/content/sips/sip-187.md","frontmatter":{"sip":187,"sccp":null,"title":"Fix Partial Synth Updates In Debt Cache","network":"Ethereum","author":"Jackson Chan (@jacko125)","type":"Governance","proposal":null,"implementor":null,"release":null,"created":"2021-09-30T00:00:00.000Z","updated":null,"status":"Implemented"},"html":"<!--You can leave these HTML comments in your merged SIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. This is the suggested template for new SIPs. Note that an SIP number will be assigned by an editor. When opening a pull request to submit your SIP, please use an abbreviated title in the filename, `sip-draft_title_abbrev.md`. The title should be 44 characters or less.-->\n<h2 id=\"simple-summary\" style=\"position:relative;\"><a href=\"#simple-summary\" aria-label=\"simple summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Simple Summary</h2>\n<!--\"If you can't explain it simply, you don't understand it well enough.\" Simply describe the outcome the proposed changes intends to achieve. This should be non-technical and accessible to a casual community member.-->\n<p>Fix an issue with partial updates of synths in the debt cache which is causing the cached debt value to not update after minting and burning sUSD.</p>\n<h2 id=\"abstract\" style=\"position:relative;\"><a href=\"#abstract\" aria-label=\"abstract permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Abstract</h2>\n<!--A short (~200 word) description of the proposed change, the abstract should clearly describe the proposed change. This is what *will* be done if the SIP is implemented, not *why* it should be done or *how* it will be done. If the SIP proposes deploying a new contract, write, \"we propose to deploy a new contract that will do x\".-->\n<p>This SIP proposes to upgrade the debt cache contract with a fix to the partial synth updates so that the cached debt is updated after minting and burning sUSD. It will remove the subtraction of the excluded debt (that is synths issued by non-SNX collateral) in the calculation of the new synth amounts as this caused them to zero out instead of updating the delta in the synth's amount and how much the cached debt has increased / decreased.</p>\n<h2 id=\"motivation\" style=\"position:relative;\"><a href=\"#motivation\" aria-label=\"motivation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Motivation</h2>\n<!--This is the problem statement. This is the *why* of the SIP. It should clearly explain *why* the current state of the protocol is inadequate.  It is critical that you explain *why* the change is needed, if the SIP proposes changing how something is calculated, you must address *why* the current calculation is innaccurate or wrong. This is not the place to describe how the SIP will address the issue!-->\n<p>In the first iteration of the debt cache, minting and burning sUSD would change the cached debt value by the amount of sUSD minted or burned to reflect the change in sUSD supply. It is important that the debt pool is updated immediately when sUSD is minted or burned to reflect the increase or decrease of the debt pool size before a snapshot happens. With the addition of the ETH wrapper, the debt cache was updated to exclude the non-SNX collateral synths that gets issued against the wrapper ETH and loans. The <code>DebtCache._updateCachedSynthDebtsWithRates()</code> function is used for updating individual synths and the cached debt when minting / burning sUSD and exchanges. But it currently isn't able to update the cached debt because the new <code>cachedSum</code> and <code>currentSum</code> is miscalculated by subtracing the <code>excludedDebtSum</code> from them and the new cached debt doesn't have any change.</p>\n<pre><code>        cachedSum = cachedSum.floorsub(_cachedSynthDebt[EXCLUDED_DEBT_KEY]);\n        currentSum = currentSum.floorsub(excludedDebtSum);\n        _cachedSynthDebt[EXCLUDED_DEBT_KEY] = excludedDebtSum;\n\n        // Compute the difference and apply it to the snapshot\n        if (cachedSum != currentSum) {\n            ...\n        }\n</code></pre>\n<h2 id=\"specification\" style=\"position:relative;\"><a href=\"#specification\" aria-label=\"specification permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Specification</h2>\n<!--The specification should describe the syntax and semantics of any new feature, there are five sections\n1. Overview\n2. Rationale\n3. Technical Specification\n4. Test Cases\n5. Configurable Values\n-->\n<h3 id=\"overview\" style=\"position:relative;\"><a href=\"#overview\" aria-label=\"overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Overview</h3>\n<!--This is a high level overview of *how* the SIP will solve the problem. The overview should clearly describe how the new feature will be implemented.-->\n<p>The <code>DebtCache._updateCachedSynthDebtsWithRates()</code> will be updated to not re-calculate the <code>excludedDebt</code> as that is not calculated in the function and it will only update the <code>_cachedSynthDebt[synth]</code> for the synth to update. The delta for the debt cache update will be calculated as the difference between <code>currentSum - cachedSum</code> which measures the change in updated synths compared to the last cached amount.</p>\n<p>This will ignore any of the changes in the supply of those synths that has been issued by non-SNX collateral such as ETH wrapper and multi-collateral loans for partial synth updates. The <code>excludedDebt</code> value would be updated when the debt snapshot is taken and updates the portion of the debt cache that is excluded.</p>\n<h3 id=\"rationale\" style=\"position:relative;\"><a href=\"#rationale\" aria-label=\"rationale permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Rationale</h3>\n<!--This is where you explain the reasoning behind how you propose to solve the problem. Why did you propose to implement the change in this way, what were the considerations and trade-offs. The rationale fleshes out what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.-->\n<ul>\n<li>Tracks the delta between the current cached synth amounts and current synth amounts.</li>\n<li>The <code>updateCachedSynthDebtsWithRates</code> currently doesn't update the excluded debt amount and should be removed.</li>\n<li>The excluded debt amount is updated during the debt snapshot which keeps the debt within 1% deviations and any synths issued by non-SNX collateral will be recalculated.</li>\n<li>Allows accurate tracking of the debt after stakers mint and burn their sUSD.</li>\n</ul>\n<h3 id=\"technical-specification\" style=\"position:relative;\"><a href=\"#technical-specification\" aria-label=\"technical specification permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Technical Specification</h3>\n<!--The technical specification should outline the public API of the changes proposed. That is, changes to any of the interfaces Synthetix currently exposes or the creations of new ones.-->\n<p>Update the <code>DebtCache</code> contract interface and the <code>_updateCachedSynthDebtsWithRates</code> function which is used internally when there is an <code>exchange</code> of synths and partial updates of synths from the snapshot keeper.</p>\n<p><strong>_updateCachedSynthDebtsWithRates (Before)</strong></p>\n<pre><code>function _updateCachedSynthDebtsWithRates(\n        bytes32[] memory currencyKeys,\n        uint[] memory currentRates,\n        bool anyRateIsInvalid,\n        bool recomputeExcludedDebt\n    ) internal {\n        uint numKeys = currencyKeys.length;\n        require(numKeys == currentRates.length, \"Input array lengths differ\");\n\n        // Update the cached values for each synth, saving the sums as we go.\n        uint cachedSum;\n        uint currentSum;\n        uint excludedDebtSum = _cachedSynthDebt[EXCLUDED_DEBT_KEY];\n        uint[] memory currentValues = _issuedSynthValues(currencyKeys, currentRates);\n\n        for (uint i = 0; i &#x3C; numKeys; i++) {\n            bytes32 key = currencyKeys[i];\n            uint currentSynthDebt = currentValues[i];\n            cachedSum = cachedSum.add(_cachedSynthDebt[key]);\n            currentSum = currentSum.add(currentSynthDebt);\n            _cachedSynthDebt[key] = currentSynthDebt;\n        }\n\n        // Always update the cached value of the excluded debt -- it's computed anyway.\n        if (recomputeExcludedDebt) {\n            (uint excludedDebt, bool anyNonSnxDebtRateIsInvalid) = _totalNonSnxBackedDebt();\n            anyRateIsInvalid = anyRateIsInvalid || anyNonSnxDebtRateIsInvalid;\n            excludedDebtSum = excludedDebt;\n        }\n\n        cachedSum = cachedSum.floorsub(_cachedSynthDebt[EXCLUDED_DEBT_KEY]);\n        currentSum = currentSum.floorsub(excludedDebtSum);\n        _cachedSynthDebt[EXCLUDED_DEBT_KEY] = excludedDebtSum;\n\n        // Compute the difference and apply it to the snapshot\n        if (cachedSum != currentSum) {\n            uint debt = _cachedDebt;\n            // This requirement should never fail, as the total debt snapshot is the sum of the individual synth\n            // debt snapshots.\n            require(cachedSum &#x3C;= debt, \"Cached synth sum exceeds total debt\");\n            debt = debt.sub(cachedSum).add(currentSum);\n            _cachedDebt = debt;\n            emit DebtCacheUpdated(debt);\n        }\n\n        // A partial update can invalidate the debt cache, but a full snapshot must be performed in order\n        // to re-validate it.\n        if (anyRateIsInvalid) {\n            _updateDebtCacheValidity(anyRateIsInvalid);\n        }\n    }\n</code></pre>\n<p><strong>_updateCachedSynthDebtsWithRates (After)</strong></p>\n<pre><code>    function _updateCachedSynthDebtsWithRates(\n        bytes32[] memory currencyKeys,\n        uint[] memory currentRates,\n        bool anyRateIsInvalid,\n    ) internal {\n        uint numKeys = currencyKeys.length;\n        require(numKeys == currentRates.length, \"Input array lengths differ\");\n\n        // Update the cached values for each synth, saving the sums as we go.\n        uint cachedSum;\n        uint currentSum;\n        uint[] memory currentValues = _issuedSynthValues(currencyKeys, currentRates);\n\n        for (uint i = 0; i &#x3C; numKeys; i++) {\n            bytes32 key = currencyKeys[i];\n            uint currentSynthDebt = currentValues[i];\n            cachedSum = cachedSum.add(_cachedSynthDebt[key]);\n            currentSum = currentSum.add(currentSynthDebt);\n            _cachedSynthDebt[key] = currentSynthDebt;\n        }\n\n        // Compute the difference and apply it to the snapshot\n        if (cachedSum != currentSum) {\n            uint debt = _cachedDebt;\n            // This requirement should never fail, as the total debt snapshot is the sum of the individual synth\n            // debt snapshots.\n            require(cachedSum &#x3C;= debt, \"Cached synth sum exceeds total debt\");\n            debt = debt.sub(cachedSum).add(currentSum);\n            _cachedDebt = debt;\n            emit DebtCacheUpdated(debt);\n        }\n\n        // A partial update can invalidate the debt cache, but a full snapshot must be performed in order\n        // to re-validate it.\n        if (anyRateIsInvalid) {\n            _updateDebtCacheValidity(anyRateIsInvalid);\n        }\n    }\n</code></pre>\n<h4 id=\"updating-debt-cache-for-minting-and-burning-susd\" style=\"position:relative;\"><a href=\"#updating-debt-cache-for-minting-and-burning-susd\" aria-label=\"updating debt cache for minting and burning susd permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Updating debt cache for minting and burning sUSD</h4>\n<p>When minting and burning sUSD, the <code>cachedSum[sUSD]</code> and <code>_cachedDebt</code> values that tracks the amount of sUSD should be updated to reflect the increase or decrease in the sUSD supply and the cached debt also updated to track the amount of sUSD that is minted / burned. It would be more accruate to update the amount of sUSD issued or burned, instead of updating the cached value of sUSD by reading the sUSD total supply as this could include non-SNX collateral issued sUSD such as Multi-collateral loans and shorts between snapshots. The excluded debts will be updated during the snapshot instead.</p>\n<p><strong>DebtCache Contract</strong></p>\n<pre><code>contract DebtCache is BaseDebtCache {\n    function increaseCachedsUSDDebt(\n        uint amount\n    ) external onlyIssuer {\n        _cachedSynthDebt[sUSD] = _cachedSynthDebt[sUSD].add(amount);\n        _cachedDebt = _cachedDebt.add(amount);\n    }\n\n    function decreaseCachedsUSDDebt(\n        uint amount\n    ) external onlyIssuer {\n        _cachedSynthDebt[sUSD] = _cachedSynthDebt[sUSD].sub(amount);\n        _cachedDebt = _cachedDebt.add(amount);\n    }\n}\n</code></pre>\n<p><strong>Issuer Contract</strong></p>\n<pre><code>Contract Issuer {\n    function _issueSynths(\n        address from,\n        uint amount,\n        bool issueMax\n    ) internal {\n        (uint maxIssuable, uint existingDebt, uint totalSystemDebt, bool anyRateIsInvalid) = _remainingIssuableSynths(from);\n        _requireRatesNotInvalid(anyRateIsInvalid);\n\n        if (!issueMax) {\n            require(amount &#x3C;= maxIssuable, \"Amount too large\");\n        } else {\n            amount = maxIssuable;\n        }\n\n        // Keep track of the debt they're about to create\n        _addToDebtRegister(from, amount, existingDebt, totalSystemDebt);\n\n        // record issue timestamp\n        _setLastIssueEvent(from);\n\n        // Create their synths\n        synths[sUSD].issue(from, amount);\n\n        // Account for the issued debt in the cache\n        debtCache().increaseCachedsUSDDebt(amount);\n\n        // Store their locked SNX amount to determine their fee % for the period\n        _appendAccountIssuanceRecord(from);\n    }\n\n     function _burnSynths(\n        address debtAccount,\n        address burnAccount,\n        uint amount,\n        uint existingDebt,\n        uint totalDebtIssued\n    ) internal returns (uint amountBurnt) {\n        // liquidation requires sUSD to be already settled / not in waiting period\n\n        // If they're trying to burn more debt than they actually owe, rather than fail the transaction, let's just\n        // clear their debt and leave them be.\n        amountBurnt = existingDebt &#x3C; amount ? existingDebt : amount;\n\n        // Remove liquidated debt from the ledger\n        _removeFromDebtRegister(debtAccount, amountBurnt, existingDebt, totalDebtIssued);\n\n        // synth.burn does a safe subtraction on balance (so it will revert if there are not enough synths).\n        synths[sUSD].burn(burnAccount, amountBurnt);\n\n        // Account for the burnt debt in the cache.\n        debtCache().decreaseCachedsUSDDebt(amountBurnt);\n\n        // Store their debtRatio against a fee period to determine their fee/rewards % for the period\n        _appendAccountIssuanceRecord(debtAccount);\n    }\n\n}\n</code></pre>\n<h3 id=\"test-cases\" style=\"position:relative;\"><a href=\"#test-cases\" aria-label=\"test cases permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Test Cases</h3>\n<!--Test cases for an implementation are mandatory for SIPs but can be included with the implementation..-->\n<ul>\n<li>\n<p>Minting 1000 sUSD, should increase the cached debt by 1000 sUSD.</p>\n</li>\n<li>\n<p>Minting 1000 sUSD, should increase the cached sUSD synths by 1000 sUSD.</p>\n</li>\n<li>\n<p>Burning 1000 sUSD, should decrease the cached debt by 1000 sUSD.</p>\n</li>\n<li>\n<p>Burning 1000 sUSD, should decrease the cached sUSD synths by 1000 sUSD.</p>\n</li>\n</ul>\n<h3 id=\"configurable-values-via-sccp\" style=\"position:relative;\"><a href=\"#configurable-values-via-sccp\" aria-label=\"configurable values via sccp permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configurable Values (Via SCCP)</h3>\n<!--Please list all values configurable via SCCP under this implementation.-->\n<h2 id=\"copyright\" style=\"position:relative;\"><a href=\"#copyright\" aria-label=\"copyright permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Copyright</h2>\n<p>Copyright and related rights waived via <a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0</a>.</p>"}},"pageContext":{"id":"7b7dbfec-0fcc-5311-9583-b418649881d8","frontmatter__sip":187,"__params":{"frontmatter__sip":"187"}}},"staticQueryHashes":[]}