@@ -21,8 +21,6 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
2121 using SafeCast for * ;
2222
2323 uint256 private constant _BASIS_POINT_SCALE = 1e4 ;
24- uint256 private constant _PRECISION = 1e18 ;
25- uint8 private constant _MAX_REGRESSION_POINTS = 30 ;
2624
2725 struct Pair {
2826 IERC20 token1;
@@ -31,7 +29,6 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
3129 uint256 oracleTTL;
3230 uint256 numerator;
3331 uint256 denominator;
34- uint8 accrualRounds;
3532 }
3633 // Numerator and denominator account for the difference in decimals between the two tokens AND for the decimals
3734 // of the oracle. They are used to scale the conversion rate between the two tokens.
@@ -69,8 +66,7 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
6966 IERC20 indexed token1 ,
7067 IERC20 indexed token2 ,
7168 Oracle oracle ,
72- uint256 oracleTTL ,
73- uint8 accrualRounds
69+ uint256 oracleTTL
7470 );
7571 event PairRemoved (bytes32 indexed id );
7672 event FeeUpdated (uint256 newFeeBasisPoints );
@@ -79,8 +75,6 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
7975 error OracleValueTooOld (Oracle oracle );
8076 error UnknownPair (IERC20 input , IERC20 output );
8177 error InvalidFee (uint256 feeBasisPoints );
82- error InvalidAccrualRounds (uint8 accrualRounds );
83- error InvalidOracleData ();
8478
8579 /// @custom:oz-upgrades-unsafe-allow constructor
8680 constructor (
@@ -105,23 +99,13 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
10599 Oracle oracle ,
106100 uint256 oracleTTL ,
107101 uint256 numerator ,
108- uint256 denominator ,
109- uint8 accrualRounds
102+ uint256 denominator
110103 )
111104 {
112105 id = hashPair (input, output);
113106 Pair storage pair = _pairs[id];
114107
115- return (
116- id,
117- pair.token1,
118- pair.token2,
119- pair.oracle,
120- pair.oracleTTL,
121- pair.numerator,
122- pair.denominator,
123- pair.accrualRounds
124- );
108+ return (id, pair.token1, pair.token2, pair.oracle, pair.oracleTTL, pair.numerator, pair.denominator);
125109 }
126110
127111 function hashPair (IERC20 input , IERC20 output ) public view virtual returns (bytes32 ) {
@@ -188,20 +172,14 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
188172 IERC20 output ,
189173 uint256 inputAmount
190174 ) internal view virtual returns (uint256 /*outputAmount*/ ) {
191- (
192- ,
193- IERC20 token1 ,
194- ,
195- Oracle oracle ,
196- uint256 oracleTTL ,
197- uint256 numerator ,
198- uint256 denominator ,
199- uint8 accrualRounds
200- ) = viewPairDetails (input, output);
175+ (, IERC20 token1 , , Oracle oracle , uint256 oracleTTL , uint256 numerator , uint256 denominator ) = viewPairDetails (
176+ input,
177+ output
178+ );
201179
202180 require (address (oracle) != address (0 ), UnknownPair (input, output));
203181
204- (int256 minPrice , int256 maxPrice ) = _getPrices (oracle, oracleTTL, accrualRounds );
182+ (int256 minPrice , int256 maxPrice ) = _getPrices (oracle, oracleTTL);
205183 return
206184 inputAmount.mulDiv (
207185 Math.ternary (input == token1, numerator * minPrice.toUint256 (), denominator),
@@ -215,20 +193,14 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
215193 IERC20 output ,
216194 uint256 outputAmount
217195 ) internal view virtual returns (uint256 /*inputAmount*/ ) {
218- (
219- ,
220- IERC20 token1 ,
221- ,
222- Oracle oracle ,
223- uint256 oracleTTL ,
224- uint256 numerator ,
225- uint256 denominator ,
226- uint8 accrualRounds
227- ) = viewPairDetails (input, output);
196+ (, IERC20 token1 , , Oracle oracle , uint256 oracleTTL , uint256 numerator , uint256 denominator ) = viewPairDetails (
197+ input,
198+ output
199+ );
228200
229201 require (address (oracle) != address (0 ), UnknownPair (input, output));
230202
231- (int256 minPrice , int256 maxPrice ) = _getPrices (oracle, oracleTTL, accrualRounds );
203+ (int256 minPrice , int256 maxPrice ) = _getPrices (oracle, oracleTTL);
232204 return
233205 outputAmount.mulDiv (
234206 Math.ternary (input == token1, denominator, numerator * maxPrice.toUint256 ()),
@@ -303,72 +275,12 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
303275 emit SwapExact (input, output, inputAmount, outputAmount, from, to);
304276 }
305277
306- function _computeSlope (int256 numerator , int256 denominator ) private pure returns (int256 ) {
307- bool negative = (numerator < 0 ) != (denominator < 0 );
308- uint256 absSlope = Math.mulDiv (SignedMath.abs (numerator), _PRECISION, SignedMath.abs (denominator));
309- return negative ? - absSlope.toInt256 () : absSlope.toInt256 ();
310- }
311-
312- function _computeLinearRegression (
313- Oracle oracle ,
314- uint8 n
315- ) internal view returns (int256 slope , int256 intercept , uint48 baseTimestamp ) {
316- require (n >= 2 && n <= _MAX_REGRESSION_POINTS, InvalidAccrualRounds (n));
317-
318- uint80 latestRoundId;
319- (latestRoundId, , , , ) = oracle.latestRoundData ();
320- require (latestRoundId > 0 && latestRoundId + 1 >= n, InvalidOracleData ());
321-
322- uint80 startRoundId = latestRoundId + 1 - n;
323- uint256 baseTs;
324- (, , baseTs, , ) = oracle.getRoundData (startRoundId);
325- baseTimestamp = uint48 (baseTs);
326-
327- int256 sumT;
328- int256 sumP;
329- int256 sumTP;
330- int256 sumT2;
331-
332- for (uint8 i = 0 ; i < n; i++ ) {
333- (, int256 price , uint256 timestamp , , ) = oracle.getRoundData (startRoundId + i);
334- int256 t = (timestamp - baseTs).toInt256 ();
335- sumT += t;
336- sumP += price;
337- sumTP += t * price;
338- sumT2 += t * t;
339- }
340-
341- int256 nInt = int256 (uint256 (n));
342- int256 denominator = nInt * sumT2 - sumT * sumT;
343-
344- require (denominator > 0 , InvalidOracleData ());
345-
346- slope = _computeSlope (nInt * sumTP - sumT * sumP, denominator);
347- intercept = (sumP - (slope * sumT) / int256 (_PRECISION)) / nInt;
348- }
349-
350- function _getPrices (
351- Oracle oracle ,
352- uint256 oracleTTL ,
353- uint8 accrualRounds
354- ) internal view virtual returns (int256 min , int256 max ) {
355- (uint80 roundId , int256 latest , , uint256 updatedAt , ) = oracle.latestRoundData ();
278+ function _getPrices (Oracle oracle , uint256 oracleTTL ) internal view virtual returns (int256 min , int256 max ) {
279+ (uint80 roundId , int256 latest , , , ) = oracle.latestRoundData ();
280+ (, int256 previous , , uint256 updatedAt , ) = oracle.getRoundData (roundId - 1 );
356281 require (block .timestamp < updatedAt + oracleTTL, OracleValueTooOld (oracle));
357-
358- if (accrualRounds == 0 ) {
359- require (roundId >= 1 , InvalidOracleData ());
360- (, int256 previous , , , ) = oracle.getRoundData (roundId - 1 );
361- min = SignedMath.min (latest, previous);
362- max = SignedMath.max (latest, previous);
363- } else {
364- (int256 slope , int256 intercept , uint48 baseTimestamp ) = _computeLinearRegression (oracle, accrualRounds);
365-
366- // price = slope * (currentTime - baseTimestamp) / _PRECISION + intercept
367- uint256 absDeltaPrice = Math.mulDiv (SignedMath.abs (slope), block .timestamp - baseTimestamp, _PRECISION);
368- min = intercept + (slope < 0 ? - absDeltaPrice.toInt256 () : absDeltaPrice.toInt256 ());
369- require (min > 0 , InvalidOracleData ());
370- max = min;
371- }
282+ min = SignedMath.min (latest, previous);
283+ max = SignedMath.max (latest, previous);
372284 }
373285
374286 /****************************************************************************************************************
@@ -378,25 +290,19 @@ contract MultiATM is ERC2771Context, PermissionManaged, Multicall {
378290 IERC20Metadata token1 ,
379291 IERC20Metadata token2 ,
380292 Oracle oracle ,
381- uint256 oracleTTL ,
382- uint8 accrualRounds
293+ uint256 oracleTTL
383294 ) public virtual restricted {
384295 bytes32 id = hashPair (token1, token2);
385- require (
386- accrualRounds == 0 || (accrualRounds >= 2 && accrualRounds <= _MAX_REGRESSION_POINTS),
387- InvalidAccrualRounds (accrualRounds)
388- );
389296 _pairs[id] = Pair ({
390297 token1: token1,
391298 token2: token2,
392299 oracle: oracle,
393300 oracleTTL: oracleTTL,
394301 numerator: 10 ** token2.decimals (),
395- denominator: 10 ** (token1.decimals () + oracle.decimals ()),
396- accrualRounds: accrualRounds
302+ denominator: 10 ** (token1.decimals () + oracle.decimals ())
397303 });
398304
399- emit PairUpdated (id, token1, token2, oracle, oracleTTL, accrualRounds );
305+ emit PairUpdated (id, token1, token2, oracle, oracleTTL);
400306 }
401307
402308 function removePair (IERC20 token1 , IERC20 token2 ) public virtual restricted {
0 commit comments