SIP-184: Remove currentRound auto incrementation from ExchangeRates#1630
SIP-184: Remove currentRound auto incrementation from ExchangeRates#1630leckylao wants to merge 8 commits intofeat/sip-184-dynamic-feesfrom
Conversation
leckylao
commented
Dec 11, 2021
- setting sUSD on constructor;
- moved currentRound auto increment into internalUpdateRates
- setting sUSD on constructor; - moved currentRound auto increment into internalUpdateRates
Codecov Report
@@ Coverage Diff @@
## feat/sip-184-dynamic-fees #1630 +/- ##
==========================================================
Coverage 95.73% 95.74%
==========================================================
Files 83 83
Lines 1945 1949 +4
Branches 609 610 +1
==========================================================
+ Hits 1862 1866 +4
Misses 83 83
Continue to review full report at Codecov.
|
artdgn
left a comment
There was a problem hiding this comment.
I was sure we said that removing the curreRate state variable is the best course of action.
The only place it's used right now is the exchanger for getting the last cached rate for dynamic fee to get the correct set of prices. It can be removed there because you already have the roundIds in the _exchange method that you can pass into the fees method to get the historic prices.
This way, this whole issue with coupling, and incrementing, etc can be avoided.
contracts/ExchangeRates.sol
Outdated
| // The sUSD rate is always 1 and is never stale. | ||
| _setRate("sUSD", 0, SafeDecimalMath.unit(), now); | ||
| // The sUSD rate is always 1 on round 1 and is never stale. | ||
| currentRoundForRate["sUSD"]++; |
There was a problem hiding this comment.
nit: can be just = 1 probably
contracts/ExchangeRates.sol
Outdated
| (sourceRate, time) = _getRateAndTimestampAtRound(sourceCurrencyKey, roundIdForSrc); | ||
| // cacheing to save external call | ||
| _setRate(sourceCurrencyKey, roundIdForSrc, sourceRate, time); | ||
| if (sourceCurrencyKey != "sUSD") _setRate(sourceCurrencyKey, roundIdForSrc, sourceRate, time); |
There was a problem hiding this comment.
the != sUSD check should probably me moved into the _setRate method to avoid the duplicate code and inline ifs. It's probably belongs there anyway because that's the method that has handles the caching and knows how sUSD rate should be cached.
nit: I'd prefer to avoid inline ifs, they're easy to miss when reading, so impact readability and clarity. Aren't used in other places in code. [If there are too many blocks due to nested ifs, it probably means that the code is written in a complex way and is doing too many things and can be refactored, shortening the syntax is only making it worse IMO]
There was a problem hiding this comment.
It does has the != sUSD check in _setRate, here is when reading the sUSD rate don't try to set it. Will put a comment there.
There was a problem hiding this comment.
I meant to remove the require in _setRate, and instead just return if it's sUSD.
So in _setRate instead of this:
require(currencyKey != "sUSD", "Rate of sUSD cannot be updated, it's always UNIT.");
maybe replace with this:
if (currencyKey == "sUSD") {
// no caching is done for sUSD
return;
}
This way, there is no need to have those ifs elsewhere and:
- code is easier to read (less ifs)
- whoever is calling setRate doesn't need to check the currency
Also, nit: "sUSD" should probably be a named constant.
| require(currencyKey != "sUSD", "Rate of sUSD cannot be updated, it's always UNIT."); | ||
| require(roundId > 0, "Round id must be greater than 0."); | ||
|
|
||
| currentRoundForRate[currencyKey] = roundId; |
There was a problem hiding this comment.
I was under the impression that we've agreed that currentRoundForRate should be removed because it introduces more risks, potential for bugs, and too much coupling (between rates and exchanger contract).
There was a problem hiding this comment.
This is the first iteration. And currentRoundForRate is more for improvement due to the tightly coupled code and timeframe.
- Using constant for sUSD; - no cache for sUSD in setRate
Yes, it's pretty much doing the same, instead of creating more params in order to pass in the roundId, it's just reusing the |
artdgn
left a comment
There was a problem hiding this comment.
That's great, now that currentRoundForRate is not used, I think it should be possible to remove it also from the ExchangeRates contract.
contracts/Exchanger.sol
Outdated
| returns (uint exchangeFeeRate) | ||
| { | ||
| exchangeFeeRate = _feeRateForExchange(sourceCurrencyKey, destinationCurrencyKey); | ||
| exchangeFeeRate = _feeRateForExchange(sourceCurrencyKey, destinationCurrencyKey, 0, 0); |
There was a problem hiding this comment.
I see you're using 0, 0 to mean latest rounds. I think it's better to use the correct latestRounds here, and avoid having special logic for 0 there. Less implicit special logic for special values will reduce edge cases and surface area for bugs (explicit > implicit).
Alternatively you can create another method that doesn't expect roundId numbers: _feeRateForExchangeLatestRounds that doesn't expect roundIds and get them from exchangeRates.
contracts/Exchanger.sol
Outdated
| // Note: We are using cache round ID here for cheap read | ||
| uint currentRoundId = exchangeRates().currentRoundForRate(currencyKey); | ||
| (prices, ) = exchangeRates().ratesAndUpdatedTimeForCurrencyLastNRounds(currencyKey, rounds, currentRoundId); | ||
| if (roundId == 0) roundId = exchangeRates().getCurrentRoundId(currencyKey); |
There was a problem hiding this comment.
I don't think this method should try to be smart about the roundId it's getting. It's better to avoid using 0 as a special case if we can. This will reduce coupling, edge cases, and surface area for bugs. This method should just work with the roundId it's getting IMO because it's a low level method.
contracts/Exchanger.sol
Outdated
| ) | ||
| { | ||
| exchangeFeeRate = _feeRateForExchange(sourceCurrencyKey, destinationCurrencyKey); | ||
| exchangeFeeRate = _feeRateForExchange(sourceCurrencyKey, destinationCurrencyKey, 0, 0); |
- Using level method to avoid explicite condition
|
Closed in favor of #1649 |