{"componentChunkName":"component---src-pages-sips-sip-markdown-remark-frontmatter-sip-tsx","path":"/sips/sip-86/","result":{"data":{"markdownRemark":{"fileAbsolutePath":"/vercel/path0/content/sips/sip-86.md","frontmatter":{"sip":86,"sccp":null,"title":"ExchangeRates Chainlink Aggregator V2V3","network":"Ethereum","author":"Clement Balestrat (@clementbalestrat)","type":"Governance","proposal":null,"implementor":null,"release":null,"created":"2020-09-02T00:00:00.000Z","updated":null,"status":"Implemented"},"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>Updating the ExchangeRates contract to use the ChainLink Aggregator V2V3 Interface.</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>The current <code>ExchangeRates</code> contract uses a deprecated version of Chainlink's aggregator interface to get its prices. This SIP proposes to update <code>ExchangeRates</code> to be using a newer version, the <a href=\"https://github.com/smartcontractkit/chainlink/blob/master/evm-contracts/src/v0.6/interfaces/AggregatorV2V3Interface.sol\">AggregatorV2V3Interface</a>, which is a hybrid interface including functions from both V2 and V3 interfaces.</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 inaccurate or wrong. This is not the place to describe how the SIP will address the issue!-->\n<p><a href=\"https://sips.synthetix.io/sips/sip-79\">SIP-79</a> requires <code>ExchangeRates</code> to add a new Chainlink aggregator in order to track <code>fastGasPrice</code>. This is the first time this contract is using an aggregator to fetch a value which is not related to an asset price. Although it is not mandatory for <code>ExchangeRates</code> to track asset rates only, the current implementation may introduce some issues related to how many decimals a value returned by an aggregator contains.\nAll the current aggregators used by the system return 8 decimals, which are then converted to 18 decimals using a multiplier.\nHowever, <code>fasGasPrice</code> aggregator returns a value which is already in WEI (0 decimals), meaning <code>ExchangeRates</code> will have to check if whether or not, the value is already in the expected format.</p>\n<p>Another issue with using the current Aggregator Interface is the amount of gas needed to update a price. To do so, the <code>ExchangeRates</code> contract needs to make two calls to an aggregator in order to get the value and its last update timestamp.</p>\n<p>This SIP proposes to update <code>ExchangeRates</code> to use <code>AggregatorV2V3Interface</code>, which contains a few enhancements that will solve both of the issues explained above.</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<p>The interface proposed by Chainlink provides a <code>decimals()</code> function which returns the number of decimals the aggregator response contains. This will be used to determine if a value needs to be formatted with a multiplier or not in the <code>ExchangeRates</code> contract.</p>\n<p>It also returns all the required data for a price update (value and timestamp) in one single function call, meaning this process will consume a smaller amount of gas.</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<p>Adding new kind of aggregators into <code>ExchangeRates</code> such as <code>fastGasPrice</code> introduces the necessity of handling multiple data formats. If <code>BTC/USD</code> rate contains 8 decimals and <code>fastGasPrice</code> none, then we only need to convert the former.</p>\n<p>Switching to this new interface will allow <code>ExchangeRates</code> to know if an aggregator answer needs to be formatted without the need to hardcode the <code>currencyKey</code> directly into the contract. Then, if let's say the <code>lowGasPrice</code> aggregator needs to be added in the future, no change and redeployment will be required.</p>\n<p>The fact that this interface includes <code>V2</code> and <code>V3</code> will allow <code>ExchangeRates</code> to continue using some functions from the current aggregator which were removed from <code>V3</code>, such as <code>latestRound()</code>. It will also allow the contract to use the following new functions:</p>\n<ul>\n<li><code>decimals()</code> which indicates what kind of format is expected from an aggregator</li>\n<li><code>getRoundData(uint80 _roundId)</code> to get the aggregator data at a specific round ID</li>\n<li><code>latestRoundData()</code> to get the latest aggregator data</li>\n</ul>\n<p>In the <code>ExchangeRates</code>, two functions are used to fetch data from an aggregator: <code>_getRateAndUpdatedTime()</code> and <code>_getRateAndTimestampAtRound()</code>.</p>\n<p>They both require two calls to get a price and a timestamp so it can be stored in the contract.</p>\n<p>Current <code>V2</code> interface doesn't allow these two values to be fetched at the same time, into a single call:</p>\n<pre><code>function getAnswer(uint256 roundId) external view returns (int256);\nfunction getTimestamp(uint256 roundId) external view returns (uint256);\n</code></pre>\n<p>However, the new aggregator simplifies this process by returning the data from a single function, which should decrease the gas cost significantly:</p>\n<pre><code>  function getRoundData(uint80 _roundId)\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n  function latestRoundData()\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n</code></pre>\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>This SIP requires the <code>ExchangeRates</code> contract to update some of its logic to be compatible with the new interface. It also includes finding a solution to store the number of decimals an aggregator will return to avoid any unnecessary calls while fetching a new price update.</p>\n<p>Here is a list of most of the required changes and new implementations:</p>\n<ul>\n<li>New mapping <code>mapping(bytes32 -> unit8) public currencyKeyDecimals</code> to store the currency keys and their number of decimals</li>\n<li><code>addAggregator()</code> calling <code>aggregator.decimals()</code> and storing the returned value into <code>currencyKeyDecimals</code>.</li>\n<li><code>removeAggregator()</code> removing <code>currencyKey</code> from the <code>currencyKeyDecimals</code> mapping.</li>\n<li>New function <code>_formatAggregatorAnswer(bytes32 currencyKey, int256 rate)</code> reading <code>currencyKeyDecimals</code> and applying the multiplier on a rate if needed.</li>\n<li><code>_getRateAndUpdatedTime()</code> and <code>_getRateAndTimestampAtRound()</code> calling <code>latestRoundData()</code> and <code>getRoundData()</code> to fetch the new rates from an aggregator, and using <code>_formatAggregatorAnswer()</code> to format them.</li>\n</ul>\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>Given one aggregator, tracking <code>BTC/USD</code> price:</p>\n<ul>\n<li>When owner calls <code>addAggregator()</code>\n<ul>\n<li><code>currencyKeyDecimals</code> mapping now contains <code>BTC => 8</code></li>\n</ul>\n</li>\n<li>When user calls <code>rateAndTimestampAtRound()</code>\n<ul>\n<li>should return <code>rate</code> and <code>time</code> in correct formats</li>\n</ul>\n</li>\n<li>When user calls <code>rateAndUpdatedTime()</code>\n<ul>\n<li>should return <code>rate</code> and <code>time</code> in correct formats</li>\n</ul>\n</li>\n</ul>\n<p>Given one aggregator, tracking <code>fasGasPrice</code> price:</p>\n<ul>\n<li>When owner calls <code>addAggregator()</code>\n<ul>\n<li><code>currencyKeyDecimals</code> mapping now contains <code>fasGasPrice => 0</code></li>\n</ul>\n</li>\n<li>When user calls <code>rateAndTimestampAtRound()</code>\n<ul>\n<li>should return <code>rate</code> and <code>time</code> in correct formats</li>\n</ul>\n</li>\n<li>When user calls <code>rateAndUpdatedTime()</code>\n<ul>\n<li>should return <code>rate</code> and <code>time</code> in correct formats</li>\n</ul>\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<p>N/A</p>\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>"}},"pageContext":{"id":"ee3501a0-bd60-5d57-88eb-5d9010a780c7","frontmatter__sip":86,"__params":{"frontmatter__sip":"86"}}},"staticQueryHashes":[]}