{"componentChunkName":"component---src-pages-sips-sip-markdown-remark-frontmatter-sip-tsx","path":"/sips/sip-156/","result":{"data":{"markdownRemark":{"fileAbsolutePath":"/vercel/path0/content/sips/sip-156.md","frontmatter":{"sip":156,"sccp":null,"title":"Debt Pool Oracle","network":"Ethereum & Optimism","author":"Kain Warwick (@Kaiynne), Anton Jurisevic (@zyzek)","type":"Governance","proposal":null,"implementor":null,"release":null,"created":"2021-07-05T00:00:00.000Z","updated":null,"status":"Rejected"},"html":"<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>This SIP proposes to replace the existing debt cache mechanism with a debt pool oracle operated by Chainlink.</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<p>This SIP will deprecate the existing debt cache mechanism described in SIPs <a href=\"https://sips.synthetix.io/sips/sip-83\">83</a>\nand <a href=\"https://sips.synthetix.io/sips/sip-91\">91</a> in favour of an oracle that reads the\ncomposition of the debt pool, then calculates the total debt size\noff-chain and pushes it on-chain via a Chainlink aggregation contract.</p>\n<p>The current debt cache mechanism has the benefit of being entirely on-chain, however, it introduces some\ncomplexity to the protocol. By replacing it with a Chainlink oracle we will simplify several functions and reduce gas costs,\nas well as introducing more scalability to the number of Synths the protocol can support, and unifying the\ndebt pool between chains, which is addressed in <a href=\"https://sips.synthetix.io/sips/sip-165\">SIP 165</a>.</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>The current debt cache, while an extremely elegant solution to the problem of calculating the size of the debt pool for use by the minting and burning functions has a number of limitations. The primary limitation driving this proposed change is the upcoming need to unify the debt pools across L1 and L2. This requirement would mean that cross chain messaging would need to be enabled and would introduce further complexity to the implementation.\nMoving this functionality off-chain will allow for a more scalable network as the number of Synths that can comprise the debt pool will no longer be limited by on-chain computational resources.</p>\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<ol>\n<li>Implement a new debt pool contract interface to allow the oracle to read and calculate the skew of each Synth.</li>\n<li>Replace the function to read the debt cache with a new function to read the latest debt oracle value.</li>\n<li>Add a function to minting and burning that tracks the incremental debt since the last debt oracle update.</li>\n</ol>\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<p>The existing debt system requires snapshots to be performed by an off-chain keeper.\nAlthough this is trustless, in that all the logic required for keeping the debt cache number exists\non chain, it is also relatively expensive. This calculation is\nonly becoming moreso as new synths and debt-relevant mechanisms such as loans,\nthe ether wrapper, and futures are added. A debt oracle would need to perform only a single\nstate update and no extra calculations on-chain, and should therefore be substantially more\nefficient to operate. The upshot of the move from an \\(O(n)\\) to an \\(O(1)\\) on-chain component\nmeans that the number of synths the system can support is no longer bottlenecked by the debt snapshot,\nbut by oracle computations, and so this limit should become substantially higher,\nif it is not effectively removed.</p>\n<p>At the same time, we were contemplating extending the current debt cache mechanism to support cross network\nmessaging as well as making a number of other iterative improvements to the calculations.\nHowever, after reviewing the implementation effort compared to performing these calculations\noff-chain we concluded that an oracle was the superior solution.</p>\n<p>While an oracle increases the reliance on off-chain data aggregation,\nthe system this SIP proposes is designed to ensure this procedure is as simple as possible,\nand processes only easily-accessible on-chain data. We believe this solution has\nrelatively few failure modes, and therefore a poses a relatively low risk to the system as a whole.</p>\n<p>The modularity of this design means that it is easily possible to modify the contract-level\nstructure of the debt pool calculation that feeds up to the oracle,\nso that new protocol functionality can be supported without any modifications to the oracle logic.</p>\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<p>As the interface between L1 and L2 is to be unified, <code>DebtCache</code> and <code>BaseDebtCache</code>\nshould be merged back into a single contract with a substantially modified interface:</p>\n<pre><code class=\"language-solidity\">contract DebtCache {\n    function availableDebtComponents() external view returns (bytes32[] memory components);\n    function debtComponent(bytes32 key) external view returns (int component, bool invalid);\n    function totalDebt() external view returns (int debt, bool invalid, bool stale);\n    function totalDebtOnL1() external view returns (int debt, bool invalid, bool stale);\n    function totalDebtOnL2() external view returns (int debt, bool invalid, bool stale);\n    function issuanceCorrection() external view returns (int correction);\n    function updateIssuanceCorrection(int amount, bytes32 synth) external;\n    function isInvalidOrStale() external view returns (bool invalid, bool stale);\n    function debtOracleStaleTime() external view returns (uint staleTime);\n    event DebtUpdated(uint debt);\n}\n</code></pre>\n<p>The <code>debtOracleStaleTime</code> function and <code>DebtUpdated</code> event should be preserved from the respective\n<code>debtCacheStaleTime</code> and <code>DebtCacheUpdated</code> members from the previous implementation.\nThe <code>isInvalidOrStale</code> is simply the merger of the previous <code>isInvalid</code> and <code>isStale</code> functions.\nThe other contract functions are described below.</p>\n<h4 id=\"debt-components\" style=\"position:relative;\"><a href=\"#debt-components\" aria-label=\"debt components 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>Debt Components</h4>\n<p>Currently, the maximum number of components possible in the system is constrained by\nthe execution budget of the <code>currentDebt</code> function. To alleviate this, the\ndebt system should be able to break down the debt cache into each of its component parts, representing the\nnet skew for each synth, including both circulating synths (long) and outstanding non-SNX collateral debt (short).\nThe overall debt pool value will simply be the sum of all these components.</p>\n<p>In this way, Chainlink oracle nodes will just need to perform an off-chain sum over all available synth\ndebt components. The debt pool contract will require new functions to support this:</p>\n<ul>\n<li><code>function availableDebtComponents() external view returns (bytes32[] memory)</code>: Returns the list of all available debt component currency keys (<code>sUSD</code>, <code>sETH</code>, et cetera)</li>\n<li><code>function debtComponent(bytes32 key) external view returns (int component, bool invalid)</code>: Returns the dollar value of a given component of the debt pool. This value will be positive if the debt component is long-skewed, negative if it is short-skewed.</li>\n</ul>\n<p>Each synth's debt component will be calculated as follows:</p>\n<pre><code class=\"language-solidity\">function debtComponent(bytes32 key) external view returns (int component, bool invalid) {\n    (uint rate, bool invalid) = ExchangeRates.getRateAndInvalid(key);\n\n    // The circulating supply is the long part of the debt component\n    uint component = synth(key).totalSupply();\n\n    // Any non-SNX backed debt is the short part of the debt component\n    // Multi-collateral loans\n    component -= collateralManager.long(key) + collateralManager.long(short);\n    // wrapper debt\n    component -= wrapper(key);\n\n    return (component * rate, invalid);\n}\n</code></pre>\n<p>Note that we have omitted the <code>EtherCollateral</code> and <code>EtherCollateralsUSD</code> contributions present in the current\nimplementation, as these are shortly to be deprecated.</p>\n<h4 id=\"oracle-logic\" style=\"position:relative;\"><a href=\"#oracle-logic\" aria-label=\"oracle logic 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>Oracle Logic</h4>\n<p>The Chainlink oracle should report the sum of the debt components in a manner equivalent to the following\nfunction:</p>\n<pre><code class=\"language-javascript\">// Implemented off-chain\nfunction currentDebt() {\n  debt = 0\n  invalid = false\n\n  for (key of DebtPool.availableDebtComponents()) {\n    component, (componentInvalid = DebtPool.debtComponent(key))\n    debt += component\n    invalid |= componentInvalid\n  }\n\n  return debt, invalid\n}\n</code></pre>\n<p>In this way, Synthetix will be able to update the composition of its debt pool calculation by altering the available\ndebt components and the behaviour of the <code>debtComponent</code> function, without Chainlink nodes\nneeding to update their internal logic. Each debt component will at first correspond to a particular synth,\nbut in the future may be extended to different objects.</p>\n<p>The oracle should simply report the current value returned by this <code>currentDebt()</code> function.\nWhenever there is a deviation of 1% or more (SCCP configurable) between this result,\nand the result returned by <code>DebtCache.totalDebt()</code>&#x3C; then a new update should be pushed on chain.\nThe oracle should also operate at a regular heartbeat.</p>\n<h4 id=\"total-debt-and-issuance-corrections\" style=\"position:relative;\"><a href=\"#total-debt-and-issuance-corrections\" aria-label=\"total debt and issuance corrections 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>Total Debt and Issuance Corrections</h4>\n<p>The updated debt cache contract's interface includes a single new function,\nwhich will report the debt as received from the oracle.</p>\n<ul>\n<li><code>function totalDebt() external view returns (uint debt, bool isInvalid)</code></li>\n</ul>\n<p>This function will replace <code>Issuer._totalIssuedSynths</code>, which currently contains a call to\n<code>DebtCache.cacheInfo</code>. As its name implies, <code>totalDebt</code> should report the latest result from the oracle,\nand its validity. There is a caveat here, which is that in between oracle updates, it must still accurately\nreflect the fluctuations in the debt pool induced by the minting and burning of synths.\nit must reflect the resulting fluctuations in the debt pool.\nWithout this, the issue identified in <a href=\"https://sips.synthetix.io/sips/sip-150\">SIP-150</a> will remain in place.\nTo accomplish the desired result, the debt pool contract must track two additional variables:</p>\n<ul>\n<li><code>int256 issuanceCorrection</code>: the net movement in the sUSD value of the debt pool since the last oracle update</li>\n<li><code>uint256 lastTimestamp</code>: the Chainlink debt aggregator update time last known to the cache</li>\n</ul>\n<p>With this in mind, the <code>totalDebt</code> function should approximately implement the following pseudo-code:</p>\n<pre><code class=\"language-solidity\">function totalDebt() external view returns (uint, bool) {\n    // Fetch the latest debt numbers\n    (debt, timestamp, isInvalid) = ExchangeRates.debtAndTimestampAndInvalid();\n\n    // An update has occurred, but the new timestamp has not yet been recorded.\n    // Do not apply the issuance correction in this case.\n    if (lastTimestamp &#x3C; timestamp) {\n        return (debt, isInvalid);\n    }\n\n    // Otherwise, account for all mint/burn events\n    return (debt + issuanceCorrection, isInvalid, _isStale(timestamp));\n}\n</code></pre>\n<p>In addition, whenever new synths are minted or burnt, whether against SNX or otherwise, the\nsUSD value of those synths should be recorded against the <code>issuanceCorrection</code> variable:</p>\n<pre><code class=\"language-solidity\">function updateIssuanceCorrection(int amount, bytes32 synth) external onlyIssuers {\n    // Fail if the oracle's debt value is invalid or stale.\n    (, timestamp, isInvalid) = ExchangeRates.debtAndTimestampAndInvalid();\n    require(!(isInvalid || _isStale(timestamp));\n\n    // If a new update has come through from the oracle, reset the issuance correction\n    if (lastTimestamp &#x3C; timestamp) {\n        lastTimestamp = timestamp;\n        issuanceCorrection = 0;\n    }\n\n    issuanceCorrection += amount * ExchangeRates.getRateAndEnsureValid(synth);\n    emit DebtUpdated(totalDebt());\n}\n</code></pre>\n<p>This function should be invoked whenever synths are created or destroyed, but not when exchanged or transformed into\nanother form, such as by a deposit into a futures margin account. It must be callable only by synth-issuing contracts\nincluding the issuer, wrapper, and multi-collateral contracts. It must fail if any relevant oracle feeds are invalid.</p>\n<h4 id=\"phase-2---total-debt-on-l1-and-l2\" style=\"position:relative;\"><a href=\"#phase-2---total-debt-on-l1-and-l2\" aria-label=\"phase 2   total debt on l1 and l2 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>Phase 2 - Total Debt on L1 and L2</h4>\n<p>The updated debt cache contract's interface includes a two new functions, reporting the <code>totalDebtOnL1</code> and <code>totalDebtOnL2</code>. based on the total debt on mainnet and L2.</p>\n<p>The total debt would be aggregated by Chainlink oracles and reported for both L1 and L2, which will be accessible from the <code>ExchangeRates</code> contract on both layers.</p>\n<ul>\n<li><code>function totalDebtOnL1() external view returns (int debt, bool invalid, bool stale)</code></li>\n<li><code>function totalDebtOnL2() external view returns (int debt, bool invalid, bool stale)</code></li>\n</ul>\n<p>These functions will allow the total combined debt of L1 and L2 debt pools to be calculated within the debt cache contract when debt is issued or burned on both chains.</p>\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<p>TBD</p>\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<table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n<th>Initial Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Max Debt Oracle Deviation</td>\n<td>If the difference between the true system debt and the number reported by the oracle exceeds this value, the oracle should push an updated value on-chain.</td>\n<td>1%</td>\n</tr>\n</tbody>\n</table>\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":"6d88fd6a-8132-592b-9a7b-b2f252042487","frontmatter__sip":156,"__params":{"frontmatter__sip":"156"}}},"staticQueryHashes":[]}