Skip to content

Commit d3bcaad

Browse files
committed
feat: add price updates to price helper
1 parent 6e5f6fc commit d3bcaad

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

contracts/PriceHelper.sol

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,29 @@
33
// (c) Gearbox Holdings, 2024
44
pragma solidity ^0.8.10;
55

6-
import {IPriceHelper, TokenPriceInfo} from "./interfaces/IPriceHelper.sol";
6+
import {IPriceHelper, PriceOnDemand, TokenPriceInfo} from "./interfaces/IPriceHelper.sol";
77
import {ICreditAccountV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditAccountV3.sol";
88
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
99
import {IPriceOracleV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPriceOracleV3.sol";
10-
import {IPriceFeed} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeed.sol";
10+
import {IPriceFeed, IUpdatablePriceFeed} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeed.sol";
1111
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
1212
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
13+
import "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
1314

1415
contract PriceHelper is IPriceHelper {
15-
function previewTokens(address creditAccount) external view returns (TokenPriceInfo[] memory results) {
16+
function previewTokens(address creditAccount, PriceOnDemand[] memory priceUpdates)
17+
external
18+
returns (TokenPriceInfo[] memory results)
19+
{
1620
ICreditManagerV3 creditManager = ICreditManagerV3(ICreditAccountV3(creditAccount).creditManager());
21+
address oracle = creditManager.priceOracle();
22+
23+
_updatePrices(oracle, priceUpdates);
24+
1725
address underlying = creditManager.underlying();
1826
uint256 underlyingScale = 10 ** IERC20Metadata(underlying).decimals();
19-
address oracle = creditManager.priceOracle();
2027
uint256 enabledTokensMask = creditManager.enabledTokensMaskOf(creditAccount);
21-
uint256 priceTo = _getUnupdatedPrice(oracle, underlying);
28+
uint256 priceTo = _unsafeGetPrice(oracle, underlying);
2229

2330
uint256 len = creditManager.collateralTokensCount();
2431
uint256 cnt = 0;
@@ -34,7 +41,7 @@ contract PriceHelper is IPriceHelper {
3441
if (info.token == underlying) {
3542
info.balanceInUnderlying = info.balance;
3643
} else {
37-
uint256 priceFrom = _getUnupdatedPrice(oracle, info.token);
44+
uint256 priceFrom = _unsafeGetPrice(oracle, info.token);
3845
info.balanceInUnderlying = info.balance * priceFrom * underlyingScale / (priceTo * tokenScale);
3946
}
4047
tmp[cnt] = info;
@@ -51,8 +58,22 @@ contract PriceHelper is IPriceHelper {
5158
}
5259
}
5360

54-
/// @dev Returns price feed answer while trying to ignore that can happen due to unupdated PULL oracles
55-
function _getUnupdatedPrice(address oracle, address token) internal view returns (uint256 price) {
61+
function _updatePrices(address priceOracle, PriceOnDemand[] memory priceUpdates) internal {
62+
IPriceOracleV3 oracle = IPriceOracleV3(priceOracle);
63+
uint256 len = priceUpdates.length;
64+
unchecked {
65+
for (uint256 i; i < len; ++i) {
66+
address priceFeed = oracle.priceFeeds(priceUpdates[i].token);
67+
if (priceFeed == address(0)) {
68+
revert PriceFeedDoesNotExistException();
69+
}
70+
IUpdatablePriceFeed(priceFeed).updatePrice(priceUpdates[i].callData);
71+
}
72+
}
73+
}
74+
75+
/// @dev Returns price feed answer while trying to ignore revert that can happen due to unupdated PULL oracles
76+
function _unsafeGetPrice(address oracle, address token) internal view returns (uint256 price) {
5677
IPriceOracleV3 priceOracle = IPriceOracleV3(oracle);
5778

5879
// check main price feed

contracts/interfaces/IPriceHelper.sol

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ struct TokenPriceInfo {
1010
uint256 liquidationThreshold;
1111
}
1212

13+
struct PriceOnDemand {
14+
address token;
15+
bytes callData;
16+
}
17+
1318
interface IPriceHelper {
14-
function previewTokens(address creditAccount) external view returns (TokenPriceInfo[] memory results);
19+
function previewTokens(address creditAccount, PriceOnDemand[] memory priceUpdates)
20+
external
21+
returns (TokenPriceInfo[] memory results);
1522
}

0 commit comments

Comments
 (0)