Skip to content

Commit 91bb5d1

Browse files
committed
Revert "feat(multi-atm): linear accrual"
This reverts commit 0e27d4a.
1 parent 0e27d4a commit 91bb5d1

2 files changed

Lines changed: 27 additions & 883 deletions

File tree

contracts/token/MultiATM.sol

Lines changed: 21 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)