Omniscia Bluejay Finance Audit
PriceStabilizer Manual Review Findings
PriceStabilizer Manual Review Findings
PSR-01M: Insufficiently Protected Capability of Oracle Adjustment
Type | Severity | Location |
---|---|---|
Centralization Concern | PriceStabilizer.sol:L50-L59 |
Description:
The updateOracle
function permits the oracle to be arbitrarily set by the MANAGER_ROLE
and thus compromise the stabilizing updatePrice
function which can in turn affect the price movement of the token and how its treasury is handled.
Example:
33function initializePool(address pool, address oracle)34 public35 override36 onlyRole(MANAGER_ROLE)37{38 require(poolInfos[pool].reserve == address(0), "Pool has been initialized");39 (address reserve, address stablecoin, , ) = stablecoinEngine.poolsInfo(40 pool41 );42 poolInfos[pool] = PoolInfo({43 reserve: reserve,44 stablecoin: stablecoin,45 pool: pool,46 oracle: oracle47 });48}49
50function updateOracle(address pool, address oracle)51 public52 override53 ifPoolExists(pool)54 onlyRole(MANAGER_ROLE)55{56 require(oracle != address(0), "Address cannot be 0");57 poolInfos[pool].oracle = oracle;58 emit UpdatedOracle(pool, oracle);59}60
61// oracle should quote the price as number of stablecoin for reserve62function updatePrice(63 address pool,64 uint256 amountIn,65 uint256 minAmountOut,66 bool stablecoinForReserve67)68 public69 override70 ifPoolExists(pool)71 onlyRole(OPERATOR_ROLE)72 returns (uint256 poolPrice, uint256 oraclePrice)73{74 (uint256 stablecoinReserve, uint256 reserveReserve) = stablecoinEngine75 .getReserves(pool);76 poolPrice = (stablecoinReserve * WAD) / reserveReserve;77 oraclePrice = IPriceFeedOracle(poolInfos[pool].oracle).getPrice();78 require(79 stablecoinForReserve80 ? oraclePrice >= poolPrice81 : oraclePrice <= poolPrice,82 "Swap direction is incorrect"83 );84
85 stablecoinEngine.swap(pool, amountIn, minAmountOut, stablecoinForReserve);86
87 (stablecoinReserve, reserveReserve) = stablecoinEngine.getReserves(pool);88 poolPrice = (stablecoinReserve * WAD) / reserveReserve;89 require(90 stablecoinForReserve91 ? oraclePrice >= poolPrice92 : oraclePrice <= poolPrice,93 "Overcorrection"94 );95
96 emit UpdatePrice(pool, amountIn, minAmountOut, stablecoinForReserve);97}
Recommendation:
We advise the capability of adjusting the oracle to be omitted from the codebase. Additionally, we advise more stringent control to be imposed on all oracle related actions (initializePool
and updateOracle
) as they can compromise the system. As a recommendation, oracle updates could be queued for a pre-determinate period of time in which the owner of the system possesses veto power.
Alleviation:
The Bluejay Finance team stated that they plan to fully decentralize the operation of the stabilizer by assigning the relevant access control roles only to governance-controlled addresses such as the timelock. We consider this decentralization path an adequate response to the exhibit and we mark it as alleviated based on the premise that the Bluejay Finance team will act accordingly after the deployment of their protocol.