@ubk-labs/ubk-oracle 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/constants/UBKOracleConstants.sol +6 -5
- package/contracts/core/UBKOracle.sol +58 -33
- package/contracts/errors/UBKOracleErrors.sol +1 -1
- package/contracts/imports/UBKImports.sol +14 -0
- package/interfaces/IUBKOracle.sol +90 -6
- package/package.json +4 -4
- package/artifacts/contracts/constants/UBKOracleConstants.sol/UBKOracleConstants.dbg.json +0 -4
- package/artifacts/contracts/constants/UBKOracleConstants.sol/UBKOracleConstants.json +0 -141
- package/artifacts/contracts/core/UBKOracle.sol/UBKOracle.dbg.json +0 -4
- package/artifacts/contracts/core/UBKOracle.sol/UBKOracle.json +0 -1028
- package/artifacts/contracts/mocks/MockAggregatorV3.sol/MockAggregatorV3.dbg.json +0 -4
- package/artifacts/contracts/mocks/MockAggregatorV3.sol/MockAggregatorV3.json +0 -177
- package/artifacts/contracts/mocks/MockERC20.sol/MockERC20.dbg.json +0 -4
- package/artifacts/contracts/mocks/MockERC20.sol/MockERC20.json +0 -381
- package/artifacts/contracts/mocks/MockERC4626.sol/Mock4626.dbg.json +0 -4
- package/artifacts/contracts/mocks/MockERC4626.sol/Mock4626.json +0 -500
- package/artifacts/contracts/mocks/MockIERC4626.sol/MockIERC4626.dbg.json +0 -4
- package/artifacts/contracts/mocks/MockIERC4626.sol/MockIERC4626.json +0 -99
- package/artifacts/interfaces/IUBKOracle.sol/IUBKOracle.dbg.json +0 -4
- package/artifacts/interfaces/IUBKOracle.sol/IUBKOracle.json +0 -312
- package/contracts/mocks/MockAggregatorV3.sol +0 -56
- package/contracts/mocks/MockERC20.sol +0 -28
- package/contracts/mocks/MockERC4626.sol +0 -74
- package/contracts/mocks/MockIERC4626.sol +0 -13
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.20;
|
|
3
3
|
|
|
4
|
-
import "@ubk-labs/ubk-commons/
|
|
5
|
-
|
|
4
|
+
import "@ubk-labs/ubk-commons/contracts/constants/UBKConstants.sol";
|
|
6
5
|
|
|
7
6
|
library UBKOracleConstants {
|
|
8
7
|
// -----------------------------------------------------------------------
|
|
@@ -27,12 +26,14 @@ library UBKOracleConstants {
|
|
|
27
26
|
// -----------------------------------------------------------------------
|
|
28
27
|
// Oracle Staleness Periods
|
|
29
28
|
// -----------------------------------------------------------------------
|
|
30
|
-
uint256 public constant ORACLE_DEFAULT_STALE_PERIOD = 1 hours;
|
|
31
29
|
uint256 public constant ORACLE_MIN_STALE_PERIOD = 1 hours;
|
|
32
|
-
uint256 public constant ORACLE_MAX_STALE_PERIOD =
|
|
30
|
+
uint256 public constant ORACLE_MAX_STALE_PERIOD = 48 hours;
|
|
31
|
+
|
|
32
|
+
uint256 public constant ORACLE_DEFAULT_STALE_FALLBACK_MULTIPLIER = 2; //2x stale
|
|
33
|
+
uint256 public constant ORACLE_MAX_STALE_FALLBACK_MULTIPLIER = 3; //3x stale
|
|
33
34
|
|
|
34
35
|
// -----------------------------------------------------------------------
|
|
35
36
|
// Oracle Recursion
|
|
36
37
|
// -----------------------------------------------------------------------
|
|
37
|
-
uint256 public constant
|
|
38
|
+
uint256 public constant ORACLE_MAX_RECURSION_DEPTH = 5;
|
|
38
39
|
}
|
|
@@ -14,7 +14,7 @@ import "../constants/UBKOracleConstants.sol";
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @title Oracle
|
|
17
|
-
* @notice This contract is an implementation of the
|
|
17
|
+
* @notice This contract is an implementation of the IUBKOracle interface.
|
|
18
18
|
*
|
|
19
19
|
* @dev
|
|
20
20
|
* The oracle computes normalized 1e18 prices for all supported assets,
|
|
@@ -63,11 +63,10 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
63
63
|
mapping(address => VaultRateBounds) public vaultRateBounds;
|
|
64
64
|
|
|
65
65
|
/// @notice Maximum staleness period for Chainlink feeds (seconds).
|
|
66
|
-
uint256 public stalePeriod
|
|
66
|
+
mapping(address => uint256) public stalePeriod;
|
|
67
67
|
|
|
68
68
|
/// @notice Staleness tolerance for fallback prices (seconds).
|
|
69
|
-
uint256 public fallbackStalePeriod
|
|
70
|
-
UBKOracleConstants.ORACLE_DEFAULT_STALE_PERIOD * 2;
|
|
69
|
+
mapping(address => uint256) public fallbackStalePeriod;
|
|
71
70
|
|
|
72
71
|
OracleMode public mode = OracleMode.NORMAL;
|
|
73
72
|
|
|
@@ -102,7 +101,7 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
102
101
|
|
|
103
102
|
/// @notice Prevents infinite recursion when resolving nested ERC4626 vaults.
|
|
104
103
|
modifier checkRecursion() {
|
|
105
|
-
if (_recursionDepth >= UBKOracleConstants.
|
|
104
|
+
if (_recursionDepth >= UBKOracleConstants.ORACLE_MAX_RECURSION_DEPTH)
|
|
106
105
|
revert RecursiveResolution(address(0));
|
|
107
106
|
_recursionDepth++;
|
|
108
107
|
_;
|
|
@@ -125,16 +124,20 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
125
124
|
|
|
126
125
|
/**
|
|
127
126
|
* @notice Sets the maximum time (in seconds) a Chainlink feed value is valid.
|
|
128
|
-
* @param period The new staleness threshold.
|
|
127
|
+
* @param period The new fallback staleness threshold. Must be 1.5x of stalePeriod of the same token.
|
|
129
128
|
* @dev Must lie within [UBKOracleConstants.ORACLE_MIN_STALE_PERIOD, UBKOracleConstants.ORACLE_MAX_STALE_PERIOD].
|
|
130
129
|
*/
|
|
131
|
-
function setStalePeriod(uint256 period) external onlyOwner {
|
|
130
|
+
function setStalePeriod(address token, uint256 period) external onlyOwner {
|
|
132
131
|
if (
|
|
133
132
|
period < UBKOracleConstants.ORACLE_MIN_STALE_PERIOD ||
|
|
134
133
|
period > UBKOracleConstants.ORACLE_MAX_STALE_PERIOD
|
|
135
134
|
) revert InvalidStalePeriod(period);
|
|
136
|
-
stalePeriod = period;
|
|
137
|
-
|
|
135
|
+
stalePeriod[token] = period;
|
|
136
|
+
fallbackStalePeriod[token] =
|
|
137
|
+
UBKOracleConstants.ORACLE_DEFAULT_STALE_FALLBACK_MULTIPLIER *
|
|
138
|
+
period; //Minimum fallback period should be 2x stalePeriod[token].
|
|
139
|
+
emit StalePeriodUpdated(token, stalePeriod[token]);
|
|
140
|
+
emit FallbackStalePeriodUpdated(token, fallbackStalePeriod[token]);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
/**
|
|
@@ -142,10 +145,17 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
142
145
|
* @param period Maximum allowed seconds for fallback validity.
|
|
143
146
|
* @dev Must be ≥ stalePeriod to remain meaningful.
|
|
144
147
|
*/
|
|
145
|
-
function setFallbackStalePeriod(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
function setFallbackStalePeriod(
|
|
149
|
+
address token,
|
|
150
|
+
uint256 period
|
|
151
|
+
) external onlyOwner {
|
|
152
|
+
uint256 stalePeriodToken = stalePeriod[token]; // Default stale period of token.
|
|
153
|
+
uint256 maxFallbackPeriod = stalePeriodToken *
|
|
154
|
+
UBKOracleConstants.ORACLE_MAX_STALE_FALLBACK_MULTIPLIER; // The absolute maximum fallback stale period allowed. (3x)
|
|
155
|
+
if (period < stalePeriodToken || period > maxFallbackPeriod)
|
|
156
|
+
revert InvalidStalePeriod(period);
|
|
157
|
+
fallbackStalePeriod[token] = period;
|
|
158
|
+
emit FallbackStalePeriodUpdated(token, period);
|
|
149
159
|
}
|
|
150
160
|
|
|
151
161
|
/**
|
|
@@ -188,12 +198,16 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
188
198
|
) revert InvalidManualPrice(token, price);
|
|
189
199
|
|
|
190
200
|
LastValidPrice memory lv = lastValidPrice[token];
|
|
191
|
-
if (
|
|
201
|
+
if (
|
|
202
|
+
lv.price > 0 && block.timestamp - lv.timestamp <= stalePeriod[token]
|
|
203
|
+
) {
|
|
192
204
|
uint256 lowerBound = (lv.price *
|
|
193
|
-
(UBKOracleConstants.WAD -
|
|
205
|
+
(UBKOracleConstants.WAD -
|
|
206
|
+
UBKOracleConstants.ORACLE_MANUAL_PRICE_MAX_DELTA_WAD)) /
|
|
194
207
|
UBKOracleConstants.WAD;
|
|
195
208
|
uint256 upperBound = (lv.price *
|
|
196
|
-
(UBKOracleConstants.WAD +
|
|
209
|
+
(UBKOracleConstants.WAD +
|
|
210
|
+
UBKOracleConstants.ORACLE_MANUAL_PRICE_MAX_DELTA_WAD)) /
|
|
197
211
|
UBKOracleConstants.WAD;
|
|
198
212
|
if (price < lowerBound || price > upperBound)
|
|
199
213
|
revert InvalidManualPrice(token, price);
|
|
@@ -245,7 +259,6 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
245
259
|
} catch {
|
|
246
260
|
revert InvalidFeedContract(feed);
|
|
247
261
|
}
|
|
248
|
-
|
|
249
262
|
chainlinkFeeds[token] = feed;
|
|
250
263
|
isManual[token] = false;
|
|
251
264
|
_addSupportedToken(token);
|
|
@@ -310,15 +323,12 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
310
323
|
return block.timestamp - lv.timestamp;
|
|
311
324
|
}
|
|
312
325
|
|
|
313
|
-
/**
|
|
326
|
+
/** Public wrapper for _isPriceFresh
|
|
314
327
|
* @notice Checks if cached price is within freshness threshold.
|
|
315
|
-
* @param token Token address.
|
|
316
328
|
* @return isFresh True if price updated ≤ stalePeriod ago.
|
|
317
329
|
*/
|
|
318
330
|
function isPriceFresh(address token) external view returns (bool isFresh) {
|
|
319
|
-
|
|
320
|
-
return (lv.timestamp != 0 &&
|
|
321
|
-
block.timestamp - lv.timestamp <= stalePeriod);
|
|
331
|
+
return _isPriceFresh(token);
|
|
322
332
|
}
|
|
323
333
|
|
|
324
334
|
/**
|
|
@@ -352,7 +362,8 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
352
362
|
) external view returns (uint256 usdValue) {
|
|
353
363
|
if (amount == 0) return 0;
|
|
354
364
|
uint8 decimals = IERC20Metadata(token).decimals();
|
|
355
|
-
uint256 normalized = (amount * UBKOracleConstants.WAD) /
|
|
365
|
+
uint256 normalized = (amount * UBKOracleConstants.WAD) /
|
|
366
|
+
(10 ** decimals);
|
|
356
367
|
uint256 price = _getPrice(token); // 18 decimals
|
|
357
368
|
usdValue = (normalized * price) / UBKOracleConstants.WAD;
|
|
358
369
|
}
|
|
@@ -385,13 +396,26 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
385
396
|
* @return price Cached price in 1e18 precision.
|
|
386
397
|
*/
|
|
387
398
|
function _getPrice(address token) internal view returns (uint256) {
|
|
388
|
-
if (token == address(0))
|
|
399
|
+
if (token == address(0))
|
|
400
|
+
revert ZeroAddress("UBKOracle::getPrice", "token");
|
|
389
401
|
LastValidPrice memory lv = lastValidPrice[token];
|
|
390
402
|
if (lv.price == 0) revert NoFallbackPrice(token);
|
|
391
|
-
if (!
|
|
403
|
+
if (!_isPriceFresh(token))
|
|
392
404
|
revert StalePrice(token, lv.timestamp, block.timestamp);
|
|
393
405
|
return lv.price;
|
|
394
406
|
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* @notice Checks if cached price is within freshness threshold.
|
|
410
|
+
* @param token Token address.
|
|
411
|
+
* @return isFresh True if price updated ≤ stalePeriod ago.
|
|
412
|
+
*/
|
|
413
|
+
function _isPriceFresh(address token) internal view returns (bool isFresh) {
|
|
414
|
+
LastValidPrice memory lv = lastValidPrice[token];
|
|
415
|
+
return (lv.timestamp != 0 &&
|
|
416
|
+
block.timestamp - lv.timestamp <= stalePeriod[token]);
|
|
417
|
+
}
|
|
418
|
+
|
|
395
419
|
/**
|
|
396
420
|
* @notice Resolves the fair price of an ERC4626 vault share.
|
|
397
421
|
* @param vault ERC4626 vault token address.
|
|
@@ -428,13 +452,13 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
428
452
|
if (rate > maxRate || rate < minRate)
|
|
429
453
|
revert SuspiciousVaultRate(vault, rate);
|
|
430
454
|
|
|
431
|
-
uint256 underlyingPrice =
|
|
455
|
+
uint256 underlyingPrice = _resolvePrice(underlying);
|
|
432
456
|
return (underlyingPrice * rate) / UBKOracleConstants.WAD;
|
|
433
457
|
}
|
|
434
458
|
|
|
435
459
|
/**
|
|
436
460
|
* @notice Fetches and validates the latest Chainlink feed price.
|
|
437
|
-
* @param
|
|
461
|
+
* @param token The address of the token whose feed needs to be read.
|
|
438
462
|
* @return price The normalized price (1e18 precision).
|
|
439
463
|
* @return valid Boolean indicating whether the feed result is valid.
|
|
440
464
|
*
|
|
@@ -448,8 +472,9 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
448
472
|
* If any condition fails or the feed call reverts, returns `(0, false)`.
|
|
449
473
|
*/
|
|
450
474
|
function _getChainlinkPrice(
|
|
451
|
-
address
|
|
475
|
+
address token
|
|
452
476
|
) internal view returns (uint256 price, bool valid) {
|
|
477
|
+
address feed = chainlinkFeeds[token];
|
|
453
478
|
try AggregatorV3Interface(feed).latestRoundData() returns (
|
|
454
479
|
uint80,
|
|
455
480
|
int256 answer,
|
|
@@ -460,7 +485,7 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
460
485
|
if (
|
|
461
486
|
answer <= 0 ||
|
|
462
487
|
updatedAt == 0 ||
|
|
463
|
-
block.timestamp - updatedAt > stalePeriod
|
|
488
|
+
block.timestamp - updatedAt > stalePeriod[token]
|
|
464
489
|
) return (0, false);
|
|
465
490
|
|
|
466
491
|
uint8 feedDecimals = AggregatorV3Interface(feed).decimals();
|
|
@@ -494,7 +519,7 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
494
519
|
* @return price Resolved fair price in 1e18 precision.
|
|
495
520
|
* @dev May trigger state updates if underlying vaults are resolved.
|
|
496
521
|
*/
|
|
497
|
-
function
|
|
522
|
+
function _resolvePrice(address token) internal returns (uint256 price) {
|
|
498
523
|
if (isManual[token]) return manualPrices[token];
|
|
499
524
|
|
|
500
525
|
address underlying = erc4626Underlying[token];
|
|
@@ -503,12 +528,12 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
503
528
|
address feed = chainlinkFeeds[token];
|
|
504
529
|
if (feed == address(0)) revert NoPriceFeed(token);
|
|
505
530
|
|
|
506
|
-
(uint256 clPrice, bool valid) = _getChainlinkPrice(
|
|
531
|
+
(uint256 clPrice, bool valid) = _getChainlinkPrice(token);
|
|
507
532
|
if (valid) return clPrice;
|
|
508
533
|
|
|
509
534
|
LastValidPrice memory lv = lastValidPrice[token];
|
|
510
535
|
if (lv.price == 0) revert NoFallbackPrice(token);
|
|
511
|
-
if (block.timestamp - lv.timestamp > fallbackStalePeriod)
|
|
536
|
+
if (block.timestamp - lv.timestamp > fallbackStalePeriod[token])
|
|
512
537
|
revert StaleFallback(token);
|
|
513
538
|
|
|
514
539
|
emit OracleFallbackUsed(
|
|
@@ -529,7 +554,7 @@ contract UBKOracle is IUBKOracle, Ownable {
|
|
|
529
554
|
function _fetchAndUpdatePrice(
|
|
530
555
|
address token
|
|
531
556
|
) internal returns (uint256 price) {
|
|
532
|
-
price =
|
|
557
|
+
price = _resolvePrice(token);
|
|
533
558
|
if (
|
|
534
559
|
price < UBKOracleConstants.ORACLE_MIN_ABSOLUTE_PRICE_WAD ||
|
|
535
560
|
price > UBKOracleConstants.ORACLE_MAX_ABSOLUTE_PRICE_WAD
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.20;
|
|
3
3
|
|
|
4
|
-
import "@ubk-labs/ubk-commons/
|
|
4
|
+
import "@ubk-labs/ubk-commons/contracts/errors/UBKErrors.sol";
|
|
5
5
|
|
|
6
6
|
// ───────────── Errors ─────────────
|
|
7
7
|
error InvalidManualPrice(address token, uint256 price);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
// Importing these ensures Hardhat generates artifacts for them.
|
|
5
|
+
import "@ubk-labs/ubk-commons/contracts/mocks/MockERC20.sol";
|
|
6
|
+
import "@ubk-labs/ubk-commons/contracts/mocks/MockERC4626.sol";
|
|
7
|
+
import "@ubk-labs/ubk-commons/contracts/mocks/MockAggregatorV3.sol";
|
|
8
|
+
|
|
9
|
+
abstract contract UBKImports {
|
|
10
|
+
/**
|
|
11
|
+
This shim file will import all external contracts to enable
|
|
12
|
+
automatic artifact generation by HardHat.
|
|
13
|
+
*/
|
|
14
|
+
}
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
pragma solidity ^0.8.20;
|
|
3
3
|
|
|
4
4
|
interface IUBKOracle {
|
|
5
|
+
// -----------------------------------------------------------------------
|
|
6
|
+
// ENUMS & STRUCTS
|
|
7
|
+
// -----------------------------------------------------------------------
|
|
8
|
+
|
|
5
9
|
/// @notice Operational state of the oracle.
|
|
6
10
|
enum OracleMode {
|
|
7
11
|
NORMAL,
|
|
@@ -14,31 +18,40 @@ interface IUBKOracle {
|
|
|
14
18
|
uint256 timestamp;
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
/// @notice
|
|
21
|
+
/// @notice Vault-specific allowable min/max exchange rates.
|
|
18
22
|
struct VaultRateBounds {
|
|
19
23
|
uint256 minRate;
|
|
20
24
|
uint256 maxRate;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
// -----------------------------------------------------------------------
|
|
28
|
+
// EVENTS (for Subgraph indexing)
|
|
29
|
+
// -----------------------------------------------------------------------
|
|
30
|
+
|
|
24
31
|
event ChainlinkFeedSet(address indexed token, address indexed feed);
|
|
25
32
|
event ERC4626Registered(address indexed vault, address indexed underlying);
|
|
26
33
|
event TokenSupportAdded(address indexed token);
|
|
34
|
+
|
|
27
35
|
event ManualPriceSet(address indexed token, uint256 price);
|
|
28
36
|
event ManualModeEnabled(address indexed token, bool enabled);
|
|
29
|
-
|
|
37
|
+
|
|
38
|
+
event StalePeriodUpdated(address indexed token, uint256 newPeriod);
|
|
39
|
+
event FallbackStalePeriodUpdated(address indexed token, uint256 newPeriod);
|
|
40
|
+
|
|
30
41
|
event OracleModeChanged(OracleMode oldMode, OracleMode newMode);
|
|
31
|
-
|
|
42
|
+
|
|
32
43
|
event VaultRateBoundsSet(
|
|
33
44
|
address indexed vault,
|
|
34
45
|
uint256 minRate,
|
|
35
46
|
uint256 maxRate
|
|
36
47
|
);
|
|
48
|
+
|
|
37
49
|
event LastValidPriceUpdated(
|
|
38
50
|
address indexed token,
|
|
39
51
|
uint256 price,
|
|
40
52
|
uint256 timestamp
|
|
41
53
|
);
|
|
54
|
+
|
|
42
55
|
event OracleFallbackUsed(
|
|
43
56
|
address indexed token,
|
|
44
57
|
uint256 lastValid,
|
|
@@ -46,17 +59,88 @@ interface IUBKOracle {
|
|
|
46
59
|
string reason
|
|
47
60
|
);
|
|
48
61
|
|
|
49
|
-
//
|
|
62
|
+
// -----------------------------------------------------------------------
|
|
63
|
+
// VIEW PRICING API (Consumer-facing)
|
|
64
|
+
// -----------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @notice Returns the cached fair price for a token (1e18 precision).
|
|
68
|
+
* @dev Reverts if the price is stale or no valid price exists.
|
|
69
|
+
*/
|
|
50
70
|
function getPrice(address token) external view returns (uint256);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @notice Converts a token amount (native decimals) into USD value (1e18).
|
|
74
|
+
*/
|
|
51
75
|
function toUSD(
|
|
52
76
|
address token,
|
|
53
77
|
uint256 amount
|
|
54
78
|
) external view returns (uint256 usdValue);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @notice Converts a USD amount (1e18) into token units (native decimals).
|
|
82
|
+
*/
|
|
55
83
|
function fromUSD(
|
|
56
84
|
address token,
|
|
57
85
|
uint256 usdAmount
|
|
58
86
|
) external view returns (uint256 tokenAmount);
|
|
59
87
|
|
|
60
|
-
//
|
|
88
|
+
// -----------------------------------------------------------------------
|
|
89
|
+
// KEEPER / MUTATOR FUNCTIONS
|
|
90
|
+
// -----------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @notice Fetches and resolves the token price, then persists it as lastValidPrice.
|
|
94
|
+
* @dev Keeper entrypoint. May revert if price resolution fails.
|
|
95
|
+
*/
|
|
61
96
|
function fetchAndUpdatePrice(address token) external returns (uint256);
|
|
97
|
+
|
|
98
|
+
// -----------------------------------------------------------------------
|
|
99
|
+
// ADMIN / GOVERNANCE CONFIGURATION
|
|
100
|
+
// -----------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @notice Sets the operating mode of the oracle (NORMAL or PAUSED).
|
|
104
|
+
* @dev PAUSED mode disables fetchAndUpdatePrice().
|
|
105
|
+
*/
|
|
106
|
+
function setOracleMode(OracleMode newMode) external;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @notice Sets the maximum allowed staleness for Chainlink feed data.
|
|
110
|
+
*/
|
|
111
|
+
function setStalePeriod(address token, uint256 period) external;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @notice Sets the fallback staleness threshold for relying on lastValidPrice.
|
|
115
|
+
*/
|
|
116
|
+
function setFallbackStalePeriod(address token, uint256 period) external;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @notice Defines allowable min/max ERC4626 exchange rate bounds for a vault.
|
|
120
|
+
*/
|
|
121
|
+
function setVaultRateBounds(
|
|
122
|
+
address vault,
|
|
123
|
+
uint256 minRate,
|
|
124
|
+
uint256 maxRate
|
|
125
|
+
) external;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @notice Manually sets a token's price (1e18), constrained by ±10% of lastValidPrice.
|
|
129
|
+
*/
|
|
130
|
+
function setManualPrice(address token, uint256 price) external;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @notice Disables manual pricing mode for a token.
|
|
134
|
+
*/
|
|
135
|
+
function disableManualPrice(address token) external;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @notice Registers or updates a Chainlink feed for a token.
|
|
139
|
+
*/
|
|
140
|
+
function setChainlinkFeed(address token, address feed) external;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @notice Registers an ERC4626 vault and its underlying token for valuation.
|
|
144
|
+
*/
|
|
145
|
+
function setERC4626Vault(address vault, address underlying) external;
|
|
62
146
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubk-labs/ubk-oracle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Oracle supporting ERC-20 and ERC-4626 assets for use in decentralized financial applications.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npx hardhat compile",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"files": [
|
|
21
21
|
"contracts",
|
|
22
|
-
"artifacts",
|
|
23
22
|
"interfaces",
|
|
24
23
|
"README.md",
|
|
25
|
-
"LICENSE"
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"package.json"
|
|
26
26
|
],
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@graphprotocol/hardhat-graph": "^0.1.0-alpha.2",
|
|
@@ -37,6 +37,6 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@chainlink/contracts": "^0.6.1",
|
|
40
|
-
"@ubk-labs/ubk-commons": "^0.1.
|
|
40
|
+
"@ubk-labs/ubk-commons": "^0.1.5"
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_format": "hh-sol-artifact-1",
|
|
3
|
-
"contractName": "UBKOracleConstants",
|
|
4
|
-
"sourceName": "contracts/constants/UBKOracleConstants.sol",
|
|
5
|
-
"abi": [
|
|
6
|
-
{
|
|
7
|
-
"inputs": [],
|
|
8
|
-
"name": "MAX_RECURSION_DEPTH",
|
|
9
|
-
"outputs": [
|
|
10
|
-
{
|
|
11
|
-
"internalType": "uint256",
|
|
12
|
-
"name": "",
|
|
13
|
-
"type": "uint256"
|
|
14
|
-
}
|
|
15
|
-
],
|
|
16
|
-
"stateMutability": "view",
|
|
17
|
-
"type": "function"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"inputs": [],
|
|
21
|
-
"name": "ORACLE_DEFAULT_STALE_PERIOD",
|
|
22
|
-
"outputs": [
|
|
23
|
-
{
|
|
24
|
-
"internalType": "uint256",
|
|
25
|
-
"name": "",
|
|
26
|
-
"type": "uint256"
|
|
27
|
-
}
|
|
28
|
-
],
|
|
29
|
-
"stateMutability": "view",
|
|
30
|
-
"type": "function"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"inputs": [],
|
|
34
|
-
"name": "ORACLE_MANUAL_PRICE_MAX_DELTA_WAD",
|
|
35
|
-
"outputs": [
|
|
36
|
-
{
|
|
37
|
-
"internalType": "uint256",
|
|
38
|
-
"name": "",
|
|
39
|
-
"type": "uint256"
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
"stateMutability": "view",
|
|
43
|
-
"type": "function"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"inputs": [],
|
|
47
|
-
"name": "ORACLE_MAX_ABSOLUTE_PRICE_WAD",
|
|
48
|
-
"outputs": [
|
|
49
|
-
{
|
|
50
|
-
"internalType": "uint256",
|
|
51
|
-
"name": "",
|
|
52
|
-
"type": "uint256"
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
|
-
"stateMutability": "view",
|
|
56
|
-
"type": "function"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"inputs": [],
|
|
60
|
-
"name": "ORACLE_MAX_STALE_PERIOD",
|
|
61
|
-
"outputs": [
|
|
62
|
-
{
|
|
63
|
-
"internalType": "uint256",
|
|
64
|
-
"name": "",
|
|
65
|
-
"type": "uint256"
|
|
66
|
-
}
|
|
67
|
-
],
|
|
68
|
-
"stateMutability": "view",
|
|
69
|
-
"type": "function"
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"inputs": [],
|
|
73
|
-
"name": "ORACLE_MAX_VAULT_RATE_WAD",
|
|
74
|
-
"outputs": [
|
|
75
|
-
{
|
|
76
|
-
"internalType": "uint256",
|
|
77
|
-
"name": "",
|
|
78
|
-
"type": "uint256"
|
|
79
|
-
}
|
|
80
|
-
],
|
|
81
|
-
"stateMutability": "view",
|
|
82
|
-
"type": "function"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"inputs": [],
|
|
86
|
-
"name": "ORACLE_MIN_ABSOLUTE_PRICE_WAD",
|
|
87
|
-
"outputs": [
|
|
88
|
-
{
|
|
89
|
-
"internalType": "uint256",
|
|
90
|
-
"name": "",
|
|
91
|
-
"type": "uint256"
|
|
92
|
-
}
|
|
93
|
-
],
|
|
94
|
-
"stateMutability": "view",
|
|
95
|
-
"type": "function"
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
"inputs": [],
|
|
99
|
-
"name": "ORACLE_MIN_STALE_PERIOD",
|
|
100
|
-
"outputs": [
|
|
101
|
-
{
|
|
102
|
-
"internalType": "uint256",
|
|
103
|
-
"name": "",
|
|
104
|
-
"type": "uint256"
|
|
105
|
-
}
|
|
106
|
-
],
|
|
107
|
-
"stateMutability": "view",
|
|
108
|
-
"type": "function"
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
"inputs": [],
|
|
112
|
-
"name": "ORACLE_MIN_VAULT_RATE_WAD",
|
|
113
|
-
"outputs": [
|
|
114
|
-
{
|
|
115
|
-
"internalType": "uint256",
|
|
116
|
-
"name": "",
|
|
117
|
-
"type": "uint256"
|
|
118
|
-
}
|
|
119
|
-
],
|
|
120
|
-
"stateMutability": "view",
|
|
121
|
-
"type": "function"
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"inputs": [],
|
|
125
|
-
"name": "WAD",
|
|
126
|
-
"outputs": [
|
|
127
|
-
{
|
|
128
|
-
"internalType": "uint256",
|
|
129
|
-
"name": "",
|
|
130
|
-
"type": "uint256"
|
|
131
|
-
}
|
|
132
|
-
],
|
|
133
|
-
"stateMutability": "view",
|
|
134
|
-
"type": "function"
|
|
135
|
-
}
|
|
136
|
-
],
|
|
137
|
-
"bytecode": "0x61016861003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100a85760003560e01c8063730513511161007057806373051351146101015780639a1b2c43146100ad578063afb9888514610112578063d160ed4d14610121578063f3f7de781461012957600080fd5b80634e9331ef146100ad5780635c94d0f9146100c85780636a146024146100d75780636bae86bb146100e65780636c0d5b36146100f2575b600080fd5b6100b6610e1081565b60405190815260200160405180910390f35b6100b667016345785d8a000081565b6100b6670de0b6b3a764000081565b6100b66402540be40081565b6100b66729a2241af62c000081565b6100b669d3c21bcecceda100000081565b6100b66702c68af0bb14000081565b6100b6600581565b6100b6612a308156fea2646970667358221220a0861901c16baa83a56628bb8b95ec1e373e3060f03d44a4084cb5c2271c79ef64736f6c63430008150033",
|
|
138
|
-
"deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100a85760003560e01c8063730513511161007057806373051351146101015780639a1b2c43146100ad578063afb9888514610112578063d160ed4d14610121578063f3f7de781461012957600080fd5b80634e9331ef146100ad5780635c94d0f9146100c85780636a146024146100d75780636bae86bb146100e65780636c0d5b36146100f2575b600080fd5b6100b6610e1081565b60405190815260200160405180910390f35b6100b667016345785d8a000081565b6100b6670de0b6b3a764000081565b6100b66402540be40081565b6100b66729a2241af62c000081565b6100b669d3c21bcecceda100000081565b6100b66702c68af0bb14000081565b6100b6600581565b6100b6612a308156fea2646970667358221220a0861901c16baa83a56628bb8b95ec1e373e3060f03d44a4084cb5c2271c79ef64736f6c63430008150033",
|
|
139
|
-
"linkReferences": {},
|
|
140
|
-
"deployedLinkReferences": {}
|
|
141
|
-
}
|