@@ -4,11 +4,12 @@ pragma solidity 0.8.23;
44import {ERC4626 } from "@solady/tokens/ERC4626.sol " ;
55import {IPriceOracle} from "src/interfaces/IPriceOracle.sol " ;
66import {Errors} from "src/lib/Errors.sol " ;
7+ import {Governable} from "src/lib/Governable.sol " ;
78
89/// @title EulerRouter
910/// @author Euler Labs (https://www.eulerlabs.com/)
1011/// @notice Default Oracle resolver for Euler lending products.
11- contract EulerRouter is IPriceOracle {
12+ contract EulerRouter is Governable , IPriceOracle {
1213 /// @notice The PriceOracle to call if this router is not configured for base/quote.
1314 /// @dev If `address(0)` then there is no fallback.
1415 address public fallbackOracle;
@@ -18,16 +19,14 @@ contract EulerRouter is IPriceOracle {
1819 /// @dev During resolution the vault is substituted with its asset.
1920 /// The `inAmount` is augmented by the vault's `convert*` function.
2021 mapping (address vault = > address asset ) public resolvedVaults;
21- /// @notice The active governor address. If `address(0)` then the role is renounced.
22- address public governor;
2322
24- /// @notice Configure an PriceOracle to resolve base/quote.
23+ /// @notice Configure a PriceOracle to resolve base/quote.
2524 /// @param base The address of the base token.
2625 /// @param quote The address of the quote token.
2726 /// @param oracle The address of the PriceOracle that resolves base/quote.
2827 /// @dev If `oracle` is `address(0)` then the base/quote configuration was removed.
2928 event ConfigSet (address indexed base , address indexed quote , address indexed oracle );
30- /// @notice Set an PriceOracle as a fallback resolver.
29+ /// @notice Set a PriceOracle as a fallback resolver.
3130 /// @param fallbackOracle The address of the PriceOracle that is called when base/quote is not configured.
3231 /// @dev If `fallbackOracle` is `address(0)` then there is no fallback resolver.
3332 event FallbackOracleSet (address indexed fallbackOracle );
@@ -36,18 +35,12 @@ contract EulerRouter is IPriceOracle {
3635 /// @param asset The address of the vault's asset.
3736 /// @dev If `asset` is `address(0)` then the configuration was removed.
3837 event ResolvedVaultSet (address indexed vault , address indexed asset );
39- /// @notice Set the governor of the contract.
40- /// @param oldGovernor The address of the previous governor.
41- /// @param newGovernor The address of the newly appointed governor.
42- event GovernorSet (address indexed oldGovernor , address indexed newGovernor );
4338
4439 /// @notice Deploy EulerRouter.
4540 /// @param _governor The address of the governor.
46- constructor (address _governor ) {
47- _setGovernor (_governor);
48- }
41+ constructor (address _governor ) Governable (_governor) {}
4942
50- /// @notice Configure an PriceOracle to resolve base/quote.
43+ /// @notice Configure a PriceOracle to resolve base/quote.
5144 /// @param base The address of the base token.
5245 /// @param quote The address of the quote token.
5346 /// @param oracle The address of the PriceOracle that resolves base/quote.
@@ -57,55 +50,26 @@ contract EulerRouter is IPriceOracle {
5750 emit ConfigSet (base, quote, oracle);
5851 }
5952
60- /// @notice Clear the configuration for base/quote.
61- /// @param base The address of the base token.
62- /// @param quote The address of the quote token.
63- /// @dev Callable only by the governor.
64- function govClearConfig (address base , address quote ) external onlyGovernor {
65- delete oracles[base][quote];
66- emit ConfigSet (base, quote, address (0 ));
67- }
68-
6953 /// @notice Configure an ERC4626 vault to use internal pricing via `convert*` methods.
7054 /// @param vault The address of the ERC4626 vault.
55+ /// @param set True to configure the vault, false to clear the record.
7156 /// @dev Callable only by the governor. Vault must be ERC4626.
7257 /// Only configure internal pricing after verifying that the implementation of
7358 /// `convertToAssets` and `convertToShares` cannot be manipulated.
74- function govSetResolvedVault (address vault ) external onlyGovernor {
75- address asset = ERC4626 (vault).asset ();
59+ function govSetResolvedVault (address vault , bool set ) external onlyGovernor {
60+ address asset = set ? ERC4626 (vault).asset () : address ( 0 );
7661 resolvedVaults[vault] = asset;
7762 emit ResolvedVaultSet (vault, asset);
7863 }
7964
80- /// @notice Clear the configuration for internal pricing resolution for a vault.
81- /// @param vault The address of the ERC4626 vault.
82- /// @dev Callable only by the governor.
83- function govClearResolvedVault (address vault ) external onlyGovernor {
84- delete resolvedVaults[vault];
85- emit ResolvedVaultSet (vault, address (0 ));
86- }
87-
88- /// @notice Set an PriceOracle as a fallback resolver.
65+ /// @notice Set a PriceOracle as a fallback resolver.
8966 /// @param _fallbackOracle The address of the PriceOracle that is called when base/quote is not configured.
9067 /// @dev `address(0)` removes the fallback.
9168 function govSetFallbackOracle (address _fallbackOracle ) external onlyGovernor {
9269 fallbackOracle = _fallbackOracle;
9370 emit FallbackOracleSet (_fallbackOracle);
9471 }
9572
96- /// @notice Transfer the governor role to another address.
97- /// @param newGovernor The address of the next governor.
98- /// @dev Can only be called by the current governor.
99- function transferGovernance (address newGovernor ) external onlyGovernor {
100- _setGovernor (newGovernor);
101- }
102-
103- /// @notice Renounce the governor role.
104- /// @dev Sets governor to address(0), effectively removing governance.
105- function renounceGovernance () external onlyGovernor {
106- _setGovernor (address (0 ));
107- }
108-
10973 /// @inheritdoc IPriceOracle
11074 function getQuote (uint256 inAmount , address base , address quote ) external view returns (uint256 ) {
11175 address oracle;
@@ -128,7 +92,7 @@ contract EulerRouter is IPriceOracle {
12892 /// @param quote The token that is the unit of account.
12993 /// @dev Implements the following recursive resolution logic:
13094 /// 1. Check the base case: `base == quote` and terminate if true.
131- /// 2. If an PriceOracle is configured for base/quote in the `oracles` mapping,
95+ /// 2. If a PriceOracle is configured for base/quote in the `oracles` mapping,
13296 /// return it without transforming the other variables.
13397 /// 3. If `base` is configured as an ERC4626 vault with internal pricing,
13498 /// transform inAmount by calling `convertToAssets` and recurse by substituting `asset` for `base`.
@@ -137,7 +101,7 @@ contract EulerRouter is IPriceOracle {
137101 /// 5. If there is a fallback oracle, return it without transforming the other variables, else revert.
138102 /// @return The resolved inAmount.
139103 /// @return The resolved base.
140- /// @return The resolved base .
104+ /// @return The resolved quote .
141105 /// @return The resolved PriceOracle to call.
142106 function _resolveOracle (uint256 inAmount , address base , address quote )
143107 internal
@@ -166,20 +130,4 @@ contract EulerRouter is IPriceOracle {
166130 if (oracle == address (0 )) revert Errors.PriceOracle_NotSupported (base, quote);
167131 return (inAmount, base, quote, oracle);
168132 }
169-
170- /// @notice Set the governor address.
171- /// @param newGovernor The address of the new governor.
172- function _setGovernor (address newGovernor ) internal {
173- address oldGovernor = governor;
174- governor = newGovernor;
175- emit GovernorSet (oldGovernor, newGovernor);
176- }
177-
178- /// @notice Restrict access to the governor.
179- modifier onlyGovernor () {
180- if (msg .sender != governor) {
181- revert Errors.Governance_CallerNotGovernor ();
182- }
183- _;
184- }
185133}
0 commit comments