diff --git a/script/DeployOracle.s.sol b/script/DeployOracle.s.sol index d9a3adf..dcce999 100644 --- a/script/DeployOracle.s.sol +++ b/script/DeployOracle.s.sol @@ -5,6 +5,7 @@ import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; import {CommonMainnet} from '@script/Common.s.sol'; import 'forge-std/console2.sol'; +import {CamelotV2RelayerFactory} from '@contracts/factories/CamelotV2RelayerFactory.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; @@ -179,14 +180,19 @@ contract DeployCamelotEPendleUsdOracle is Script, CommonMainnet { IBaseOracle public _PendleEthOracleRelayer; IBaseOracle public _PendleUsdOracleRelayer; IBaseOracle public _ePendleUsdOracle; + IBaseOracle public _ePendleDelayedOracle; address public MAINNET_E_PENDLE = 0x3EaBE18eAE267D1B57f917aBa085bb5906114600; address public MAINNET_PENDLE = 0x0c880f6761F1af8d9Aa9C466984b80DAb9a8c9e8; + CamelotV2RelayerFactory internal _camelotV2RelayerFactory; function run() public { vm.startBroadcast(); - _ePendlePendleCamelotV2Relayer = camelotV2RelayerFactory.deployCamelotV2Relayer( + // TODO: remove factory deployment + _camelotV2RelayerFactory = new CamelotV2RelayerFactory(); + + _ePendlePendleCamelotV2Relayer = _camelotV2RelayerFactory.deployCamelotV2Relayer( MAINNET_CAMELOT_V2_FACTORY, MAINNET_E_PENDLE, MAINNET_PENDLE, uint32(MAINNET_CAMELOT_QUOTE_PERIOD) ); @@ -201,14 +207,14 @@ contract DeployCamelotEPendleUsdOracle is Script, CommonMainnet { _ePendleUsdOracle = denominatedOracleFactory.deployDenominatedOracle(_ePendlePendleCamelotV2Relayer, _PendleUsdOracleRelayer, false); - IBaseOracle ePendleDelayedOracle = + _ePendleDelayedOracle = delayedOracleFactory.deployDelayedOracle(IBaseOracle(_ePendleUsdOracle), MAINNET_ORACLE_DELAY); _PendleUsdOracleRelayer.symbol(); _PendleUsdOracleRelayer.getResultWithValidity(); - ePendleDelayedOracle.symbol(); - ePendleDelayedOracle.getResultWithValidity(); + _ePendleDelayedOracle.symbol(); + _ePendleDelayedOracle.getResultWithValidity(); vm.stopBroadcast(); } diff --git a/script/predeployment/DeployFactories.s.sol b/script/predeployment/DeployFactories.s.sol index 4ffcc9a..5615888 100644 --- a/script/predeployment/DeployFactories.s.sol +++ b/script/predeployment/DeployFactories.s.sol @@ -65,9 +65,6 @@ contract DeployCamelotV2FactoryMain is Script { vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); _camelotV2RelayerFactory = new CamelotV2RelayerFactory(); - _camelotV2RelayerFactory.addAuthorization(MAINNET_TIMELOCK_CONTROLLER); - _camelotV2RelayerFactory.removeAuthorization(MAINNET_DEPLOYER); - vm.stopBroadcast(); } } diff --git a/src/contracts/oracles/CamelotV2Relayer.sol b/src/contracts/oracles/CamelotV2Relayer.sol index 9b33d9a..86b09a4 100644 --- a/src/contracts/oracles/CamelotV2Relayer.sol +++ b/src/contracts/oracles/CamelotV2Relayer.sol @@ -23,7 +23,12 @@ contract CamelotV2Relayer { constructor(address _camelotV2Factory, address _baseToken, address _quoteToken, uint32 _quotePeriod) { camelotV2Pair = ICamelotFactory(_camelotV2Factory).getPair(_baseToken, _quoteToken); require(camelotV2Pair != address(0)); - require(camelotV2Pair.stableSwap() == false); + require(ICamelotPair(camelotV2Pair).stableSwap() == false); + + uint112 reserve0; + uint112 reserve1; + (reserve0, reserve1,,) = ICamelotPair(camelotV2Pair).getReserves(); + require(reserve0 != 0 && reserve1 != 0, 'CamelotV2Relayer: INSUFFICIENT_RESERVES'); address _token0 = ICamelotPair(camelotV2Pair).token0(); address _token1 = ICamelotPair(camelotV2Pair).token1(); @@ -44,35 +49,43 @@ contract CamelotV2Relayer { symbol = string(abi.encodePacked(IERC20Metadata(_baseToken).symbol(), ' / ', IERC20Metadata(_quoteToken).symbol())); } - // TODO: Update calculation for V2 - function getResultWithValidity() external view returns (uint256 _result, bool _validity) { - // TODO: add catch if the pool doesn't have enough history - return false - - // Consult the query with a TWAP period of QUOTE_PERIOD - int24 _arithmeticMeanTick = DataStorageLibrary.consult(camelotV2Pool, QUOTE_PERIOD); - // Calculate the quote amount - uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ - tick: _arithmeticMeanTick, - baseAmount: BASE_AMOUNT, - baseToken: baseToken, - quoteToken: quoteToken - }); - // Process the quote result to 18 decimal quote - _result = _parseResult(_quoteAmount); + uint112 _reserve0; + uint112 _reserve1; + (_reserve0, _reserve1,,) = ICamelotPair(camelotV2Pair).getReserves(); + + require(_reserve0 > 0 && _reserve1 > 0, 'CamelotPair: INSUFFICIENT_RESERVES'); + + uint256 price; + if (baseToken == ICamelotPair(camelotV2Pair).token0()) { + // baseToken is token0, quoteToken is token1 + price = uint256(_reserve1) * BASE_AMOUNT / uint256(_reserve0); + } else { + // baseToken is token1, quoteToken is token0 + price = uint256(_reserve0) * BASE_AMOUNT / uint256(_reserve1); + } + + _result = _parseResult(price); _validity = true; } function read() external view returns (uint256 _result) { - // This call may revert with 'OLD!' if the pool doesn't have enough cardinality or initialized history - int24 _arithmeticMeanTick = DataStorageLibrary.consult(camelotV2Pool, QUOTE_PERIOD); - uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ - tick: _arithmeticMeanTick, - baseAmount: BASE_AMOUNT, - baseToken: baseToken, - quoteToken: quoteToken - }); - _result = _parseResult(_quoteAmount); + uint112 _reserve0; + uint112 _reserve1; + (_reserve0, _reserve1,,) = ICamelotPair(camelotV2Pair).getReserves(); + + require(_reserve0 > 0 && _reserve1 > 0, 'CamelotPair: INSUFFICIENT_RESERVES'); + + uint256 price; + if (baseToken == ICamelotPair(camelotV2Pair).token0()) { + // baseToken is token0, quoteToken is token1 + price = uint256(_reserve1) * BASE_AMOUNT / uint256(_reserve0); + } else { + // baseToken is token1, quoteToken is token0 + price = uint256(_reserve0) * BASE_AMOUNT / uint256(_reserve1); + } + + _result = _parseResult(price); } function _parseResult(uint256 _quoteResult) internal view returns (uint256 _result) {