Conversation
- created libraries folder - moving SafeDecimalMath into libraries
- adding decimals into SafeDecimalMath
- Adding dynamic fee constants;
- Adding require check for price; - Adding setup for test;
- Adding more rounds of price feeds for test; - Adding dynamic fee in systemSettings in test
- removed fastForward as startTime and Now is not equal
- Rename priceWeight to RoundDecay - adding cap 100% for max exchangeFeeRate - Added return for invalid rate - linking libraries in setup
…nthetix into feat/sip-184-dynamic-fees
- disable dynamic fee when price feeds less than 2 rounds - disable dynamic fee on exchanger spec settle
- move setPriceAggregator out of the updateRates loop
- Fix set price with no volatility on exchangeAtomically
- remove format from cacheRate as it's already been formatted
- Having the rounds rate loop inside the aggregator
- Using roundId 1 for sUSD to be consistent - Fix interface wrong compiler version warning
- adding --max-old-space-size
Codecov Report
@@ Coverage Diff @@
## develop #1642 +/- ##
===========================================
+ Coverage 95.58% 95.68% +0.09%
===========================================
Files 82 83 +1
Lines 1904 1946 +42
Branches 593 610 +17
===========================================
+ Hits 1820 1862 +42
Misses 84 84
Continue to review full report at Codecov.
|
- update setMissingRates to always add all rates
- increase SNXAmount on stake
- increase SNX stake amount
contracts/ExchangeRates.sol
Outdated
| uint rate, | ||
| uint time | ||
| ) internal { | ||
| if (rate > 0) { |
There was a problem hiding this comment.
should check if rate != cacheRates[currencyKey][roundId].rate to avoid SSTORE for rewriting same rate
| return false; | ||
| } | ||
|
|
||
| function anyRateIsInvalidAtRound(bytes32[] calldata currencyKeys, uint[] calldata roundIds) |
There was a problem hiding this comment.
- This seems to be used only in exchanger and always for two rates, does this need to accept arrays, maybe a single rate method can be used twice instead.
- This checks for flags and time, but doesn't check for 0 rate. probably needs a test case as well. If method's intent is time only, than should be renamed to
anyRateStaleAtRoundor smth.. - Would be good to add doc comments (and specify what invalid means in this case).
There was a problem hiding this comment.
This function is meant the be consistent with function anyRateIsInvalid so the recommendation would likely be apply on both functions therefore would just leave it for now and mark as improvement.
There was a problem hiding this comment.
It looks like the array variants are more gas efficient in terms of number of external calls vs. checking each rate separately.
| uint[] memory roundIds = new uint[](2); | ||
| roundIds[0] = roundIdForSrc; | ||
| roundIds[1] = roundIdForDest; | ||
| require(!exchangeRates().anyRateIsInvalidAtRound(synthKeys, roundIds), "Src/dest rate invalid or not found"); |
There was a problem hiding this comment.
-
As above, can probably check the two rates specificaly instead of creating and iterating on array of 2
-
Not sure if
"or not found"part of message is needed or accurate.
There was a problem hiding this comment.
Similar that the function is meant the be consistent with function _ensureCanExchange so not necessary changing the legacy function would just leave it for now and mark as improvement.
| function _getDynamicFeeForExchange(bytes32 currencyKey) internal view returns (uint dynamicFee) { | ||
| // No dynamic fee for sUSD | ||
| if (currencyKey == sUSD) return 0; | ||
| (uint threshold, uint weightDecay, uint rounds) = getExchangeDynamicFeeData(); |
There was a problem hiding this comment.
nit: getExchangeDynamicFeeData -> getExchangeDynamicFeeParams or getExchangeDynamicFeeConfig
|
|
||
| /// @notice Get exchange max dynamic fee | ||
| /// @return max dynamic fee | ||
| function getExchangeMaxDynamicFee() internal view returns (uint) { |
There was a problem hiding this comment.
should this be added to getExchangeDynamicFeeData to query for them all together?
There was a problem hiding this comment.
It's fetching from different functions though, might just leave it for now.
| @@ -0,0 +1,124 @@ | |||
| ,,,,,,, | |||
| ,round,price,ΔP (bp),boost,dynamic_fee (bp),,deviation threshold (bp) | |||
There was a problem hiding this comment.
please add the formulas text so that numbers can be recreated / checked / adjusted
There was a problem hiding this comment.
Would be refer back to the xlsx spreadsheet.
| function itCanStake({ ctx }) { | ||
| describe('staking and claiming', () => { | ||
| const SNXAmount = ethers.utils.parseEther('100'); | ||
| const SNXAmount = ethers.utils.parseEther('100000'); |
There was a problem hiding this comment.
why was this change needed? (in another PR it was changed to 1000 :)
There was a problem hiding this comment.
Was trying to fix this but unfortunately works on the other PR but not this one
https://app.circleci.com/pipelines/github/Synthetixio/synthetix/9775/workflows/f2026f37-4e7f-4a23-9127-b1d31f20adac/jobs/101109?invite=true#step-109-1867
| await setSystemSetting({ ctx, settingName: 'rateStalePeriod', newValue: '1000000000' }); | ||
|
|
||
| // try to add the missing rates | ||
| await _setMissingRates({ ctx }); |
There was a problem hiding this comment.
I don't think we should remove the check, instead we should check if the aggregators have enough rates for the dynamic fee, and if they don't add them. This always adds and overwrites aggregators, which makes the integration tests less "integration".
There was a problem hiding this comment.
I am not too familiar with the aggregator stuff and how to change that. As you added this part would you mind having a new PR on top of this to change it?
| aggregator = aggregator.connect(owner); | ||
| // set decimals | ||
| await (await aggregator.setDecimals(18)).wait(); | ||
| // deploy an aggregator |
There was a problem hiding this comment.
As these are integration tests, this should probably try to add rates if they're missing, and not always. So probably the check needs to be altered and not removed - it should check probably if there are enough rates, and if there aren't - add them.
|
|
||
| const { timestamp } = await ctx.provider.getBlock(); | ||
| // factory for price aggregators contracts | ||
| const MockAggregatorFactory = await createMockAggregatorFactory(ctx.users.owner); |
There was a problem hiding this comment.
as in the other PR - this method shouldn't deploy and add aggregators, this should be a separate explicit setup step, otherwise this could hide a broken scenario or fork test
|
Also, would be nice to see an updated gas usage report. |
- _setCacheRate also check non-duplicate entry - remove duplicate rates in Exchanger.spec.js
This reverts commit e558ac9.
|
Work continued in #1649 |
No description provided.