From f5e3fb8ba410625966e4a6517c2a1f6aefc5a5e2 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 16:25:13 -0500 Subject: [PATCH 01/11] removing camelot from repo --- .gitmodules | 11 +- lib/AlgebraV1.9 | 1 - remappings.txt | 5 - script/Common.s.sol | 48 +++--- script/DeployOracle.s.sol | 2 - script/Registry.s.sol | 16 -- script/dexrelayer/CallResult.s.sol | 65 -------- script/dexrelayer/DeployOracleFactories.s.sol | 8 - script/dexrelayer/DeployOracles.s.sol | 11 -- script/dexrelayer/DeployPool.s.sol | 96 ------------ script/dexrelayer/GetPrice.s.sol | 86 ++++------- .../MockSetupPostEnvironment.s.sol | 29 +--- .../postdeployment/SetupPostEnvironment.s.sol | 26 ++-- script/predeployment/DeployRelayers.s.sol | 46 ------ .../factories/CamelotRelayerChild.sol | 15 -- .../factories/CamelotRelayerFactory.sol | 33 ---- src/contracts/for-test/Data.sol | 34 +--- src/contracts/for-test/MintableERC20.sol | 1 - .../factories/ICamelotRelayerFactory.sol | 16 -- src/interfaces/oracles/ICamelotRelayer.sol | 36 ----- test/unit/RelayerFactories.t.sol | 145 +----------------- 21 files changed, 79 insertions(+), 651 deletions(-) delete mode 160000 lib/AlgebraV1.9 delete mode 100644 script/dexrelayer/CallResult.s.sol delete mode 100644 script/dexrelayer/DeployPool.s.sol delete mode 100644 src/contracts/factories/CamelotRelayerChild.sol delete mode 100644 src/contracts/factories/CamelotRelayerFactory.sol delete mode 100644 src/interfaces/factories/ICamelotRelayerFactory.sol delete mode 100644 src/interfaces/oracles/ICamelotRelayer.sol diff --git a/.gitmodules b/.gitmodules index eb95de4..8269a2b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std +path = lib/forge-std +url = https://github.com/foundry-rs/forge-std [submodule "lib/openzeppelin-contracts"] - path = lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts -[submodule "lib/AlgebraV1.9"] - path = lib/AlgebraV1.9 - url = https://github.com/cryptoalgebra/AlgebraV1.9 +path = lib/openzeppelin-contracts +url = https://github.com/OpenZeppelin/openzeppelin-contracts diff --git a/lib/AlgebraV1.9 b/lib/AlgebraV1.9 deleted file mode 160000 index 779b568..0000000 --- a/lib/AlgebraV1.9 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 779b5681395e2864ba6be9ff2adaa2870f6a600c diff --git a/remappings.txt b/remappings.txt index 302d842..24d88ba 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,10 +1,5 @@ @openzeppelin/=lib/openzeppelin-contracts/ @isolmate/=lib/isolmate/src/ -@cryptoalgebra/v1.9-core/contracts/=lib/AlgebraV1.9/src/core/contracts/ - -@algebra-core/=lib/AlgebraV1.9/src/core/contracts/ -@algebra-periphery/=lib/AlgebraV1.9/src/periphery/contracts/ -@algebra-tokenomics/=lib/AlgebraV1.9/src/tokenomics/contracts/ @script/=script/ @contracts/=src/contracts/ diff --git a/script/Common.s.sol b/script/Common.s.sol index fdb1194..dc46f27 100644 --- a/script/Common.s.sol +++ b/script/Common.s.sol @@ -3,11 +3,7 @@ pragma solidity 0.7.6; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; -import {Sqrt} from '@algebra-core/libraries/Sqrt.sol'; -import {IERC20Metadata} from '@algebra-periphery/interfaces/IERC20Metadata.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IAuthorizable} from '@interfaces/utils/IAuthorizable.sol'; -import {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {DenominatedOracleFactory} from '@contracts/factories/DenominatedOracleFactory.sol'; import {PendleRelayerFactory} from '@contracts/factories/pendle/PendleRelayerFactory.sol'; @@ -15,7 +11,6 @@ import {IDelayedOracleFactory} from '@interfaces/factories/IDelayedOracleFactory abstract contract CommonMainnet is Script { ChainlinkRelayerFactory public chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); - CamelotRelayerFactory public camelotRelayerFactory = CamelotRelayerFactory(MAINNET_CAMELOT_RELAYER_FACTORY); DenominatedOracleFactory public denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); PendleRelayerFactory public pendleRelayerFactory = PendleRelayerFactory(MAINNET_PENDLE_RELAYER_FACTORY); @@ -24,12 +19,10 @@ abstract contract CommonMainnet is Script { abstract contract CommonSepolia is Script { ChainlinkRelayerFactory public chainlinkRelayerFactory = ChainlinkRelayerFactory(SEPOLIA_CHAINLINK_RELAYER_FACTORY); - CamelotRelayerFactory public camelotRelayerFactory = CamelotRelayerFactory(SEPOLIA_CAMELOT_RELAYER_FACTORY); DenominatedOracleFactory public denominatedOracleFactory = DenominatedOracleFactory(SEPOLIA_DENOMINATED_ORACLE_FACTORY); IAuthorizable public chainlinkRelayerFactoryAuth = IAuthorizable(SEPOLIA_CHAINLINK_RELAYER_FACTORY); - IAuthorizable public camelotRelayerFactoryAuth = IAuthorizable(SEPOLIA_CAMELOT_RELAYER_FACTORY); IAuthorizable public denominatedOracleFactoryAuth = IAuthorizable(SEPOLIA_DENOMINATED_ORACLE_FACTORY); address public deployer = vm.envAddress('ARB_SEPOLIA_DEPLOYER_ADDR'); @@ -42,32 +35,30 @@ abstract contract CommonSepolia is Script { function revokeFactories() internal { _revoke(chainlinkRelayerFactoryAuth, TEST_GOVERNOR, deployer); - _revoke(camelotRelayerFactoryAuth, TEST_GOVERNOR, deployer); _revoke(denominatedOracleFactoryAuth, TEST_GOVERNOR, deployer); } // basePrice = OD, quotePrice = WETH - function initialPrice( - uint256 _basePrice, - uint256 _quotePrice, - address _pool - ) internal view returns (uint160 _sqrtPriceX96) { - address _token0 = IAlgebraPool(_pool).token0(); - bytes32 _symbol = keccak256(abi.encodePacked(IERC20Metadata(_token0).symbol())); - uint256 _price; + // function initialPrice( + // uint256 _basePrice, + // uint256 _quotePrice, + // address _pool + // ) internal view returns (uint160 _sqrtPriceX96) { + // bytes32 _symbol = keccak256(abi.encodePacked(IERC20Metadata(_token0).symbol())); + // uint256 _price; - // price = token1 / token0 - if (_token0 == SEPOLIA_SYSTEM_COIN) { - require(keccak256(abi.encodePacked('OD')) == _symbol, '!OD'); - _price = ((_quotePrice * WAD) / _basePrice); - } else { - require(keccak256(abi.encodePacked('WETH')) == _symbol, '!WETH'); - _price = ((_basePrice * WAD) / _quotePrice); - } + // // price = token1 / token0 + // if (_token0 == SEPOLIA_SYSTEM_COIN) { + // require(keccak256(abi.encodePacked('OD')) == _symbol, '!OD'); + // _price = ((_quotePrice * WAD) / _basePrice); + // } else { + // require(keccak256(abi.encodePacked('WETH')) == _symbol, '!WETH'); + // _price = ((_basePrice * WAD) / _quotePrice); + // } - // check math @ https://uniswap-v3-calculator.netlify.app/ - _sqrtPriceX96 = uint160(Sqrt.sqrtAbs(int256(_price)) * (2 ** 96)) / 1e9; - } + // // check math @ https://uniswap-v3-calculator.netlify.app/ + // _sqrtPriceX96 = uint160(Sqrt.sqrtAbs(int256(_price)) * (2 ** 96)) / 1e9; + // } /** * note FOR TEST @@ -76,9 +67,6 @@ abstract contract CommonSepolia is Script { if (!chainlinkRelayerFactoryAuth.authorizedAccounts(admin)) { chainlinkRelayerFactoryAuth.addAuthorization(admin); } - if (!camelotRelayerFactoryAuth.authorizedAccounts(admin)) { - camelotRelayerFactoryAuth.addAuthorization(admin); - } if (!denominatedOracleFactoryAuth.authorizedAccounts(admin)) { denominatedOracleFactoryAuth.addAuthorization(admin); } diff --git a/script/DeployOracle.s.sol b/script/DeployOracle.s.sol index b6a4167..aeab6ce 100644 --- a/script/DeployOracle.s.sol +++ b/script/DeployOracle.s.sol @@ -5,8 +5,6 @@ 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 {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {DenominatedOracleFactory} from '@contracts/factories/DenominatedOracleFactory.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; diff --git a/script/Registry.s.sol b/script/Registry.s.sol index 10d9d4b..f35267a 100644 --- a/script/Registry.s.sol +++ b/script/Registry.s.sol @@ -44,27 +44,12 @@ address constant SEPOLIA_SYSTEM_ORACLE = address(0); // post setup address constant SEPOLIA_CHAINLINK_ETH_USD_FEED = 0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165; address constant SEPOLIA_CHAINLINK_ARB_USD_FEED = 0xD1092a65338d049DB68D7Be6bD89d17a0929945e; -// Algebra protocol (deployed by daopunk - not official camelot contracts) -address constant SEPOLIA_ALGEBRA_FACTORY = 0x21852176141b8D139EC5D3A1041cdC31F0F20b94; -address constant SEPOLIA_ALGEBRA_POOL_DEPLOYER = 0xca5C849a6ce036cdF83e8F87dCa71Dc2B309E59b; -address constant SEPOLIA_ALGEBRA_QUOTER = 0xf7E25be14E5F5e36d5c2FE7a7822A601d18CD120; -address constant SEPOLIA_ALGEBRA_SWAPROUTER = 0xD18583a01837c9Dc4dC02E2202955E9d71C08771; -address constant SEPOLIA_ALGEBRA_NFT_DESCRIPTOR = 0x88Fa9f46645C7c638fFA9675b36DfdeF2cbae296; -address constant SEPOLIA_ALGEBRA_PROXY = 0xDAed3376f8112570a9E319A1D425C9B37CA901B3; -address constant SEPOLIA_ALGEBRA_NFT_MANAGER = 0xAf588D87BaDE8654F26686D5502be8ceDbE8FFe0; -address constant SEPOLIA_ALGEBRA_INTERFACE_MULTICALL = 0xf94b8a5D6dBd8F4026Ae467fdDB96028F74b9B96; -address constant SEPOLIA_ALGEBRA_V3_MIGRATOR = 0x766682889b8A6070be210C2a821Ad671E3388ab3; -address constant SEPOLIA_ALGEBRA_LIMIT_FARMING = 0x62B46a9565C7ECEc4FE7Dd309174ac3B03AF44E2; -address constant SEPOLIA_ALGEBRA_ETERNAL_FARMING = 0xD8474356C6976E18275735531b22f3Aa872a8b3B; -address constant SEPOLIA_ALGEBRA_FARM_CENTER = 0x04e4A5A4E4D2A5a0fb48ECde0bbD5554652D254b; - // -- Mainnet -- ////////// FACTORIES ////////// address constant MAINNET_CAMELOT_RELAYER_FACTORY = 0x36645830479170265A154Acb726780fdaE41A28F; address constant MAINNET_CHAINLINK_RELAYER_FACTORY = 0x06C32500489C28Bd57c551afd8311Fef20bFaBB5; address constant MAINNET_DENOMINATED_ORACLE_FACTORY = 0xBF760b23d2ef3615cec549F22b95a34DB0F8f5CD; -address constant MAINNET_ALGEBRA_FACTORY = 0x1a3c9B1d2F0529D97f2afC5136Cc23e58f1FD35B; address constant MAINNET_DELAYED_ORACLE_FACTORY = 0x9Dd63fA54dEfd8820BCAb3e3cC39aeEc1aE88098; ////////// RELAYERS ////////// @@ -118,4 +103,3 @@ uint32 constant MAINNET_PENDLE_TWAP_DURATION = 900; address constant MAINNET_PENDLE_ORACLE = 0x9a9Fa8338dd5E5B2188006f1Cd2Ef26d921650C2; address constant MAINNET_PENDLE_RETH_MARKET = 0x14FbC760eFaF36781cB0eb3Cb255aD976117B9Bd; address constant MAINNET_PENDLE_WSTETH_MARKET = 0x08a152834de126d2ef83D612ff36e4523FD0017F; - diff --git a/script/dexrelayer/CallResult.s.sol b/script/dexrelayer/CallResult.s.sol deleted file mode 100644 index b5e5f62..0000000 --- a/script/dexrelayer/CallResult.s.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; -pragma abicoder v2; - -import '@script/Registry.s.sol'; -import {Script} from 'forge-std/Script.sol'; -import {Test} from 'forge-std/Test.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; -import {ICamelotRelayer} from '@interfaces/oracles/ICamelotRelayer.sol'; -import {Data} from '@contracts/for-test/Data.sol'; - -// BROADCAST -// source .env && forge script CallResult --skip-simulation --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY - -// SIMULATE -// source .env && forge script CallResult --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC - -contract CallResult is Script, Test { - Data public data = Data(RELAYER_DATA); - - ICamelotRelayer public relayer = data.camelotRelayer(); - - function run() public { - vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); - ( - uint160 price, - int24 tick, - int24 prevInitializedTick, - uint16 fee, - uint16 timepointIndex, - uint8 communityFee, - bool unlocked - ) = getGlobalState(IAlgebraPool(relayer.algebraPool())); - - emit log_named_uint('Price :', price); - emit log_named_uint('Fee :', fee); - emit log_named_uint('TimePntIndex:', timepointIndex); - emit log_named_uint('CommunityFee:', communityFee); - emit log_named_int('Tick :', tick); - emit log_named_int('PrevInitTick:', prevInitializedTick); - assertTrue(unlocked); - - relayer.getResultWithValidity(); - vm.stopBroadcast(); - } - - /** - * @dev helper functions - */ - function getGlobalState(IAlgebraPool _pool) - public - view - returns ( - uint160 price, - int24 tick, - int24 prevInitializedTick, - uint16 fee, - uint16 timepointIndex, - uint8 communityFee, - bool unlocked - ) - { - (price, tick, prevInitializedTick, fee, timepointIndex, communityFee, unlocked) = _pool.globalState(); - } -} diff --git a/script/dexrelayer/DeployOracleFactories.s.sol b/script/dexrelayer/DeployOracleFactories.s.sol index df647eb..578cf04 100644 --- a/script/dexrelayer/DeployOracleFactories.s.sol +++ b/script/dexrelayer/DeployOracleFactories.s.sol @@ -3,7 +3,6 @@ pragma solidity 0.7.6; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; -import {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {DenominatedOracleFactory} from '@contracts/factories/DenominatedOracleFactory.sol'; import {IAuthorizable} from '@interfaces/utils/IAuthorizable.sol'; @@ -19,7 +18,6 @@ contract MockDeployFactories is Script { Data public data = Data(RELAYER_DATA); ChainlinkRelayerFactory public chainlinkRelayerFactory; - CamelotRelayerFactory public camelotRelayerFactory; DenominatedOracleFactory public denominatedOracleFactory; /** @@ -28,15 +26,9 @@ contract MockDeployFactories is Script { function run() public { vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK')); chainlinkRelayerFactory = new ChainlinkRelayerFactory(); - camelotRelayerFactory = new CamelotRelayerFactory(); denominatedOracleFactory = new DenominatedOracleFactory(); - IAuthorizable(address(chainlinkRelayerFactory)).addAuthorization(vm.envAddress('ARB_SEPOLIA_ADDR')); - IAuthorizable(address(camelotRelayerFactory)).addAuthorization(vm.envAddress('ARB_SEPOLIA_ADDR')); - IAuthorizable(address(denominatedOracleFactory)).addAuthorization(vm.envAddress('ARB_SEPOLIA_ADDR')); - data.modifyFactory(bytes32('chainlinkRelayerFactory'), address(chainlinkRelayerFactory)); - data.modifyFactory(bytes32('camelotRelayerFactory'), address(camelotRelayerFactory)); data.modifyFactory(bytes32('denominatedOracleFactory'), address(denominatedOracleFactory)); vm.stopBroadcast(); } diff --git a/script/dexrelayer/DeployOracles.s.sol b/script/dexrelayer/DeployOracles.s.sol index 8fe67c5..689989d 100644 --- a/script/dexrelayer/DeployOracles.s.sol +++ b/script/dexrelayer/DeployOracles.s.sol @@ -3,11 +3,9 @@ pragma solidity 0.7.6; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; -import {ICamelotRelayerFactory} from '@interfaces/factories/ICamelotRelayerFactory.sol'; import {IChainlinkRelayerFactory} from '@interfaces/factories/IChainlinkRelayerFactory.sol'; import {IDenominatedOracleFactory} from '@interfaces/factories/IDenominatedOracleFactory.sol'; import {IChainlinkRelayer} from '@interfaces/oracles/IChainlinkRelayer.sol'; -import {ICamelotRelayer} from '@interfaces/oracles/ICamelotRelayer.sol'; import {IDenominatedOracle} from '@interfaces/oracles/IDenominatedOracle.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; @@ -23,18 +21,15 @@ contract DeployOracles is Script { Data public data = Data(RELAYER_DATA); IBaseOracle public chainlinkEthUSDPriceFeed; - IBaseOracle public camelotRelayer; IBaseOracle public denominatedOracle; IChainlinkRelayerFactory public chainlinkRelayerFactory; - ICamelotRelayerFactory public camelotRelayerFactory; IDenominatedOracleFactory public denominatedOracleFactory; function run() public { vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); chainlinkRelayerFactory = data.chainlinkRelayerFactory(); - camelotRelayerFactory = data.camelotRelayerFactory(); denominatedOracleFactory = data.denominatedOracleFactory(); // deploy chainlink relayer @@ -42,12 +37,6 @@ contract DeployOracles is Script { chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); data.modifyOracle(bytes32('chainlinkRelayer'), address(chainlinkEthUSDPriceFeed)); - // deploy camelot relayer - camelotRelayer = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, data.tokenA(), data.tokenB(), uint32(ORACLE_INTERVAL_TEST) - ); - data.modifyOracle(bytes32('camelotRelayer'), address(camelotRelayer)); - // deploy denominated oracle denominatedOracle = denominatedOracleFactory.deployDenominatedOracle(chainlinkEthUSDPriceFeed, camelotRelayer, false); diff --git a/script/dexrelayer/DeployPool.s.sol b/script/dexrelayer/DeployPool.s.sol deleted file mode 100644 index 513d9d0..0000000 --- a/script/dexrelayer/DeployPool.s.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import '@script/Registry.s.sol'; -import {Script} from 'forge-std/Script.sol'; -import {Sqrt} from '@algebra-core/libraries/Sqrt.sol'; -import {IERC20Metadata} from '@algebra-periphery/interfaces/IERC20Metadata.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; -import {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; -import {ICamelotRelayer} from '@interfaces/oracles/ICamelotRelayer.sol'; -import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; -import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {Router} from '@contracts/for-test/Router.sol'; -import {Data} from '@contracts/for-test/Data.sol'; - -// BROADCAST -// source .env && forge script DeployPool --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY - -// SIMULATE -// source .env && forge script DeployPool --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC - -contract DeployPool is Script { - Data public data = Data(RELAYER_DATA); - - // Pool Factory - IAlgebraFactory public algebraFactory = IAlgebraFactory(SEPOLIA_ALGEBRA_FACTORY); - - // Router - Router public router; - - function run() public { - vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); - - deployTestTokens(); - deployPool(); - - // check balance before - (uint256 bal0, uint256 bal1) = data.getPoolBal(); - - // deploy router and approve it to handle funds - router = new Router(data.pool(), H); - IERC20(data.tokenA()).approve(address(router), MINT_AMOUNT); - IERC20(data.tokenB()).approve(address(router), MINT_AMOUNT); - - // add liquidity - (int24 bottomTick, int24 topTick) = data.generateTickParams(); - router.addLiquidity(bottomTick, topTick, uint128(100)); - - // check balance after - (bal0, bal1) = data.getPoolBal(); - - vm.stopBroadcast(); - } - - /** - * @dev setup functions - */ - function deployTestTokens() public { - MintableERC20 token0 = new MintableERC20('Open Dollar', 'OD', 18); - MintableERC20 token1 = new MintableERC20('Wrapped ETH', 'WETH', 18); - token0.mint(H, MINT_AMOUNT); - token1.mint(H, MINT_AMOUNT); - data.setTokens(address(token0), address(token1)); - } - - function deployPool() public { - algebraFactory.createPool(data.tokenA(), data.tokenB()); - data.setPool(IAlgebraPool(algebraFactory.poolByPair(data.tokenA(), data.tokenB()))); - uint160 _sqrtPriceX96 = initialPrice(INIT_OD_AMOUNT, INIT_WETH_AMOUNT, address(data.pool())); - data.pool().initialize(_sqrtPriceX96); - } - - // basePrice = OD, quotePrice = WETH - function initialPrice( - uint256 _basePrice, - uint256 _quotePrice, - address _pool - ) internal view returns (uint160 _sqrtPriceX96) { - address _token0 = IAlgebraPool(_pool).token0(); - bytes32 _symbol = keccak256(abi.encodePacked(IERC20Metadata(_token0).symbol())); - uint256 _price; - - // price = token1 / token0 - if (_token0 == data.tokenA()) { - require(keccak256(abi.encodePacked('OD')) == _symbol, '!OD'); - _price = ((_quotePrice * WAD) / _basePrice); - } else { - require(keccak256(abi.encodePacked('WETH')) == _symbol, '!WETH'); - _price = ((_basePrice * WAD) / _quotePrice); - } - - _sqrtPriceX96 = uint160(Sqrt.sqrtAbs(int256(_price)) * (2 ** 96)); - } -} diff --git a/script/dexrelayer/GetPrice.s.sol b/script/dexrelayer/GetPrice.s.sol index 252f606..65018bb 100644 --- a/script/dexrelayer/GetPrice.s.sol +++ b/script/dexrelayer/GetPrice.s.sol @@ -5,14 +5,10 @@ pragma abicoder v2; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; import {Test} from 'forge-std/Test.sol'; -import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IChainlinkRelayer} from '@interfaces/oracles/IChainlinkRelayer.sol'; -import {ICamelotRelayer} from '@interfaces/oracles/ICamelotRelayer.sol'; import {IDenominatedOracle} from '@interfaces/oracles/IDenominatedOracle.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {Data} from '@contracts/for-test/Data.sol'; -import {DataStorageLibrary} from '@algebra-periphery/libraries/DataStorageLibrary.sol'; // BROADCAST // source .env && forge script GetPrice --skip-simulation --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY @@ -21,56 +17,38 @@ import {DataStorageLibrary} from '@algebra-periphery/libraries/DataStorageLibrar // source .env && forge script GetPrice --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC contract GetPrice is Script, Test { - Data public data = Data(RELAYER_DATA); - - // Tokens - address public tokenA = data.tokenA(); - address public tokenB = data.tokenB(); - - // Pool - IAlgebraPool public pool = data.pool(); - uint256 public initPrice = ((INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); - - // Relayers - IBaseOracle public chainlinkRelayer = IBaseOracle(address(data.chainlinkRelayer())); - IBaseOracle public camelotRelayer = IBaseOracle(address(data.camelotRelayer())); - IBaseOracle public denominatedOracle = IBaseOracle(address(data.denominatedOracle())); - - function run() public { - vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); - - poolPrice(); - camelotRelayerPrice(); - chainlinkRelayerPrice(); - denominatedOraclePrice(); - } - - function poolPrice() public { - IAlgebraPool _pool = IAlgebraPool(pool); - (uint160 _sqrtPriceX96,,,,,,) = _pool.globalState(); - - emit log_named_uint('Sq Root Price X96', _sqrtPriceX96); - - uint256 _price = (SafeMath.div(uint256(_sqrtPriceX96), (2 ** 96))) ** 2; - - emit log_named_uint('Price from L-Pool', _price); - emit log_named_uint('Price Calculated', (INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); - } - - function camelotRelayerPrice() public { - uint256 _result = camelotRelayer.read(); - emit log_named_uint('Camelot OD/WETH', _result); - } - - function chainlinkRelayerPrice() public { - uint256 _result = chainlinkRelayer.read(); - emit log_named_uint('Chainlink ETH/USD', _result); - } - - function denominatedOraclePrice() public { - uint256 _result = denominatedOracle.read(); - emit log_named_uint('SystOracle OD/USD', _result); - } +// Data public data = Data(RELAYER_DATA); + +// // Tokens +// address public tokenA = data.tokenA(); +// address public tokenB = data.tokenB(); + +// // Pool +// IAlgebraPool public pool = data.pool(); +// uint256 public initPrice = ((INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); + +// // Relayers +// IBaseOracle public chainlinkRelayer = IBaseOracle(address(data.chainlinkRelayer())); +// IBaseOracle public denominatedOracle = IBaseOracle(address(data.denominatedOracle())); + +// function run() public { +// vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); + +// poolPrice(); +// camelotRelayerPrice(); +// chainlinkRelayerPrice(); +// denominatedOraclePrice(); +// } + +// function chainlinkRelayerPrice() public { +// uint256 _result = chainlinkRelayer.read(); +// emit log_named_uint('Chainlink ETH/USD', _result); +// } + +// function denominatedOraclePrice() public { +// uint256 _result = denominatedOracle.read(); +// emit log_named_uint('SystOracle OD/USD', _result); +// } } /** diff --git a/script/postdeployment/MockSetupPostEnvironment.s.sol b/script/postdeployment/MockSetupPostEnvironment.s.sol index c7bd4b1..f31bf15 100644 --- a/script/postdeployment/MockSetupPostEnvironment.s.sol +++ b/script/postdeployment/MockSetupPostEnvironment.s.sol @@ -4,8 +4,6 @@ pragma solidity 0.7.6; import 'forge-std/console2.sol'; import '@script/Registry.s.sol'; import {CommonSepolia} from '@script/Common.s.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; @@ -27,7 +25,6 @@ interface ODProxy { // source .env && forge script MockSetupPostEnvironment --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC contract MockSetupPostEnvironment is CommonSepolia { - IAlgebraFactory public algebraFactory = IAlgebraFactory(SEPOLIA_ALGEBRA_FACTORY); MintableERC20 public mockWeth; MintableERC20 public mockWsteth = MintableERC20(0x5Ae92E2cBce39b74f149B7dA16d863382397d4a7); address public systemCoinOracle; @@ -38,29 +35,11 @@ contract MockSetupPostEnvironment is CommonSepolia { // deploy mock WETH token mockWeth = new MintableERC20('Wrapped ETH', 'WETH', 18); - // create OD / WETH pool - algebraFactory.createPool(SEPOLIA_SYSTEM_COIN, address(mockWeth)); - address _pool = algebraFactory.poolByPair(SEPOLIA_SYSTEM_COIN, address(mockWeth)); - - // calculate Q64.96 - uint160 _sqrtPriceX96 = initialPrice(INIT_OD_AMOUNT, INIT_WETH_AMOUNT, _pool); - console2.logUint(_sqrtPriceX96); - - // initialize camelot pool price - IAlgebraPool(_pool).initialize(_sqrtPriceX96); - - // deploy camelotRelayer - IBaseOracle _odWethOracle = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, SEPOLIA_SYSTEM_COIN, address(mockWeth), uint32(ORACLE_INTERVAL_TEST) - ); - // deploy chainlinkRelayer IBaseOracle chainlinkEthUSDPriceFeed = chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); - // deploy systemOracle - systemCoinOracle = - address(denominatedOracleFactory.deployDenominatedOracle(_odWethOracle, chainlinkEthUSDPriceFeed, false)); + // system coin oracle was deployed here // add authorizations authOnlyFactories(); @@ -74,11 +53,11 @@ contract MockSetupPostEnvironment is CommonSepolia { mintSystemCoin(); // deploy Router for AlgebraPool - Router _router = new Router(IAlgebraPool(_pool), deployer); + // Router _router = new Router(IAlgebraPool(_pool), deployer); // approve tokens to Router - IERC20(SEPOLIA_SYSTEM_COIN).approve(address(_router), MINT_AMOUNT); - IERC20(mockWeth).approve(address(_router), MINT_AMOUNT); + // IERC20(SEPOLIA_SYSTEM_COIN).approve(address(_router), MINT_AMOUNT); + // IERC20(mockWeth).approve(address(_router), MINT_AMOUNT); // add liquidity (int24 bottomTick, int24 topTick) = generateTickParams(IAlgebraPool(_pool)); diff --git a/script/postdeployment/SetupPostEnvironment.s.sol b/script/postdeployment/SetupPostEnvironment.s.sol index 73f10bd..43b3ace 100644 --- a/script/postdeployment/SetupPostEnvironment.s.sol +++ b/script/postdeployment/SetupPostEnvironment.s.sol @@ -4,8 +4,6 @@ pragma solidity 0.7.6; import 'forge-std/console2.sol'; import '@script/Registry.s.sol'; import {CommonSepolia} from '@script/Common.s.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; @@ -21,23 +19,23 @@ contract SetupPostEnvironment is CommonSepolia { function run() public { vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK')); - algebraFactory.createPool(SEPOLIA_SYSTEM_COIN, SEPOLIA_WETH); - address _pool = algebraFactory.poolByPair(SEPOLIA_SYSTEM_COIN, SEPOLIA_WETH); + // algebraFactory.createPool(SEPOLIA_SYSTEM_COIN, SEPOLIA_WETH); + // address _pool = algebraFactory.poolByPair(SEPOLIA_SYSTEM_COIN, SEPOLIA_WETH); - uint160 _sqrtPriceX96 = initialPrice(INIT_OD_AMOUNT, INIT_WETH_AMOUNT, _pool); - IAlgebraPool(_pool).initialize(uint160(_sqrtPriceX96)); + // uint160 _sqrtPriceX96 = initialPrice(INIT_OD_AMOUNT, INIT_WETH_AMOUNT, _pool); + // IAlgebraPool(_pool).initialize(uint160(_sqrtPriceX96)); - IBaseOracle _odWethOracle = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, SEPOLIA_SYSTEM_COIN, SEPOLIA_WETH, uint32(ORACLE_INTERVAL_TEST) - ); + // IBaseOracle _odWethOracle = camelotRelayerFactory.deployAlgebraRelayer( + // SEPOLIA_ALGEBRA_FACTORY, SEPOLIA_SYSTEM_COIN, SEPOLIA_WETH, uint32(ORACLE_INTERVAL_TEST) + // ); - IBaseOracle chainlinkEthUSDPriceFeed = - chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); + // IBaseOracle chainlinkEthUSDPriceFeed = + // chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); - // deploy systemOracle - denominatedOracleFactory.deployDenominatedOracle(_odWethOracle, chainlinkEthUSDPriceFeed, false); + // // deploy systemOracle + // denominatedOracleFactory.deployDenominatedOracle(_odWethOracle, chainlinkEthUSDPriceFeed, false); - revokeFactories(); + // revokeFactories(); /** * note oracleRelayer will be set to systemOracle in odContracts post deploy script diff --git a/script/predeployment/DeployRelayers.s.sol b/script/predeployment/DeployRelayers.s.sol index 999c98b..dd191c1 100644 --- a/script/predeployment/DeployRelayers.s.sol +++ b/script/predeployment/DeployRelayers.s.sol @@ -3,49 +3,9 @@ pragma solidity 0.7.6; import '@script/Registry.s.sol'; import {CommonMainnet} from '@script/Common.s.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IDelayedOracleFactory} from '@interfaces/factories/IDelayedOracleFactory.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; -// BROADCAST -// source .env && forge script DeployODGCamelotRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY - -// SIMULATE -// source .env && forge script DeployODGCamelotRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC - -contract DeployODGCamelotRelayerMainnet is CommonMainnet { - IAlgebraFactory public algebraFactory = IAlgebraFactory(MAINNET_ALGEBRA_FACTORY); - - function run() public { - vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); - camelotRelayerFactory.deployAlgebraRelayer( - MAINNET_ALGEBRA_FACTORY, MAINNET_PROTOCOL_TOKEN, MAINNET_WETH, uint32(MAINNET_ORACLE_DELAY) - ); - vm.stopBroadcast(); - } -} - -// BROADCAST -// source .env && forge script DeployOdgUsdRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY - -// SIMULATE -// source .env && forge script DeployOdgUsdRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC - -contract DeployOdgUsdRelayerMainnet is CommonMainnet { - IAlgebraFactory public algebraFactory = IAlgebraFactory(MAINNET_ALGEBRA_FACTORY); - - function run() public { - vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); - IBaseOracle _odgUsdOracle = denominatedOracleFactory.deployDenominatedOracle( - IBaseOracle(MAINNET_CAMELOT_ODG_WETH_RELAYER), IBaseOracle(MAINNET_CHAINLINK_ETH_USD_RELAYER), false - ); - - _odgUsdOracle.symbol(); // "(ODG / WETH) * (ETH / USD)" - vm.stopBroadcast(); - } -} - // BROADCAST // source .env && forge script DeployEthUsdChainlinkRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY @@ -53,8 +13,6 @@ contract DeployOdgUsdRelayerMainnet is CommonMainnet { // source .env && forge script DeployEthUsdChainlinkRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC contract DeployEthUsdChainlinkRelayerMainnet is CommonMainnet { - IAlgebraFactory public algebraFactory = IAlgebraFactory(MAINNET_ALGEBRA_FACTORY); - function run() public { vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); chainlinkRelayerFactory.deployChainlinkRelayer(MAINNET_CHAINLINK_ETH_USD_FEED, MAINNET_ORACLE_DELAY); @@ -69,8 +27,6 @@ contract DeployEthUsdChainlinkRelayerMainnet is CommonMainnet { // source .env && forge script DeployRethEthChainlinkRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC contract DeployRethEthChainlinkRelayerMainnet is CommonMainnet { - IAlgebraFactory public algebraFactory = IAlgebraFactory(MAINNET_ALGEBRA_FACTORY); - function run() public { vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); IBaseOracle _chainlinkRethEthPriceFeed = @@ -92,8 +48,6 @@ contract DeployRethEthChainlinkRelayerMainnet is CommonMainnet { // source .env && forge script DeployWstethEthChainlinkRelayerMainnet --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC contract DeployWstethEthChainlinkRelayerMainnet is CommonMainnet { - IAlgebraFactory public algebraFactory = IAlgebraFactory(MAINNET_ALGEBRA_FACTORY); - function run() public { vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); IBaseOracle _chainlinkWstethEthPriceFeed = diff --git a/src/contracts/factories/CamelotRelayerChild.sol b/src/contracts/factories/CamelotRelayerChild.sol deleted file mode 100644 index 927d229..0000000 --- a/src/contracts/factories/CamelotRelayerChild.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import {CamelotRelayer} from '@contracts/oracles/CamelotRelayer.sol'; -import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; - -contract CamelotRelayerChild is CamelotRelayer, FactoryChild { - // --- Init --- - constructor( - address _algebraV3Factory, - address _baseToken, - address _quoteToken, - uint32 _quotePeriod - ) CamelotRelayer(_algebraV3Factory, _baseToken, _quoteToken, _quotePeriod) {} -} diff --git a/src/contracts/factories/CamelotRelayerFactory.sol b/src/contracts/factories/CamelotRelayerFactory.sol deleted file mode 100644 index 06e6c70..0000000 --- a/src/contracts/factories/CamelotRelayerFactory.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; -import {CamelotRelayerChild} from '@contracts/factories/CamelotRelayerChild.sol'; -import {Authorizable} from '@contracts/utils/Authorizable.sol'; - -contract CamelotRelayerFactory is Authorizable { - uint256 public relayerId; - - // --- Events --- - event NewAlgebraRelayer(address indexed _relayer, address _baseToken, address _quoteToken, uint32 _quotePeriod); - - // --- Data --- - mapping(uint256 => address) public relayerById; - - // --- Init --- - constructor() Authorizable(msg.sender) {} - - // --- Methods --- - - function deployAlgebraRelayer( - address _algebraV3Factory, - address _baseToken, - address _quoteToken, - uint32 _quotePeriod - ) external isAuthorized returns (IBaseOracle _relayer) { - _relayer = IBaseOracle(address(new CamelotRelayerChild(_algebraV3Factory, _baseToken, _quoteToken, _quotePeriod))); - relayerId++; - relayerById[relayerId] = address(_relayer); - emit NewAlgebraRelayer(address(_relayer), _baseToken, _quoteToken, _quotePeriod); - } -} diff --git a/src/contracts/for-test/Data.sol b/src/contracts/for-test/Data.sol index aa1e519..8b984c5 100644 --- a/src/contracts/for-test/Data.sol +++ b/src/contracts/for-test/Data.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.7.6; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {IChainlinkRelayerFactory} from '@interfaces/factories/IChainlinkRelayerFactory.sol'; import {ICamelotRelayerFactory} from '@interfaces/factories/ICamelotRelayerFactory.sol'; @@ -15,55 +14,38 @@ contract Data { address public tokenA; address public tokenB; - // Pool - IAlgebraPool public pool; // Factories IChainlinkRelayerFactory public chainlinkRelayerFactory; - ICamelotRelayerFactory public camelotRelayerFactory; IDenominatedOracleFactory public denominatedOracleFactory; // Relayers IChainlinkRelayer public chainlinkRelayer; - ICamelotRelayer public camelotRelayer; IDenominatedOracle public denominatedOracle; +} - function getPoolBal() public view returns (uint256, uint256) { - (address t0, address t1) = getPoolPair(); - address poolAddress = address(pool); - return (IERC20(t0).balanceOf(poolAddress), IERC20(t1).balanceOf(poolAddress)); - } - - function getPoolPair() public view returns (address, address) { - return (pool.token0(), pool.token1()); - } - - function generateTickParams() public view returns (int24 bottomTick, int24 topTick) { - (, int24 tick,,,,,) = pool.globalState(); - int24 tickSpacing = pool.tickSpacing(); - bottomTick = ((tick / tickSpacing) * tickSpacing) - 3 * tickSpacing; - topTick = ((tick / tickSpacing) * tickSpacing) + 3 * tickSpacing; - } + // function generateTickParams() public view returns (int24 bottomTick, int24 topTick) { + // (, int24 tick,,,,,) = pool.globalState(); + // int24 tickSpacing = pool.tickSpacing(); + // bottomTick = ((tick / tickSpacing) * tickSpacing) - 3 * tickSpacing; + // topTick = ((tick / tickSpacing) * tickSpacing) + 3 * tickSpacing; + // } function setTokens(address _t0, address _t1) public { tokenA = _t0; tokenB = _t1; } - function setPool(IAlgebraPool _pool) public { - pool = _pool; - } + function modifyFactory(bytes32 _param, address _factory) public { if (_param == 'chainlinkRelayerFactory') chainlinkRelayerFactory = IChainlinkRelayerFactory(_factory); - else if (_param == 'camelotRelayerFactory') camelotRelayerFactory = ICamelotRelayerFactory(_factory); else if (_param == 'denominatedOracleFactory') denominatedOracleFactory = IDenominatedOracleFactory(_factory); else revert('Factory not set'); } function modifyOracle(bytes32 _param, address _oracle) public { if (_param == 'chainlinkRelayer') chainlinkRelayer = IChainlinkRelayer(_oracle); - else if (_param == 'camelotRelayer') camelotRelayer = ICamelotRelayer(_oracle); else if (_param == 'denominatedOracle') denominatedOracle = IDenominatedOracle(_oracle); else revert('Oracle not set'); } diff --git a/src/contracts/for-test/MintableERC20.sol b/src/contracts/for-test/MintableERC20.sol index abd7117..a122aaf 100644 --- a/src/contracts/for-test/MintableERC20.sol +++ b/src/contracts/for-test/MintableERC20.sol @@ -2,7 +2,6 @@ pragma solidity 0.7.6; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; -import {IERC20Metadata} from '@algebra-periphery/interfaces/IERC20Metadata.sol'; /** * @title MintableERC20 diff --git a/src/interfaces/factories/ICamelotRelayerFactory.sol b/src/interfaces/factories/ICamelotRelayerFactory.sol deleted file mode 100644 index 913d8c7..0000000 --- a/src/interfaces/factories/ICamelotRelayerFactory.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; - -interface ICamelotRelayerFactory { - // --- Events --- - event NewAlgebraRelayer(address indexed _relayer, address _baseToken, address _quoteToken, uint32 _quotePeriod); - - function deployAlgebraRelayer( - address _algebraV3Factory, - address _baseToken, - address _quoteToken, - uint32 _quotePeriod - ) external returns (IBaseOracle _relayer); -} diff --git a/src/interfaces/oracles/ICamelotRelayer.sol b/src/interfaces/oracles/ICamelotRelayer.sol deleted file mode 100644 index 1bc63a0..0000000 --- a/src/interfaces/oracles/ICamelotRelayer.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; - -interface ICamelotRelayer is IBaseOracle { - /** - * @dev Address of the AlgebraPair used to consult the TWAP - */ - function algebraPool() external view returns (address _algebraPool); - - /** - * @dev Address of the base token used to consult the quote - */ - function baseToken() external view returns (address _baseToken); - - /** - * @dev Address of the token used as a quote reference - */ - function quoteToken() external view returns (address _quoteToken); - - /** - * @dev The amount in wei of the base token used to consult the pool for a quote - */ - function baseAmount() external view returns (uint128 _baseAmount); - - /** - * @dev The multiplier used to convert the quote into an 18 decimals format - */ - function multiplier() external view returns (int256 _multiplier); - - /** - * @dev The length of the TWAP used to consult the pool - */ - function quotePeriod() external view returns (uint32 _quotePeriod); -} diff --git a/test/unit/RelayerFactories.t.sol b/test/unit/RelayerFactories.t.sol index 7536e87..548ba88 100644 --- a/test/unit/RelayerFactories.t.sol +++ b/test/unit/RelayerFactories.t.sol @@ -4,11 +4,6 @@ pragma abicoder v2; import '@script/Registry.s.sol'; import {DSTestPlus} from '@test/utils/DSTestPlus.t.sol'; -import {IERC20Metadata} from '@algebra-periphery/interfaces/IERC20Metadata.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; -import {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; -import {CamelotRelayerChild} from '@contracts/factories/CamelotRelayerChild.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {ChainlinkRelayerChild} from '@contracts/factories/ChainlinkRelayerChild.sol'; import {PendleRelayerFactory} from '@contracts/factories/pendle/PendleRelayerFactory.sol'; @@ -27,14 +22,9 @@ abstract contract Base is DSTestPlus { address authorizedAccount = label('authorizedAccount'); address user = label('user'); - IAlgebraFactory mockAlgebraFactory = IAlgebraFactory(mockContract(SEPOLIA_ALGEBRA_FACTORY, 'UniswapV3Factory')); - IAlgebraPool mockAlgebraPool = IAlgebraPool(mockContract('UniswapV3Pool')); IERC20Metadata mockBaseToken = IERC20Metadata(mockContract('BaseToken')); IERC20Metadata mockQuoteToken = IERC20Metadata(mockContract('QuoteToken')); - CamelotRelayerFactory camelotRelayerFactory; - IBaseOracle camelotRelayerChild; - ChainlinkRelayerFactory chainlinkRelayerFactory; IBaseOracle chainlinkRelayerChild; @@ -48,12 +38,6 @@ abstract contract Base is DSTestPlus { function setUp() public virtual { vm.startPrank(deployer); - - camelotRelayerFactory = new CamelotRelayerFactory(); - label(address(camelotRelayerFactory), 'CamelotRelayerFactory'); - - camelotRelayerFactory.addAuthorization(authorizedAccount); - chainlinkRelayerFactory = new ChainlinkRelayerFactory(); label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); @@ -67,22 +51,6 @@ abstract contract Base is DSTestPlus { vm.stopPrank(); } - function _mockGetPool(address _baseToken, address _quoteToken, address _algebraPool) internal { - vm.mockCall( - address(mockAlgebraFactory), - abi.encodeWithSignature('poolByPair(address,address)', _baseToken, _quoteToken), - abi.encode(_algebraPool) - ); - } - - function _mockToken0(address _token0) internal { - vm.mockCall(address(mockAlgebraPool), abi.encodeWithSignature('token0()'), abi.encode(_token0)); - } - - function _mockToken1(address _token1) internal { - vm.mockCall(address(mockAlgebraPool), abi.encodeWithSignature('token1()'), abi.encode(_token1)); - } - function _mockSymbol(string memory _symbol) internal { vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); @@ -96,111 +64,6 @@ abstract contract Base is DSTestPlus { } } -contract Unit_CamelotRelayerFactory_Constructor is Base { - event AddAuthorization(address _account); - - modifier happyPath() { - vm.startPrank(user); - _; - } - - function test_Emit_AddAuthorization() public happyPath { - vm.expectEmit(); - emit AddAuthorization(user); - - camelotRelayerFactory = new CamelotRelayerFactory(); - } -} - -contract Unit_RelayerFactory_DeployCamelotRelayer is Base { - event NewAlgebraRelayer(address indexed _relayer, address _baseToken, address _quoteToken, uint32 _quotePeriod); - - address algebraRelayer = 0x7F85e9e000597158AED9320B5A5E11AB8cC7329A; - - modifier happyPath(string memory _symbol, uint8 _decimals) { - vm.startPrank(authorizedAccount); - _assumeHappyPath(_decimals); - _mockValues(_symbol, _decimals); - _; - } - - function _assumeHappyPath(uint8 _decimals) internal pure { - vm.assume(_decimals <= 18); - } - - function _mockValues(string memory _symbol, uint8 _decimals) internal { - _mockGetPool(address(mockBaseToken), address(mockQuoteToken), address(mockAlgebraPool)); - _mockToken0(address(mockBaseToken)); - _mockToken1(address(mockQuoteToken)); - _mockSymbol(_symbol); - _mockDecimals(_decimals); - } - - function test_Revert_Unauthorized(uint32 _quotePeriod) public { - vm.expectRevert('Unauthorized'); - - camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, address(mockBaseToken), address(mockQuoteToken), _quotePeriod - ); - } - - function test_Deploy_RelayerChild( - uint32 _quotePeriod, - string memory _symbol, - uint8 _decimals - ) public happyPath(_symbol, _decimals) { - vm.expectEmit(); - emit NewAlgebraRelayer(address(algebraRelayer), address(mockBaseToken), address(mockQuoteToken), _quotePeriod); - camelotRelayerChild = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, address(mockBaseToken), address(mockQuoteToken), _quotePeriod - ); - - string memory concatSymbol = string(abi.encodePacked(_symbol, ' / ', _symbol)); - // params - assertEq(camelotRelayerChild.symbol(), concatSymbol); - } - - function test_Set_Relayers( - uint32 _quotePeriod, - string memory _symbol, - uint8 _decimals - ) public happyPath(_symbol, _decimals) { - camelotRelayerChild = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, address(mockBaseToken), address(mockQuoteToken), _quotePeriod - ); - - assertEq(camelotRelayerFactory.relayerById(1), address(camelotRelayerChild)); - } - - function test_Emit_NewRelayer( - uint32 _quotePeriod, - string memory _symbol, - uint8 _decimals - ) public happyPath(_symbol, _decimals) { - vm.expectEmit(); - emit NewAlgebraRelayer(address(algebraRelayer), address(mockBaseToken), address(mockQuoteToken), _quotePeriod); - - camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, address(mockBaseToken), address(mockQuoteToken), _quotePeriod - ); - } - - function test_Return_Relayer( - uint32 _quotePeriod, - string memory _symbol, - uint8 _decimals - ) public happyPath(_symbol, _decimals) { - assertEq( - address( - camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, address(mockBaseToken), address(mockQuoteToken), _quotePeriod - ) - ), - address(algebraRelayer) - ); - } -} - contract Unit_ChainlinkRelayerFactory_Constructor is Base { event AddAuthorization(address _account); @@ -334,11 +197,7 @@ contract Unit_DenominatedPriceOracleFactory_DeployDenominatedOracle is Base { chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, 100); _mockToken0(address(mockBaseToken)); _mockToken1(address(mockQuoteToken)); - _mockGetPool(address(mockBaseToken), address(mockQuoteToken), address(mockAlgebraPool)); - camelotRelayerChild = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, address(mockBaseToken), address(mockQuoteToken), 1000 - ); vm.stopPrank(); } @@ -401,7 +260,7 @@ contract Unit_Pendle_Renzo_Deploy_Oracle is Base { delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); - pendleFactory = IPendleRelayerFactory(address(new PendleRelayerFactory())); + pendleFactory = IPendleRelayerFactory(address(new PendleRelayerFactory())); label(address(delayedOracleFactory), 'DelayedOracleFactory'); label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); @@ -425,7 +284,6 @@ contract Unit_Pendle_Renzo_Deploy_Oracle is Base { string memory _ezEthSymbol = _ezEthUsdDelayedOracle.symbol(); // "(EZETH / ETH) * (ETH / USD)" vm.stopPrank(); assertEq(_ezEthSymbol, '(ezETH / ETH) * (ETH / USD)'); - } function test_Deploy_PendleFactory() public { @@ -433,7 +291,6 @@ contract Unit_Pendle_Renzo_Deploy_Oracle is Base { assertEq(pendleFactory.authorizedAccounts()[0], address(this)); } - function test_Deploy_PT_Oracle() public { IBaseOracle ptOracle = pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); From 463b9073e6a04ac78f19d63efe5cf6bfa0f77fb1 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 18:58:13 -0500 Subject: [PATCH 02/11] updated openzeppelin and got contracts compiling --- lib/forge-std | 2 +- lib/openzeppelin-contracts | 2 +- script/Common.s.sol | 2 +- script/DeployOracle.s.sol | 10 +- script/Registry.s.sol | 3 +- script/dexrelayer/DeployDataLog.s.sol | 2 +- script/dexrelayer/DeployOracleFactories.s.sol | 2 +- script/dexrelayer/DeployOracles.s.sol | 22 +- script/dexrelayer/DeployPendleFactory.s.sol | 6 +- script/dexrelayer/GetPrice.s.sol | 2 +- script/dexrelayer/Read.s.sol | 78 +-- .../MockSetupPostEnvironment.s.sol | 199 +++--- .../postdeployment/SetupPostEnvironment.s.sol | 4 +- script/predeployment/DeployFactories.s.sol | 8 +- script/predeployment/DeployRelayers.s.sol | 2 +- .../factories/ChainlinkRelayerChild.sol | 2 +- .../ChainlinkRelayerChildWithL2Validity.sol | 2 +- .../factories/ChainlinkRelayerFactory.sol | 2 +- .../factories/DenominatedOracleChild.sol | 2 +- .../factories/DenominatedOracleFactory.sol | 2 +- src/contracts/factories/FactoryChild.sol | 2 +- .../pendle/PendleLpToSyRelayerChild.sol | 2 +- .../pendle/PendlePtToSyRelayerChild.sol | 2 +- .../factories/pendle/PendleRelayerFactory.sol | 2 +- .../pendle/PendleYtToSyRelayerChild.sol | 2 +- src/contracts/for-test/Data.sol | 8 +- src/contracts/for-test/MintableERC20.sol | 2 +- src/contracts/for-test/MockSequencerFeed.sol | 2 +- src/contracts/for-test/Router.sol | 34 - src/contracts/oracles/CamelotRelayer.sol | 90 --- src/contracts/oracles/ChainlinkRelayer.sol | 2 +- .../ChainlinkRelayerWithL2Validity.sol | 2 +- .../oracles/DataConsumerSequencerCheck.sol | 2 +- src/contracts/oracles/DenominatedOracle.sol | 2 +- .../oracles/pendle/PendleLpToSyRelayer.sol | 2 +- .../oracles/pendle/PendlePtToSyRelayer.sol | 2 +- .../oracles/pendle/PendleYtToSyRelayer.sol | 4 +- src/contracts/utils/Authorizable.sol | 4 +- .../factories/IChainlinkRelayerFactory.sol | 2 +- .../factories/IDelayedOracleFactory.sol | 2 +- .../factories/IDenominatedOracleFactory.sol | 2 +- .../factories/IPendleRelayerFactory.sol | 2 +- src/interfaces/oracles/IBaseOracle.sol | 2 +- src/interfaces/oracles/IChainlinkOracle.sol | 2 +- src/interfaces/oracles/IChainlinkRelayer.sol | 2 +- src/interfaces/oracles/IDelayedOracle.sol | 2 +- src/interfaces/oracles/IDenominatedOracle.sol | 2 +- src/interfaces/oracles/pendle/IPMarket.sol | 2 +- src/interfaces/oracles/pendle/IPOracle.sol | 2 +- .../oracles/pendle/IPPrincipalToken.sol | 2 +- .../oracles/pendle/IPYieldToken.sol | 2 +- .../oracles/pendle/IPendleRelayer.sol | 2 +- .../oracles/pendle/IStandardizedYield.sol | 2 +- src/interfaces/utils/IAuthorizable.sol | 2 +- src/interfaces/utils/IERC20Metadata.sol | 2 +- src/libraries/Math.sol | 2 +- test/QMath.t.sol | 142 ++-- test/e2e/SystemOracle.s.sol | 493 +++++++------ test/unit/RelayerFactories.t.sol | 655 +++++++++--------- test/utils/Create2Address.sol | 2 +- test/utils/DSTestPlus.t.sol | 2 +- 61 files changed, 837 insertions(+), 1013 deletions(-) delete mode 100644 src/contracts/for-test/Router.sol delete mode 100644 src/contracts/oracles/CamelotRelayer.sol diff --git a/lib/forge-std b/lib/forge-std index 2f11269..3d8086d 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 2f112697506eab12d433a65fdc31a639548fe365 +Subproject commit 3d8086d4911b36c1874531ce8c367e6cfd028e80 diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts index fa64a1c..b73bcb2 160000 --- a/lib/openzeppelin-contracts +++ b/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit fa64a1ced0b70ab89073d5d0b6e01b0778f7e7d6 +Subproject commit b73bcb231fb6f5e7bc973edc75ab7f6c812a2255 diff --git a/script/Common.s.sol b/script/Common.s.sol index dc46f27..2181d28 100644 --- a/script/Common.s.sol +++ b/script/Common.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; diff --git a/script/DeployOracle.s.sol b/script/DeployOracle.s.sol index aeab6ce..554d901 100644 --- a/script/DeployOracle.s.sol +++ b/script/DeployOracle.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; @@ -86,10 +86,10 @@ contract DeployRethPtToSyPendleRelayerMainnet is CommonMainnet { _pendleRethPtToSyFeed, IBaseOracle(MAINNET_DENOMINATED_RETH_USD_ORACLE), false ); - IBaseOracle __rethToUSDOracleDelayedOracle = - delayedOracleFactory.deployDelayedOracle(_wstethyToUSDOracle, MAINNET_ORACLE_DELAY); + IBaseOracle _rethToUSDOracleDelayedOracle = + delayedOracleFactory.deployDelayedOracle(_rethToUSDOracle, MAINNET_ORACLE_DELAY); - __rethToUSDOracleDelayedOracle.symbol(); + _rethToUSDOracleDelayedOracle.symbol(); vm.stopBroadcast(); } } @@ -108,7 +108,7 @@ contract DeployWstethPtToSyPendleRelayerMainnet is CommonMainnet { ); IBaseOracle _wstethToUSDOracle = denominatedOracleFactory.deployDenominatedOracle( - _pendleRethPtToSyFeed, IBaseOracle(MAINNET_DENOMINATED_WSTETH_USD_ORACLE), false + _pendleWstethPtToSyFeed, IBaseOracle(MAINNET_DENOMINATED_WSTETH_USD_ORACLE), false ); IBaseOracle _wstethToUSDDelayedOracle = diff --git a/script/Registry.s.sol b/script/Registry.s.sol index f35267a..491dd66 100644 --- a/script/Registry.s.sol +++ b/script/Registry.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; uint256 constant WAD = 1e18; @@ -103,3 +103,4 @@ uint32 constant MAINNET_PENDLE_TWAP_DURATION = 900; address constant MAINNET_PENDLE_ORACLE = 0x9a9Fa8338dd5E5B2188006f1Cd2Ef26d921650C2; address constant MAINNET_PENDLE_RETH_MARKET = 0x14FbC760eFaF36781cB0eb3Cb255aD976117B9Bd; address constant MAINNET_PENDLE_WSTETH_MARKET = 0x08a152834de126d2ef83D612ff36e4523FD0017F; +address constant MAINNET_PENDLE_RELAYER_FACTORY = 0x0000000000000000000000000000000000000000; diff --git a/script/dexrelayer/DeployDataLog.s.sol b/script/dexrelayer/DeployDataLog.s.sol index 352ba5a..ef56040 100644 --- a/script/dexrelayer/DeployDataLog.s.sol +++ b/script/dexrelayer/DeployDataLog.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import '@script/Registry.s.sol'; diff --git a/script/dexrelayer/DeployOracleFactories.s.sol b/script/dexrelayer/DeployOracleFactories.s.sol index 578cf04..2438abf 100644 --- a/script/dexrelayer/DeployOracleFactories.s.sol +++ b/script/dexrelayer/DeployOracleFactories.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; diff --git a/script/dexrelayer/DeployOracles.s.sol b/script/dexrelayer/DeployOracles.s.sol index 689989d..f658fc4 100644 --- a/script/dexrelayer/DeployOracles.s.sol +++ b/script/dexrelayer/DeployOracles.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; @@ -29,18 +29,18 @@ contract DeployOracles is Script { function run() public { vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); - chainlinkRelayerFactory = data.chainlinkRelayerFactory(); - denominatedOracleFactory = data.denominatedOracleFactory(); + // chainlinkRelayerFactory = data.chainlinkRelayerFactory(); + // denominatedOracleFactory = data.denominatedOracleFactory(); - // deploy chainlink relayer - chainlinkEthUSDPriceFeed = - chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); - data.modifyOracle(bytes32('chainlinkRelayer'), address(chainlinkEthUSDPriceFeed)); + // // deploy chainlink relayer + // chainlinkEthUSDPriceFeed = + // chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); + // data.modifyOracle(bytes32('chainlinkRelayer'), address(chainlinkEthUSDPriceFeed)); - // deploy denominated oracle - denominatedOracle = - denominatedOracleFactory.deployDenominatedOracle(chainlinkEthUSDPriceFeed, camelotRelayer, false); - data.modifyOracle(bytes32('denominatedOracle'), address(denominatedOracle)); + // // deploy denominated oracle + // denominatedOracle = + // denominatedOracleFactory.deployDenominatedOracle(chainlinkEthUSDPriceFeed, camelotRelayer, false); + // data.modifyOracle(bytes32('denominatedOracle'), address(denominatedOracle)); vm.stopBroadcast(); } diff --git a/script/dexrelayer/DeployPendleFactory.s.sol b/script/dexrelayer/DeployPendleFactory.s.sol index c791ce3..9abf03b 100644 --- a/script/dexrelayer/DeployPendleFactory.s.sol +++ b/script/dexrelayer/DeployPendleFactory.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; @@ -22,9 +22,7 @@ contract DeployPendleFactory is Script { PendleRelayerFactory public pendleRelayerFactory; function run() public { - - uint256 pk = vm.envUint(); - vm.startBroadcast(pk); + vm.startBroadcast(); pendleRelayerFactory = new PendleRelayerFactory(); vm.stopBroadcast(); } diff --git a/script/dexrelayer/GetPrice.s.sol b/script/dexrelayer/GetPrice.s.sol index 65018bb..4e61a1c 100644 --- a/script/dexrelayer/GetPrice.s.sol +++ b/script/dexrelayer/GetPrice.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import '@script/Registry.s.sol'; diff --git a/script/dexrelayer/Read.s.sol b/script/dexrelayer/Read.s.sol index 0d718dc..db61d8a 100644 --- a/script/dexrelayer/Read.s.sol +++ b/script/dexrelayer/Read.s.sol @@ -1,18 +1,14 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; import {Test} from 'forge-std/Test.sol'; -import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; import {IChainlinkRelayer} from '@interfaces/oracles/IChainlinkRelayer.sol'; -import {ICamelotRelayer} from '@interfaces/oracles/ICamelotRelayer.sol'; import {IDenominatedOracle} from '@interfaces/oracles/IDenominatedOracle.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {Data} from '@contracts/for-test/Data.sol'; -import {DataStorageLibrary} from '@algebra-periphery/libraries/DataStorageLibrary.sol'; // BROADCAST // source .env && forge script Read --skip-simulation --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY @@ -21,48 +17,48 @@ import {DataStorageLibrary} from '@algebra-periphery/libraries/DataStorageLibrar // source .env && forge script Read --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC contract Read is Script, Test { - Data public data = Data(RELAYER_DATA); +// Data public data = Data(RELAYER_DATA); - // Tokens - address public tokenA = data.tokenA(); - address public tokenB = data.tokenB(); +// // Tokens +// address public tokenA = data.tokenA(); +// address public tokenB = data.tokenB(); - // Pool - IAlgebraPool public pool = data.pool(); - uint256 public initPrice = ((INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); +// // Pool +// IAlgebraPool public pool = data.pool(); +// uint256 public initPrice = ((INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); - // Relayers - IBaseOracle public chainlinkRelayer = IBaseOracle(address(data.chainlinkRelayer())); - IBaseOracle public camelotRelayer = IBaseOracle(address(data.camelotRelayer())); - IBaseOracle public denominatedOracle = IBaseOracle(address(data.denominatedOracle())); +// // Relayers +// IBaseOracle public chainlinkRelayer = IBaseOracle(address(data.chainlinkRelayer())); +// IBaseOracle public camelotRelayer = IBaseOracle(address(data.camelotRelayer())); +// IBaseOracle public denominatedOracle = IBaseOracle(address(data.denominatedOracle())); - function run() public { - vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); - readPrice(); - readPriceInverse(); - } +// function run() public { +// vm.startBroadcast(vm.envUint('ARB_SEPOLIA_PK')); +// readPrice(); +// readPriceInverse(); +// } - function readPrice() public { - int24 _arithmeticMeanTick = DataStorageLibrary.consult(address(data.pool()), uint32(ORACLE_INTERVAL_TEST)); - uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ - tick: _arithmeticMeanTick, - baseAmount: 1e18, - baseToken: data.tokenA(), - quoteToken: data.tokenB() - }); - emit log_named_uint('Quote Base A:', _quoteAmount); - } +// function readPrice() public { +// int24 _arithmeticMeanTick = DataStorageLibrary.consult(address(data.pool()), uint32(ORACLE_INTERVAL_TEST)); +// uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ +// tick: _arithmeticMeanTick, +// baseAmount: 1e18, +// baseToken: data.tokenA(), +// quoteToken: data.tokenB() +// }); +// emit log_named_uint('Quote Base A:', _quoteAmount); +// } - function readPriceInverse() public { - int24 _arithmeticMeanTick = DataStorageLibrary.consult(address(data.pool()), uint32(ORACLE_INTERVAL_TEST)); - uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ - tick: _arithmeticMeanTick, - baseAmount: 1e18, - baseToken: data.tokenB(), - quoteToken: data.tokenA() - }); - emit log_named_uint('Quote Base B:', _quoteAmount); - } +// function readPriceInverse() public { +// int24 _arithmeticMeanTick = DataStorageLibrary.consult(address(data.pool()), uint32(ORACLE_INTERVAL_TEST)); +// uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ +// tick: _arithmeticMeanTick, +// baseAmount: 1e18, +// baseToken: data.tokenB(), +// quoteToken: data.tokenA() +// }); +// emit log_named_uint('Quote Base B:', _quoteAmount); +// } } /** diff --git a/script/postdeployment/MockSetupPostEnvironment.s.sol b/script/postdeployment/MockSetupPostEnvironment.s.sol index f31bf15..d74f546 100644 --- a/script/postdeployment/MockSetupPostEnvironment.s.sol +++ b/script/postdeployment/MockSetupPostEnvironment.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import 'forge-std/console2.sol'; import '@script/Registry.s.sol'; @@ -7,7 +7,6 @@ import {CommonSepolia} from '@script/Common.s.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import {Router} from '@contracts/for-test/Router.sol'; interface IVault721 { function getProxy(address _user) external view returns (address); @@ -25,102 +24,102 @@ interface ODProxy { // source .env && forge script MockSetupPostEnvironment --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC contract MockSetupPostEnvironment is CommonSepolia { - MintableERC20 public mockWeth; - MintableERC20 public mockWsteth = MintableERC20(0x5Ae92E2cBce39b74f149B7dA16d863382397d4a7); - address public systemCoinOracle; - - function run() public { - vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK')); - - // deploy mock WETH token - mockWeth = new MintableERC20('Wrapped ETH', 'WETH', 18); - - // deploy chainlinkRelayer - IBaseOracle chainlinkEthUSDPriceFeed = - chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); - - // system coin oracle was deployed here - - // add authorizations - authOnlyFactories(); - - // check pool balance before - IERC20(SEPOLIA_SYSTEM_COIN).balanceOf(_pool); - IERC20(mockWeth).balanceOf(_pool); - - // mint SystemCoin and Weth to use as liquidity - mintMockWeth(); - mintSystemCoin(); - - // deploy Router for AlgebraPool - // Router _router = new Router(IAlgebraPool(_pool), deployer); - - // approve tokens to Router - // IERC20(SEPOLIA_SYSTEM_COIN).approve(address(_router), MINT_AMOUNT); - // IERC20(mockWeth).approve(address(_router), MINT_AMOUNT); - - // add liquidity - (int24 bottomTick, int24 topTick) = generateTickParams(IAlgebraPool(_pool)); - _router.addLiquidity(bottomTick, topTick, uint128(1 ether)); - - // check pool balance after - IERC20(SEPOLIA_SYSTEM_COIN).balanceOf(_pool); - IERC20(mockWeth).balanceOf(_pool); - - // log OD / USD denominated oracle address - console2.logBytes20(bytes20(systemCoinOracle)); - - vm.stopBroadcast(); - } - - function mintMockWeth() public { - mockWeth.mint(deployer, MINT_AMOUNT); - } - - // todo: remove `magic` numbers - refactor - function mintSystemCoin() public { - IVault721 vault721 = IVault721(0xa602c0cFf8028Dd4c99fbC5e85cF0c083C5b991A); - address _safeManager = 0x8ca7D88eaFB6f666997Ca0F62Beddd8A09a62910; - address _basicActions = 0x60487E0a0eFbfbD30908b03ea6b7833E2520604F; - address _coinJoin = 0x93544B224AB94F2b568CaeD5A074f4217fC782c7; - address _collateralJoin_wsteth = 0x52400D3AEB82b0923898D918be51439A9198D980; - - // create proxy for deployer - address _proxy = vault721.getProxy(deployer); - if (_proxy == address(0)) { - _proxy = vault721.build(deployer); - } - - // create safe for deployer - bytes memory _payload = - abi.encodeWithSignature('openSAFE(address,bytes32,address)', _safeManager, bytes32('WSTETH'), _proxy); - bytes memory _safeData = ODProxy(_proxy).execute(_basicActions, _payload); - uint256 _safeId = abi.decode(_safeData, (uint256)); - - // mint token - mockWsteth.mint(deployer, MINT_AMOUNT); - IERC20(mockWsteth).approve(_proxy, MINT_AMOUNT); - - // lock collateral & generate debt - bytes memory payload = abi.encodeWithSignature( - 'lockTokenCollateralAndGenerateDebt(address,address,address,uint256,uint256,uint256)', - _safeManager, - _collateralJoin_wsteth, - _coinJoin, - _safeId, - 850 ether, - 500_000 ether - ); - ODProxy(_proxy).execute(_basicActions, payload); - } - - // find tick and add 10X spacing on either side of pool price - function generateTickParams(IAlgebraPool pool) public view returns (int24 bottomTick, int24 topTick) { - (, int24 tick,,,,,) = pool.globalState(); - int24 tickSpacing = pool.tickSpacing(); - console2.logInt(tick); - console2.logInt(tickSpacing); - bottomTick = ((tick / tickSpacing) * tickSpacing) - 10 * tickSpacing; - topTick = ((tick / tickSpacing) * tickSpacing) + 10 * tickSpacing; - } +// MintableERC20 public mockWeth; +// MintableERC20 public mockWsteth = MintableERC20(0x5Ae92E2cBce39b74f149B7dA16d863382397d4a7); +// address public systemCoinOracle; + +// function run() public { +// vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK')); + +// // deploy mock WETH token +// mockWeth = new MintableERC20('Wrapped ETH', 'WETH', 18); + +// // deploy chainlinkRelayer +// IBaseOracle chainlinkEthUSDPriceFeed = +// chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); + +// // system coin oracle was deployed here + +// // add authorizations +// authOnlyFactories(); + +// // check pool balance before +// IERC20(SEPOLIA_SYSTEM_COIN).balanceOf(_pool); +// IERC20(mockWeth).balanceOf(_pool); + +// // mint SystemCoin and Weth to use as liquidity +// mintMockWeth(); +// mintSystemCoin(); + +// // deploy Router for AlgebraPool +// // Router _router = new Router(IAlgebraPool(_pool), deployer); + +// // approve tokens to Router +// // IERC20(SEPOLIA_SYSTEM_COIN).approve(address(_router), MINT_AMOUNT); +// // IERC20(mockWeth).approve(address(_router), MINT_AMOUNT); + +// // add liquidity +// (int24 bottomTick, int24 topTick) = generateTickParams(IAlgebraPool(_pool)); +// _router.addLiquidity(bottomTick, topTick, uint128(1 ether)); + +// // check pool balance after +// IERC20(SEPOLIA_SYSTEM_COIN).balanceOf(_pool); +// IERC20(mockWeth).balanceOf(_pool); + +// // log OD / USD denominated oracle address +// console2.logBytes20(bytes20(systemCoinOracle)); + +// vm.stopBroadcast(); +// } + +// function mintMockWeth() public { +// mockWeth.mint(deployer, MINT_AMOUNT); +// } + +// // todo: remove `magic` numbers - refactor +// function mintSystemCoin() public { +// IVault721 vault721 = IVault721(0xa602c0cFf8028Dd4c99fbC5e85cF0c083C5b991A); +// address _safeManager = 0x8ca7D88eaFB6f666997Ca0F62Beddd8A09a62910; +// address _basicActions = 0x60487E0a0eFbfbD30908b03ea6b7833E2520604F; +// address _coinJoin = 0x93544B224AB94F2b568CaeD5A074f4217fC782c7; +// address _collateralJoin_wsteth = 0x52400D3AEB82b0923898D918be51439A9198D980; + +// // create proxy for deployer +// address _proxy = vault721.getProxy(deployer); +// if (_proxy == address(0)) { +// _proxy = vault721.build(deployer); +// } + +// // create safe for deployer +// bytes memory _payload = +// abi.encodeWithSignature('openSAFE(address,bytes32,address)', _safeManager, bytes32('WSTETH'), _proxy); +// bytes memory _safeData = ODProxy(_proxy).execute(_basicActions, _payload); +// uint256 _safeId = abi.decode(_safeData, (uint256)); + +// // mint token +// mockWsteth.mint(deployer, MINT_AMOUNT); +// IERC20(mockWsteth).approve(_proxy, MINT_AMOUNT); + +// // lock collateral & generate debt +// bytes memory payload = abi.encodeWithSignature( +// 'lockTokenCollateralAndGenerateDebt(address,address,address,uint256,uint256,uint256)', +// _safeManager, +// _collateralJoin_wsteth, +// _coinJoin, +// _safeId, +// 850 ether, +// 500_000 ether +// ); +// ODProxy(_proxy).execute(_basicActions, payload); +// } + +// find tick and add 10X spacing on either side of pool price +// function generateTickParams(IAlgebraPool pool) public view returns (int24 bottomTick, int24 topTick) { +// (, int24 tick,,,,,) = pool.globalState(); +// int24 tickSpacing = pool.tickSpacing(); +// console2.logInt(tick); +// console2.logInt(tickSpacing); +// bottomTick = ((tick / tickSpacing) * tickSpacing) - 10 * tickSpacing; +// topTick = ((tick / tickSpacing) * tickSpacing) + 10 * tickSpacing; +// } } diff --git a/script/postdeployment/SetupPostEnvironment.s.sol b/script/postdeployment/SetupPostEnvironment.s.sol index 43b3ace..74f2c6a 100644 --- a/script/postdeployment/SetupPostEnvironment.s.sol +++ b/script/postdeployment/SetupPostEnvironment.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import 'forge-std/console2.sol'; import '@script/Registry.s.sol'; @@ -14,7 +14,7 @@ import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; // source .env && forge script SetupPostEnvironment --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC contract SetupPostEnvironment is CommonSepolia { - IAlgebraFactory public algebraFactory = IAlgebraFactory(SEPOLIA_ALGEBRA_FACTORY); + // IAlgebraFactory public algebraFactory = IAlgebraFactory(SEPOLIA_ALGEBRA_FACTORY); function run() public { vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK')); diff --git a/script/predeployment/DeployFactories.s.sol b/script/predeployment/DeployFactories.s.sol index 7f62133..79e4241 100644 --- a/script/predeployment/DeployFactories.s.sol +++ b/script/predeployment/DeployFactories.s.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {Script} from 'forge-std/Script.sol'; -import {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {DenominatedOracleFactory} from '@contracts/factories/DenominatedOracleFactory.sol'; @@ -14,17 +13,14 @@ import {DenominatedOracleFactory} from '@contracts/factories/DenominatedOracleFa // source .env && forge script DeployFactoriesMain --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_MAINNET_RPC contract DeployFactoriesMain is Script { - CamelotRelayerFactory internal _camelotRelayerFactory; ChainlinkRelayerFactory internal _chainlinkRelayerFactory; DenominatedOracleFactory internal _denominatedOracleFactory; function run() public { vm.startBroadcast(vm.envUint('ARB_MAINNET_DEPLOYER_PK')); - _camelotRelayerFactory = new CamelotRelayerFactory(); _chainlinkRelayerFactory = new ChainlinkRelayerFactory(); _denominatedOracleFactory = new DenominatedOracleFactory(); - _camelotRelayerFactory.addAuthorization(MAINNET_DEPLOYER); _chainlinkRelayerFactory.addAuthorization(MAINNET_DEPLOYER); _denominatedOracleFactory.addAuthorization(MAINNET_DEPLOYER); vm.stopBroadcast(); @@ -38,13 +34,11 @@ contract DeployFactoriesMain is Script { // source .env && forge script DeployFactoriesSepolia --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC contract DeployFactoriesSepolia is Script { - CamelotRelayerFactory internal _camelotRelayerFactory; ChainlinkRelayerFactory internal _chainlinkRelayerFactory; DenominatedOracleFactory internal _denominatedOracleFactory; function run() public { vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK')); - _camelotRelayerFactory = new CamelotRelayerFactory(); _chainlinkRelayerFactory = new ChainlinkRelayerFactory(); _denominatedOracleFactory = new DenominatedOracleFactory(); vm.stopBroadcast(); diff --git a/script/predeployment/DeployRelayers.s.sol b/script/predeployment/DeployRelayers.s.sol index dd191c1..f44c6a3 100644 --- a/script/predeployment/DeployRelayers.s.sol +++ b/script/predeployment/DeployRelayers.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@script/Registry.s.sol'; import {CommonMainnet} from '@script/Common.s.sol'; diff --git a/src/contracts/factories/ChainlinkRelayerChild.sol b/src/contracts/factories/ChainlinkRelayerChild.sol index 89302cd..23fa618 100644 --- a/src/contracts/factories/ChainlinkRelayerChild.sol +++ b/src/contracts/factories/ChainlinkRelayerChild.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {ChainlinkRelayer} from '@contracts/oracles/ChainlinkRelayer.sol'; import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; diff --git a/src/contracts/factories/ChainlinkRelayerChildWithL2Validity.sol b/src/contracts/factories/ChainlinkRelayerChildWithL2Validity.sol index e635dd8..66f53a1 100644 --- a/src/contracts/factories/ChainlinkRelayerChildWithL2Validity.sol +++ b/src/contracts/factories/ChainlinkRelayerChildWithL2Validity.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {ChainlinkRelayerWithL2Validity} from '@contracts/oracles/ChainlinkRelayerWithL2Validity.sol'; import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; diff --git a/src/contracts/factories/ChainlinkRelayerFactory.sol b/src/contracts/factories/ChainlinkRelayerFactory.sol index 2612b55..14a0f4e 100644 --- a/src/contracts/factories/ChainlinkRelayerFactory.sol +++ b/src/contracts/factories/ChainlinkRelayerFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {ChainlinkRelayerChild} from '@contracts/factories/ChainlinkRelayerChild.sol'; diff --git a/src/contracts/factories/DenominatedOracleChild.sol b/src/contracts/factories/DenominatedOracleChild.sol index 0900983..59c84a6 100644 --- a/src/contracts/factories/DenominatedOracleChild.sol +++ b/src/contracts/factories/DenominatedOracleChild.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {DenominatedOracle} from '@contracts/oracles/DenominatedOracle.sol'; diff --git a/src/contracts/factories/DenominatedOracleFactory.sol b/src/contracts/factories/DenominatedOracleFactory.sol index 779366e..5f80f12 100644 --- a/src/contracts/factories/DenominatedOracleFactory.sol +++ b/src/contracts/factories/DenominatedOracleFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {DenominatedOracleChild} from '@contracts/factories/DenominatedOracleChild.sol'; diff --git a/src/contracts/factories/FactoryChild.sol b/src/contracts/factories/FactoryChild.sol index ccf5525..caff26e 100644 --- a/src/contracts/factories/FactoryChild.sol +++ b/src/contracts/factories/FactoryChild.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; abstract contract FactoryChild { // --- Registry --- diff --git a/src/contracts/factories/pendle/PendleLpToSyRelayerChild.sol b/src/contracts/factories/pendle/PendleLpToSyRelayerChild.sol index 795e2df..26ca24d 100644 --- a/src/contracts/factories/pendle/PendleLpToSyRelayerChild.sol +++ b/src/contracts/factories/pendle/PendleLpToSyRelayerChild.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {PendleLpToSyRelayer} from '@contracts/oracles/pendle/PendleLpToSyRelayer.sol'; import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; diff --git a/src/contracts/factories/pendle/PendlePtToSyRelayerChild.sol b/src/contracts/factories/pendle/PendlePtToSyRelayerChild.sol index 8ea1274..2839daf 100644 --- a/src/contracts/factories/pendle/PendlePtToSyRelayerChild.sol +++ b/src/contracts/factories/pendle/PendlePtToSyRelayerChild.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {PendlePtToSyRelayer} from '@contracts/oracles/pendle/PendlePtToSyRelayer.sol'; import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; diff --git a/src/contracts/factories/pendle/PendleRelayerFactory.sol b/src/contracts/factories/pendle/PendleRelayerFactory.sol index 06104e3..8d6536c 100644 --- a/src/contracts/factories/pendle/PendleRelayerFactory.sol +++ b/src/contracts/factories/pendle/PendleRelayerFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {PendlePtToSyRelayerChild} from '@contracts/factories/pendle/PendlePtToSyRelayerChild.sol'; diff --git a/src/contracts/factories/pendle/PendleYtToSyRelayerChild.sol b/src/contracts/factories/pendle/PendleYtToSyRelayerChild.sol index 6d83aa3..b357930 100644 --- a/src/contracts/factories/pendle/PendleYtToSyRelayerChild.sol +++ b/src/contracts/factories/pendle/PendleYtToSyRelayerChild.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {PendleYtToSyRelayer} from '@contracts/oracles/pendle/PendleYtToSyRelayer.sol'; import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; diff --git a/src/contracts/for-test/Data.sol b/src/contracts/for-test/Data.sol index 8b984c5..1cb7b43 100644 --- a/src/contracts/for-test/Data.sol +++ b/src/contracts/for-test/Data.sol @@ -1,12 +1,10 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {IChainlinkRelayerFactory} from '@interfaces/factories/IChainlinkRelayerFactory.sol'; -import {ICamelotRelayerFactory} from '@interfaces/factories/ICamelotRelayerFactory.sol'; import {IDenominatedOracleFactory} from '@interfaces/factories/IDenominatedOracleFactory.sol'; import {IChainlinkRelayer} from '@interfaces/oracles/IChainlinkRelayer.sol'; -import {ICamelotRelayer} from '@interfaces/oracles/ICamelotRelayer.sol'; import {IDenominatedOracle} from '@interfaces/oracles/IDenominatedOracle.sol'; contract Data { @@ -14,7 +12,6 @@ contract Data { address public tokenA; address public tokenB; - // Factories IChainlinkRelayerFactory public chainlinkRelayerFactory; IDenominatedOracleFactory public denominatedOracleFactory; @@ -22,7 +19,6 @@ contract Data { // Relayers IChainlinkRelayer public chainlinkRelayer; IDenominatedOracle public denominatedOracle; -} // function generateTickParams() public view returns (int24 bottomTick, int24 topTick) { // (, int24 tick,,,,,) = pool.globalState(); @@ -36,8 +32,6 @@ contract Data { tokenB = _t1; } - - function modifyFactory(bytes32 _param, address _factory) public { if (_param == 'chainlinkRelayerFactory') chainlinkRelayerFactory = IChainlinkRelayerFactory(_factory); else if (_param == 'denominatedOracleFactory') denominatedOracleFactory = IDenominatedOracleFactory(_factory); diff --git a/src/contracts/for-test/MintableERC20.sol b/src/contracts/for-test/MintableERC20.sol index a122aaf..eead8a7 100644 --- a/src/contracts/for-test/MintableERC20.sol +++ b/src/contracts/for-test/MintableERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; diff --git a/src/contracts/for-test/MockSequencerFeed.sol b/src/contracts/for-test/MockSequencerFeed.sol index c49ba01..da46ae0 100644 --- a/src/contracts/for-test/MockSequencerFeed.sol +++ b/src/contracts/for-test/MockSequencerFeed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; contract MockSequencerFeed { uint256 internal constant _ARBITRARY_DATA = 1; diff --git a/src/contracts/for-test/Router.sol b/src/contracts/for-test/Router.sol deleted file mode 100644 index 7355c58..0000000 --- a/src/contracts/for-test/Router.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; -import {IAlgebraMintCallback} from '@algebra-core/interfaces/callback/IAlgebraMintCallback.sol'; -import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; - -contract Router is IAlgebraMintCallback { - IAlgebraPool public pool; - IERC20 public tokenA; - IERC20 public tokenB; - address public owner; - - constructor(IAlgebraPool _pool, address _owner) { - pool = _pool; - owner = _owner; - tokenA = IERC20(_pool.token0()); - tokenB = IERC20(_pool.token1()); - } - - function addLiquidity( - int24 _bottomTick, - int24 _topTick, - uint128 _amount - ) external returns (uint256 amount0, uint256 amount1, uint128 liquidityActual) { - (amount0, amount1, liquidityActual) = pool.mint(owner, address(pool), _bottomTick, _topTick, _amount, ''); - } - - function algebraMintCallback(uint256 amount0Owed, uint256 amount1Owed, bytes calldata) external override { - require(address(pool) == msg.sender, 'Pool not authorized'); - tokenA.transferFrom(owner, address(pool), amount0Owed); - tokenB.transferFrom(owner, address(pool), amount1Owed); - } -} diff --git a/src/contracts/oracles/CamelotRelayer.sol b/src/contracts/oracles/CamelotRelayer.sol deleted file mode 100644 index 0c580e4..0000000 --- a/src/contracts/oracles/CamelotRelayer.sol +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; - -import {IERC20Metadata} from '@algebra-periphery/interfaces/IERC20Metadata.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; -import {IDataStorageOperator} from '@algebra-core/interfaces/IDataStorageOperator.sol'; -import {DataStorageLibrary} from '@algebra-periphery/libraries/DataStorageLibrary.sol'; - -contract CamelotRelayer { - int256 public immutable MULTIPLIER; - uint32 public immutable QUOTE_PERIOD; - uint128 public immutable BASE_AMOUNT; - - // --- Registry --- - address public algebraPool; - address public baseToken; - address public quoteToken; - - // --- Data --- - string public symbol; - - constructor(address _algebraV3Factory, address _baseToken, address _quoteToken, uint32 _quotePeriod) { - algebraPool = IAlgebraFactory(_algebraV3Factory).poolByPair(_baseToken, _quoteToken); - require(algebraPool != address(0)); - - address _token0 = IAlgebraPool(algebraPool).token0(); - address _token1 = IAlgebraPool(algebraPool).token1(); - - // The factory validates that both token0 and token1 are desired baseToken and quoteTokens - if (_token0 == _baseToken) { - baseToken = _token0; - quoteToken = _token1; - } else { - baseToken = _token1; - quoteToken = _token0; - } - - BASE_AMOUNT = uint128(10 ** IERC20Metadata(_baseToken).decimals()); - MULTIPLIER = int256(18) - int256(uint256(IERC20Metadata(_quoteToken).decimals())); - QUOTE_PERIOD = _quotePeriod; - - symbol = string(abi.encodePacked(IERC20Metadata(_baseToken).symbol(), ' / ', IERC20Metadata(_quoteToken).symbol())); - } - - 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(algebraPool, 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); - _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(algebraPool, QUOTE_PERIOD); - uint256 _quoteAmount = DataStorageLibrary.getQuoteAtTick({ - tick: _arithmeticMeanTick, - baseAmount: BASE_AMOUNT, - baseToken: baseToken, - quoteToken: quoteToken - }); - _result = _parseResult(_quoteAmount); - } - - function _parseResult(uint256 _quoteResult) internal view returns (uint256 _result) { - if (MULTIPLIER == 0) { - return _quoteResult; - } else if (MULTIPLIER > 0) { - return _quoteResult * (10 ** uint256(MULTIPLIER)); - } else { - return _quoteResult / (10 ** _abs(MULTIPLIER)); - } - } - - // @notice Return the absolute value of a signed integer as an unsigned integer - function _abs(int256 x) internal pure returns (uint256) { - x >= 0 ? x : -x; - return uint256(x); - } -} diff --git a/src/contracts/oracles/ChainlinkRelayer.sol b/src/contracts/oracles/ChainlinkRelayer.sol index e9c9674..7d8a42b 100644 --- a/src/contracts/oracles/ChainlinkRelayer.sol +++ b/src/contracts/oracles/ChainlinkRelayer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IChainlinkOracle} from '@interfaces/oracles/IChainlinkOracle.sol'; diff --git a/src/contracts/oracles/ChainlinkRelayerWithL2Validity.sol b/src/contracts/oracles/ChainlinkRelayerWithL2Validity.sol index 43149a4..8edeca2 100644 --- a/src/contracts/oracles/ChainlinkRelayerWithL2Validity.sol +++ b/src/contracts/oracles/ChainlinkRelayerWithL2Validity.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {ChainlinkRelayer} from '@contracts/oracles/ChainlinkRelayer.sol'; import {DataConsumerSequencerCheck} from '@contracts/oracles/DataConsumerSequencerCheck.sol'; diff --git a/src/contracts/oracles/DataConsumerSequencerCheck.sol b/src/contracts/oracles/DataConsumerSequencerCheck.sol index 6010f11..cd67ac3 100644 --- a/src/contracts/oracles/DataConsumerSequencerCheck.sol +++ b/src/contracts/oracles/DataConsumerSequencerCheck.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IChainlinkOracle} from '@interfaces/oracles/IChainlinkOracle.sol'; diff --git a/src/contracts/oracles/DenominatedOracle.sol b/src/contracts/oracles/DenominatedOracle.sol index c2b4110..374045f 100644 --- a/src/contracts/oracles/DenominatedOracle.sol +++ b/src/contracts/oracles/DenominatedOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {Math, WAD} from '@libraries/Math.sol'; diff --git a/src/contracts/oracles/pendle/PendleLpToSyRelayer.sol b/src/contracts/oracles/pendle/PendleLpToSyRelayer.sol index de7e55e..0612ee8 100644 --- a/src/contracts/oracles/pendle/PendleLpToSyRelayer.sol +++ b/src/contracts/oracles/pendle/PendleLpToSyRelayer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@interfaces/oracles/pendle/IPOracle.sol'; import '@interfaces/oracles/pendle/IPMarket.sol'; diff --git a/src/contracts/oracles/pendle/PendlePtToSyRelayer.sol b/src/contracts/oracles/pendle/PendlePtToSyRelayer.sol index 7879110..8c883e0 100644 --- a/src/contracts/oracles/pendle/PendlePtToSyRelayer.sol +++ b/src/contracts/oracles/pendle/PendlePtToSyRelayer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@interfaces/oracles/pendle/IPOracle.sol'; import '@interfaces/oracles/pendle/IPMarket.sol'; diff --git a/src/contracts/oracles/pendle/PendleYtToSyRelayer.sol b/src/contracts/oracles/pendle/PendleYtToSyRelayer.sol index e291c8e..7dbccb0 100644 --- a/src/contracts/oracles/pendle/PendleYtToSyRelayer.sol +++ b/src/contracts/oracles/pendle/PendleYtToSyRelayer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import '@interfaces/oracles/pendle/IPOracle.sol'; import '@interfaces/oracles/pendle/IPMarket.sol'; @@ -28,7 +28,7 @@ contract PendleYtToSyRelayer { twapDuration = _twapDuration; (SY,, YT) = market.readTokens(); - + symbol = string(abi.encodePacked(YT.symbol(), ' / ', SY.symbol())); // test if oracle is ready (bool increaseCardinalityRequired,, bool oldestObservationSatisfied) = oracle.getOracleState(_market, _twapDuration); diff --git a/src/contracts/utils/Authorizable.sol b/src/contracts/utils/Authorizable.sol index 2986ce8..4ae0f42 100644 --- a/src/contracts/utils/Authorizable.sol +++ b/src/contracts/utils/Authorizable.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; -import {EnumerableSet} from '@openzeppelin/contracts/utils/EnumerableSet.sol'; +import {EnumerableSet} from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; /** * @title Authorizable diff --git a/src/interfaces/factories/IChainlinkRelayerFactory.sol b/src/interfaces/factories/IChainlinkRelayerFactory.sol index bff5c60..03bebff 100644 --- a/src/interfaces/factories/IChainlinkRelayerFactory.sol +++ b/src/interfaces/factories/IChainlinkRelayerFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; diff --git a/src/interfaces/factories/IDelayedOracleFactory.sol b/src/interfaces/factories/IDelayedOracleFactory.sol index 5943a58..833a36d 100644 --- a/src/interfaces/factories/IDelayedOracleFactory.sol +++ b/src/interfaces/factories/IDelayedOracleFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {IDelayedOracle} from '@interfaces/oracles/IDelayedOracle.sol'; diff --git a/src/interfaces/factories/IDenominatedOracleFactory.sol b/src/interfaces/factories/IDenominatedOracleFactory.sol index c14059c..19a6a7f 100644 --- a/src/interfaces/factories/IDenominatedOracleFactory.sol +++ b/src/interfaces/factories/IDenominatedOracleFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; diff --git a/src/interfaces/factories/IPendleRelayerFactory.sol b/src/interfaces/factories/IPendleRelayerFactory.sol index 44ec165..c75dc1c 100644 --- a/src/interfaces/factories/IPendleRelayerFactory.sol +++ b/src/interfaces/factories/IPendleRelayerFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {IAuthorizable} from '@interfaces/utils/IAuthorizable.sol'; diff --git a/src/interfaces/oracles/IBaseOracle.sol b/src/interfaces/oracles/IBaseOracle.sol index 400ee3e..f52056b 100644 --- a/src/interfaces/oracles/IBaseOracle.sol +++ b/src/interfaces/oracles/IBaseOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; /** * @title IBaseOracle diff --git a/src/interfaces/oracles/IChainlinkOracle.sol b/src/interfaces/oracles/IChainlinkOracle.sol index 8485075..0522c77 100644 --- a/src/interfaces/oracles/IChainlinkOracle.sol +++ b/src/interfaces/oracles/IChainlinkOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; interface IChainlinkOracle { function decimals() external view returns (uint8 _decimals); diff --git a/src/interfaces/oracles/IChainlinkRelayer.sol b/src/interfaces/oracles/IChainlinkRelayer.sol index 818196a..f79870d 100644 --- a/src/interfaces/oracles/IChainlinkRelayer.sol +++ b/src/interfaces/oracles/IChainlinkRelayer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {IChainlinkOracle} from '@interfaces/oracles/IChainlinkOracle.sol'; diff --git a/src/interfaces/oracles/IDelayedOracle.sol b/src/interfaces/oracles/IDelayedOracle.sol index 9da91be..e0eac1d 100644 --- a/src/interfaces/oracles/IDelayedOracle.sol +++ b/src/interfaces/oracles/IDelayedOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; diff --git a/src/interfaces/oracles/IDenominatedOracle.sol b/src/interfaces/oracles/IDenominatedOracle.sol index 91e1377..454bace 100644 --- a/src/interfaces/oracles/IDenominatedOracle.sol +++ b/src/interfaces/oracles/IDenominatedOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; diff --git a/src/interfaces/oracles/pendle/IPMarket.sol b/src/interfaces/oracles/pendle/IPMarket.sol index 707b00e..8c63aaa 100644 --- a/src/interfaces/oracles/pendle/IPMarket.sol +++ b/src/interfaces/oracles/pendle/IPMarket.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IStandardizedYield} from '@interfaces/oracles/pendle/IStandardizedYield.sol'; import {IPPrincipalToken} from '@interfaces/oracles/pendle/IPPrincipalToken.sol'; diff --git a/src/interfaces/oracles/pendle/IPOracle.sol b/src/interfaces/oracles/pendle/IPOracle.sol index e4456fc..ab7e036 100644 --- a/src/interfaces/oracles/pendle/IPOracle.sol +++ b/src/interfaces/oracles/pendle/IPOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; // a minimal interface to interact with Pendle TWAP oracles interface IPOracle { diff --git a/src/interfaces/oracles/pendle/IPPrincipalToken.sol b/src/interfaces/oracles/pendle/IPPrincipalToken.sol index 588525b..cd74e46 100644 --- a/src/interfaces/oracles/pendle/IPPrincipalToken.sol +++ b/src/interfaces/oracles/pendle/IPPrincipalToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IERC20Metadata} from '@interfaces/utils/IERC20Metadata.sol'; diff --git a/src/interfaces/oracles/pendle/IPYieldToken.sol b/src/interfaces/oracles/pendle/IPYieldToken.sol index 47f3ddd..005d9ba 100644 --- a/src/interfaces/oracles/pendle/IPYieldToken.sol +++ b/src/interfaces/oracles/pendle/IPYieldToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IERC20Metadata} from '@interfaces/utils/IERC20Metadata.sol'; diff --git a/src/interfaces/oracles/pendle/IPendleRelayer.sol b/src/interfaces/oracles/pendle/IPendleRelayer.sol index 1968db8..9e78aa4 100644 --- a/src/interfaces/oracles/pendle/IPendleRelayer.sol +++ b/src/interfaces/oracles/pendle/IPendleRelayer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {IPMarket} from '@interfaces/oracles/pendle/IPMarket.sol'; diff --git a/src/interfaces/oracles/pendle/IStandardizedYield.sol b/src/interfaces/oracles/pendle/IStandardizedYield.sol index 599c1f7..d1dcac0 100644 --- a/src/interfaces/oracles/pendle/IStandardizedYield.sol +++ b/src/interfaces/oracles/pendle/IStandardizedYield.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IERC20Metadata} from '@interfaces/utils/IERC20Metadata.sol'; diff --git a/src/interfaces/utils/IAuthorizable.sol b/src/interfaces/utils/IAuthorizable.sol index f74d824..0115034 100644 --- a/src/interfaces/utils/IAuthorizable.sol +++ b/src/interfaces/utils/IAuthorizable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; interface IAuthorizable { // --- Data --- diff --git a/src/interfaces/utils/IERC20Metadata.sol b/src/interfaces/utils/IERC20Metadata.sol index 01a2793..ea5eff4 100644 --- a/src/interfaces/utils/IERC20Metadata.sol +++ b/src/interfaces/utils/IERC20Metadata.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.6; +pragma solidity ^0.8.20; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; diff --git a/src/libraries/Math.sol b/src/libraries/Math.sol index 96e5dc8..9947e6d 100644 --- a/src/libraries/Math.sol +++ b/src/libraries/Math.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; uint256 constant WAD = 1e18; diff --git a/test/QMath.t.sol b/test/QMath.t.sol index b6a0241..75d0cf7 100644 --- a/test/QMath.t.sol +++ b/test/QMath.t.sol @@ -1,17 +1,11 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import 'forge-std/Test.sol'; import '@script/Registry.s.sol'; -import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol'; -import {Sqrt} from '@algebra-core/libraries/Sqrt.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; -import {IAlgebraPool} from '@algebra-core/interfaces/IAlgebraPool.sol'; -import {CamelotRelayerFactory} from '@contracts/factories/CamelotRelayerFactory.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {DenominatedOracleFactory} from '@contracts/factories/DenominatedOracleFactory.sol'; -import {IERC20Metadata} from '@algebra-periphery/interfaces/IERC20Metadata.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; @@ -22,102 +16,76 @@ import {MintableERC20} from '@contracts/for-test/MintableERC20.sol'; * in the case of large price fluctuation, adjust INIT_OD_AMOUNT in the Registry to set OD / ETH price */ contract QMath is Test { - using SafeMath for uint256; +// using SafeMath for uint256; - // -- Factories -- - IAlgebraFactory public algebraFactory = IAlgebraFactory(SEPOLIA_ALGEBRA_FACTORY); - CamelotRelayerFactory public camelotRelayerFactory; - ChainlinkRelayerFactory public chainlinkRelayerFactory; - DenominatedOracleFactory public denominatedOracleFactory; +// // -- Factories -- +// IAlgebraFactory public algebraFactory = IAlgebraFactory(SEPOLIA_ALGEBRA_FACTORY); +// CamelotRelayerFactory public camelotRelayerFactory; +// ChainlinkRelayerFactory public chainlinkRelayerFactory; +// DenominatedOracleFactory public denominatedOracleFactory; - // -- Tokens -- - MintableERC20 public mockWeth; - IERC20Metadata public token0; - IERC20Metadata public token1; +// // -- Tokens -- +// MintableERC20 public mockWeth; +// IERC20Metadata public token0; +// IERC20Metadata public token1; - // -- Liquidity Pool -- - address public pool; - uint256 public initPrice; +// // -- Liquidity Pool -- +// address public pool; +// uint256 public initPrice; - // -- Relayers - IBaseOracle public camelotOdWethOracle; - IBaseOracle public chainlinkEthUSDPriceFeed; - IBaseOracle public systemOracle; +// // -- Relayers +// IBaseOracle public camelotOdWethOracle; +// IBaseOracle public chainlinkEthUSDPriceFeed; +// IBaseOracle public systemOracle; - function setUp() public { - uint256 forkId = vm.createFork(vm.rpcUrl('sepolia')); - vm.selectFork(forkId); - camelotRelayerFactory = new CamelotRelayerFactory(); - chainlinkRelayerFactory = new ChainlinkRelayerFactory(); - denominatedOracleFactory = new DenominatedOracleFactory(); +// function setUp() public { +// uint256 forkId = vm.createFork(vm.rpcUrl('sepolia')); +// vm.selectFork(forkId); +// camelotRelayerFactory = new CamelotRelayerFactory(); +// chainlinkRelayerFactory = new ChainlinkRelayerFactory(); +// denominatedOracleFactory = new DenominatedOracleFactory(); - mockWeth = new MintableERC20('Wrapped ETH', 'WETH', 18); +// mockWeth = new MintableERC20('Wrapped ETH', 'WETH', 18); - algebraFactory.createPool(SEPOLIA_SYSTEM_COIN, address(mockWeth)); - pool = algebraFactory.poolByPair(SEPOLIA_SYSTEM_COIN, address(mockWeth)); +// algebraFactory.createPool(SEPOLIA_SYSTEM_COIN, address(mockWeth)); +// pool = algebraFactory.poolByPair(SEPOLIA_SYSTEM_COIN, address(mockWeth)); - token0 = IERC20Metadata(IAlgebraPool(pool).token0()); - token1 = IERC20Metadata(IAlgebraPool(pool).token1()); +// token0 = IERC20Metadata(IAlgebraPool(pool).token0()); +// token1 = IERC20Metadata(IAlgebraPool(pool).token1()); - uint256 inverted; +// uint256 inverted; - // price = token1 / token0 - if (address(token0) == SEPOLIA_SYSTEM_COIN) { - require(keccak256(abi.encodePacked('OD')) == keccak256(abi.encodePacked(token0.symbol())), '!OD'); - initPrice = ((INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); - } else { - require(keccak256(abi.encodePacked('WETH')) == keccak256(abi.encodePacked(token0.symbol())), '!WETH'); - initPrice = ((INIT_OD_AMOUNT * WAD) / INIT_WETH_AMOUNT); - inverted = 1; - } +// // price = token1 / token0 +// if (address(token0) == SEPOLIA_SYSTEM_COIN) { +// require(keccak256(abi.encodePacked('OD')) == keccak256(abi.encodePacked(token0.symbol())), '!OD'); +// initPrice = ((INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); +// } else { +// require(keccak256(abi.encodePacked('WETH')) == keccak256(abi.encodePacked(token0.symbol())), '!WETH'); +// initPrice = ((INIT_OD_AMOUNT * WAD) / INIT_WETH_AMOUNT); +// inverted = 1; +// } - emit log_named_uint('Inverted', inverted); +// emit log_named_uint('Inverted', inverted); - uint256 _sqrtPriceX96 = (Sqrt.sqrtAbs(int256(initPrice)) * (2 ** 96)) / 1e9; +// uint256 _sqrtPriceX96 = (Sqrt.sqrtAbs(int256(initPrice)) * (2 ** 96)) / 1e9; - IAlgebraPool(pool).initialize(uint160(_sqrtPriceX96)); +// IAlgebraPool(pool).initialize(uint160(_sqrtPriceX96)); - camelotOdWethOracle = camelotRelayerFactory.deployAlgebraRelayer( - SEPOLIA_ALGEBRA_FACTORY, SEPOLIA_SYSTEM_COIN, address(mockWeth), uint32(ORACLE_INTERVAL_TEST) - ); +// camelotOdWethOracle = camelotRelayerFactory.deployAlgebraRelayer( +// SEPOLIA_ALGEBRA_FACTORY, SEPOLIA_SYSTEM_COIN, address(mockWeth), uint32(ORACLE_INTERVAL_TEST) +// ); - chainlinkEthUSDPriceFeed = - chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); +// chainlinkEthUSDPriceFeed = +// chainlinkRelayerFactory.deployChainlinkRelayer(SEPOLIA_CHAINLINK_ETH_USD_FEED, ORACLE_INTERVAL_TEST); - systemOracle = - denominatedOracleFactory.deployDenominatedOracle(camelotOdWethOracle, chainlinkEthUSDPriceFeed, false); - } +// systemOracle = +// denominatedOracleFactory.deployDenominatedOracle(camelotOdWethOracle, chainlinkEthUSDPriceFeed, false); +// } - function testPoolPrice() public { - IAlgebraPool _pool = IAlgebraPool(pool); - (uint160 _sqrtPriceX96,,,,,,) = _pool.globalState(); +// function testChainlinkRelayerPrice() public { +// uint256 _result = chainlinkEthUSDPriceFeed.read(); +// emit log_named_uint('Chainlink ETH/USD', _result); // 2347556500000000000000 / 1e18 = 2347.556500000000000000 - emit log_named_uint('sqrtPriceX96', _sqrtPriceX96); - - uint256 _price = (SafeMath.div(uint256(_sqrtPriceX96 * 1e9), (2 ** 96))) ** 2; - assertApproxEqAbs(initPrice, _price, 100_000_000); // 0.000000000100000000 variability - - emit log_named_uint('Price from LPool', _price); - emit log_named_uint('Price Calculated', (INIT_WETH_AMOUNT * WAD) / INIT_OD_AMOUNT); - } - - function testChainlinkRelayerPrice() public { - uint256 _result = chainlinkEthUSDPriceFeed.read(); - emit log_named_uint('Chainlink ETH/USD', _result); // 2347556500000000000000 / 1e18 = 2347.556500000000000000 - - assertApproxEqAbs(INIT_OD_AMOUNT / 1e18, _result / 1e18, 500); // $500 flux - } - - function testCamelotRelayerPrice() public { - vm.warp(block.timestamp + 1 minutes + 1 seconds); - uint256 _result = camelotOdWethOracle.read(); - emit log_named_uint('Camelot OD/WETH', _result); - - assertApproxEqAbs((INIT_OD_AMOUNT * _result) / 1e18, 1 ether, 0.1 ether); // 1 USD - } - - function testOldCamelotRelayerPrice() public { - vm.expectRevert(bytes('OLD')); - camelotOdWethOracle.read(); - } +// assertApproxEqAbs(INIT_OD_AMOUNT / 1e18, _result / 1e18, 500); // $500 flux +// } } diff --git a/test/e2e/SystemOracle.s.sol b/test/e2e/SystemOracle.s.sol index c989b05..3cdbc59 100644 --- a/test/e2e/SystemOracle.s.sol +++ b/test/e2e/SystemOracle.s.sol @@ -1,9 +1,8 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import { - MAINNET_ALGEBRA_FACTORY, MAINNET_CHAINLINK_ETH_USD_FEED, MAINNET_CHAINLINK_ARB_USD_FEED, MAINNET_CHAINLINK_SEQUENCER_FEED, @@ -12,9 +11,7 @@ import { ETH_ARB_POOL } from '@script/Registry.s.sol'; import {DSTestPlus} from '@test/utils/DSTestPlus.t.sol'; -import {CamelotRelayer} from '@contracts/oracles/CamelotRelayer.sol'; import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; -import {IAlgebraFactory} from '@algebra-core/interfaces/IAlgebraFactory.sol'; import {ChainlinkRelayer} from '@contracts/oracles/ChainlinkRelayer.sol'; import {ChainlinkRelayerWithL2Validity} from '@contracts/oracles/ChainlinkRelayerWithL2Validity.sol'; import {IChainlinkRelayer} from '@interfaces/oracles/IChainlinkRelayer.sol'; @@ -35,248 +32,248 @@ import {MockSequencerFeed} from '@contracts/for-test/MockSequencerFeed.sol'; * ARB = 1.0768 USD */ contract OracleSetup is DSTestPlus { - uint256 public constant ARBTIRUM_BLOCK = 159_201_690; // (Dec-11-2023 11:29:40 PM +UTC) - uint256 public constant ETHEREUM_BLOCK = 18_766_228; // (Dec-11-2023 11:26:35 PM +UTC) - - // price w/ 18 decimals - uint256 public constant CHAINLINK_ETH_USD_PRICE_H = 2_218_500_000_000_000_000_000; // +1 USD - uint256 public constant CHAINLINK_ETH_USD_PRICE_M = 2_217_500_000_000_000_000_000; // approx. price of ETH in USD - uint256 public constant CHAINLINK_ETH_USD_PRICE_L = 2_216_500_000_000_000_000_000; // -1 USD - - // price w/ 6 decimals - int256 public constant ETH_USD_PRICE_H = 221_850_000_000; // +1 USD - int256 public constant ETH_USD_PRICE_M = 221_750_000_000; // approx. price of ETH in USD - int256 public constant ETH_USD_PRICE_L = 221_650_000_000; // -1 USD - - uint256 public constant CHAINLINK_ETH_ARB_PRICE = 965_000_000_000_000_000; // NOTE: 18 decimals - - uint256 public constant ETH_ARB_PRICE = 2_046_975_875_739_099_288_474; // price of ETH in ARB - uint256 public constant ARB_ETH_PRICE = 488_525_542_412_135; // price of ARB in ETH - uint256 public constant ARB_USD_PRICE = 1_083_214_437_815_195_905; // price of ARB in USD - uint256 public constant USD_ARB_PRICE = 923_178_241_620_339_420; // price of USD in ARB - - uint256 public constant GRACE_PERIOD = 1 hours; - uint32 public constant STALE_PRICE = 1 days; - int256 public constant UP = 0; - int256 public constant DOWN = 1; - - uint256 public startTime; - - IBaseOracle public ethUsdPriceSource; // from Chainlink - IBaseOracle public ethUsdPriceSourceL2Verified; // from Chainlink - IBaseOracle public ethUsdPriceSourceL2VerifiedMock; // from Chainlink - IBaseOracle public ethArbPriceSource; // from Camelot pool - IBaseOracle public arbEthPriceSource; // from Camelot pool - - IDenominatedOracle public arbUsdPriceSource; - IDenominatedOracle public arbUsdPriceSourceL2Verified; - IDenominatedOracle public arbUsdPriceSourceInverted; - - MockSequencerFeed public mockSeqFeed; - - /** - * @dev Arbitrum block.number returns L1; createSelectFork does not work - */ - function setUp() public { - uint256 forkId = vm.createFork(vm.rpcUrl('mainnet')); - vm.selectFork(forkId); - vm.rollFork(ARBTIRUM_BLOCK); - - mockSeqFeed = new MockSequencerFeed(); - startTime = block.timestamp; - - // --- Chainlink --- - ethUsdPriceSource = IBaseOracle(address(new ChainlinkRelayer(MAINNET_CHAINLINK_ETH_USD_FEED, STALE_PRICE))); - ethUsdPriceSourceL2Verified = IBaseOracle( - address( - new ChainlinkRelayerWithL2Validity( - MAINNET_CHAINLINK_ETH_USD_FEED, MAINNET_CHAINLINK_SEQUENCER_FEED, STALE_PRICE, GRACE_PERIOD - ) - ) - ); - ethUsdPriceSourceL2VerifiedMock = IBaseOracle( - address( - new ChainlinkRelayerWithL2Validity( - MAINNET_CHAINLINK_ETH_USD_FEED, address(mockSeqFeed), STALE_PRICE, GRACE_PERIOD - ) - ) - ); - - // --- Camelot --- - arbEthPriceSource = IBaseOracle(address(new CamelotRelayer(MAINNET_ALGEBRA_FACTORY, ARB, ETH, STALE_PRICE))); // correct - ethArbPriceSource = IBaseOracle(address(new CamelotRelayer(MAINNET_ALGEBRA_FACTORY, ETH, ARB, STALE_PRICE))); // inverted - - // --- Denominated --- - arbUsdPriceSource = IDenominatedOracle(address(new DenominatedOracle(arbEthPriceSource, ethUsdPriceSource, false))); - arbUsdPriceSourceL2Verified = - IDenominatedOracle(address(new DenominatedOracle(arbEthPriceSource, ethUsdPriceSourceL2Verified, false))); - arbUsdPriceSourceInverted = - IDenominatedOracle(address(new DenominatedOracle(ethArbPriceSource, ethUsdPriceSource, true))); - } - - // --- Setup --- - - function test_ArbitrumFork() public { - emit log_named_uint('L1 Block Number Oracle Fork', block.number); - assertEq(block.number, ETHEREUM_BLOCK); - } - - function test_MockSequencerFeedUp() public { - assertEq(mockSeqFeed.answer(), UP); - assertEq(mockSeqFeed.startedAt(), startTime); - (uint256 _roundId, int256 _answer, uint256 _startedAt, uint256 _updatedAt, uint256 _answeredInRound) = - mockSeqFeed.latestRoundData(); - assertEq(_roundId, 1); - assertEq(_answer, UP); - assertEq(_startedAt, startTime); - assertEq(_updatedAt, 1); - assertEq(_answeredInRound, 1); - } - - function test_MockSequencerFeedDown() public { - mockSeqFeed.switchSequencer(); - assertEq(mockSeqFeed.answer(), DOWN); - (uint256 _roundId, int256 _answer, uint256 _startedAt, uint256 _updatedAt, uint256 _answeredInRound) = - mockSeqFeed.latestRoundData(); - assertEq(_roundId, 1); - assertEq(_answer, DOWN); - assertEq(_startedAt, startTime); - assertEq(_updatedAt, 1); - assertEq(_answeredInRound, 1); - } - - // --- Chainlink --- - function test_ChainlinkOracle() public { - int256 price = IChainlinkOracle(MAINNET_CHAINLINK_ETH_USD_FEED).latestAnswer(); - assertTrue(price >= ETH_USD_PRICE_L && price <= ETH_USD_PRICE_H); - } - - function test_InitializeChainlinkRelayer() public { - vm.expectRevert(); - new ChainlinkRelayer(address(0), STALE_PRICE); - vm.expectRevert(); - new ChainlinkRelayer(address(0x1234), 0); - } - - function test_ChainlinkRelayer() public { - uint256 price = ethUsdPriceSource.read(); - assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); - } - - function test_ChainlinkRelayerWithValidity() public { - (uint256 price, bool valid) = ethUsdPriceSource.getResultWithValidity(); - assertTrue(valid); - assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); - } - - function test_ChainlinkRelayerSymbol() public { - assertEq(ethUsdPriceSource.symbol(), 'ETH / USD'); - } - - function test_InitializeChainlinkRelayerL2Verified() public { - ChainlinkRelayerWithL2Validity _testRelayer; - vm.expectRevert(); - _testRelayer = new ChainlinkRelayerWithL2Validity(address(0), address(0x1234), STALE_PRICE, GRACE_PERIOD); - vm.expectRevert(); - _testRelayer = new ChainlinkRelayerWithL2Validity(address(0x1234), address(0), STALE_PRICE, GRACE_PERIOD); - vm.expectRevert(); - _testRelayer = new ChainlinkRelayerWithL2Validity(address(0x1234), address(0x1234), 0, GRACE_PERIOD); - vm.expectRevert(); - _testRelayer = new ChainlinkRelayerWithL2Validity(address(0x1234), address(0x1234), STALE_PRICE, 0); - } - - function test_ChainlinkRelayerL2Verified() public { - uint256 price = ethUsdPriceSourceL2Verified.read(); - assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); - } - - function test_ChainlinkRelayerL2VerifiedWithValidity() public { - (uint256 price, bool valid) = ethUsdPriceSourceL2Verified.getResultWithValidity(); - assertTrue(valid); - assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); - } - - function test_ChainlinkRelayerL2Verified_RevertAfterInit() public { - vm.expectRevert('SequencerDown'); - ethUsdPriceSourceL2VerifiedMock.read(); // sequencer up, grace period deny - (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); - assertFalse(_validity); - } - - function test_ChainlinkRelayerL2Verified_RevertGracePeriod() public { - vm.warp(startTime + GRACE_PERIOD - 1); - vm.expectRevert('SequencerDown'); // sequencer up, grace period deny - ethUsdPriceSourceL2VerifiedMock.read(); - (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); - assertFalse(_validity); - } - - function test_ChainlinkRelayerL2Verified_RevertNetworkDown() public { - vm.warp(startTime + GRACE_PERIOD); - mockSeqFeed.switchSequencer(); - vm.expectRevert('SequencerDown'); // sequencer down, grace period accept - ethUsdPriceSourceL2VerifiedMock.read(); - (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); - assertFalse(_validity); - } - - function test_ChainlinkRelayerL2Verified_RevertAll() public { - vm.warp(startTime + GRACE_PERIOD - 1); - mockSeqFeed.switchSequencer(); - vm.expectRevert('SequencerDown'); // sequencer down, grace period deny - ethUsdPriceSourceL2VerifiedMock.read(); - (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); - assertFalse(_validity); - } - - function test_ChainlinkRelayerSymbolL2Verified() public { - assertEq(ethUsdPriceSourceL2Verified.symbol(), 'ETH / USD'); - } - - // --- Algebra/Camelot --- - - function test_CamelotRelayer() public { - assertEq(arbEthPriceSource.read(), ARB_ETH_PRICE); - } - - function test_CamelotRelayerSymbol() public { - assertEq(arbEthPriceSource.symbol(), 'ARB / WETH'); - } - - function test_CamelotRelayer_Inverted() public { - assertEq(ethArbPriceSource.read(), ETH_ARB_PRICE); - } - - function test_CamelotRelayerSymbolInverted() public { - assertEq(ethArbPriceSource.symbol(), 'WETH / ARB'); - } - - // --- Denominated --- - - function test_DenominatedOracle() public { - assertEq(arbUsdPriceSource.read(), ARB_USD_PRICE); - } - - function test_DenominatedOracleL2Verified() public { - assertEq(arbUsdPriceSourceL2Verified.read(), ARB_USD_PRICE); - } - - function test_DenominatedOracleSymbol() public { - assertEq(arbUsdPriceSource.symbol(), '(ARB / WETH) * (ETH / USD)'); - } - - function test_DenominatedOracleSymbolL2Verified() public { - assertEq(arbUsdPriceSourceL2Verified.symbol(), '(ARB / WETH) * (ETH / USD)'); - } - - function test_DenominatedInvertedOracle() public { - assertEq(arbUsdPriceSourceInverted.read(), ARB_USD_PRICE); - } - - function test_DenominatedOracleInvertedSymbol() public { - IDenominatedOracle arbUsdPriceSourceInvert = - IDenominatedOracle(address(new DenominatedOracle(ethArbPriceSource, ethUsdPriceSource, true))); - - assertEq(arbUsdPriceSourceInvert.symbol(), '(WETH / ARB)^-1 / (ETH / USD)'); - } +// uint256 public constant ARBTIRUM_BLOCK = 159_201_690; // (Dec-11-2023 11:29:40 PM +UTC) +// uint256 public constant ETHEREUM_BLOCK = 18_766_228; // (Dec-11-2023 11:26:35 PM +UTC) + +// // price w/ 18 decimals +// uint256 public constant CHAINLINK_ETH_USD_PRICE_H = 2_218_500_000_000_000_000_000; // +1 USD +// uint256 public constant CHAINLINK_ETH_USD_PRICE_M = 2_217_500_000_000_000_000_000; // approx. price of ETH in USD +// uint256 public constant CHAINLINK_ETH_USD_PRICE_L = 2_216_500_000_000_000_000_000; // -1 USD + +// // price w/ 6 decimals +// int256 public constant ETH_USD_PRICE_H = 221_850_000_000; // +1 USD +// int256 public constant ETH_USD_PRICE_M = 221_750_000_000; // approx. price of ETH in USD +// int256 public constant ETH_USD_PRICE_L = 221_650_000_000; // -1 USD + +// uint256 public constant CHAINLINK_ETH_ARB_PRICE = 965_000_000_000_000_000; // NOTE: 18 decimals + +// uint256 public constant ETH_ARB_PRICE = 2_046_975_875_739_099_288_474; // price of ETH in ARB +// uint256 public constant ARB_ETH_PRICE = 488_525_542_412_135; // price of ARB in ETH +// uint256 public constant ARB_USD_PRICE = 1_083_214_437_815_195_905; // price of ARB in USD +// uint256 public constant USD_ARB_PRICE = 923_178_241_620_339_420; // price of USD in ARB + +// uint256 public constant GRACE_PERIOD = 1 hours; +// uint32 public constant STALE_PRICE = 1 days; +// int256 public constant UP = 0; +// int256 public constant DOWN = 1; + +// uint256 public startTime; + +// IBaseOracle public ethUsdPriceSource; // from Chainlink +// IBaseOracle public ethUsdPriceSourceL2Verified; // from Chainlink +// IBaseOracle public ethUsdPriceSourceL2VerifiedMock; // from Chainlink +// IBaseOracle public ethArbPriceSource; // from Camelot pool +// IBaseOracle public arbEthPriceSource; // from Camelot pool + +// IDenominatedOracle public arbUsdPriceSource; +// IDenominatedOracle public arbUsdPriceSourceL2Verified; +// IDenominatedOracle public arbUsdPriceSourceInverted; + +// MockSequencerFeed public mockSeqFeed; + +// /** +// * @dev Arbitrum block.number returns L1; createSelectFork does not work +// */ +// function setUp() public { +// uint256 forkId = vm.createFork(vm.rpcUrl('mainnet')); +// vm.selectFork(forkId); +// vm.rollFork(ARBTIRUM_BLOCK); + +// mockSeqFeed = new MockSequencerFeed(); +// startTime = block.timestamp; + +// // --- Chainlink --- +// ethUsdPriceSource = IBaseOracle(address(new ChainlinkRelayer(MAINNET_CHAINLINK_ETH_USD_FEED, STALE_PRICE))); +// ethUsdPriceSourceL2Verified = IBaseOracle( +// address( +// new ChainlinkRelayerWithL2Validity( +// MAINNET_CHAINLINK_ETH_USD_FEED, MAINNET_CHAINLINK_SEQUENCER_FEED, STALE_PRICE, GRACE_PERIOD +// ) +// ) +// ); +// ethUsdPriceSourceL2VerifiedMock = IBaseOracle( +// address( +// new ChainlinkRelayerWithL2Validity( +// MAINNET_CHAINLINK_ETH_USD_FEED, address(mockSeqFeed), STALE_PRICE, GRACE_PERIOD +// ) +// ) +// ); + +// // --- Camelot --- +// arbEthPriceSource = IBaseOracle(address(new CamelotRelayer(MAINNET_ALGEBRA_FACTORY, ARB, ETH, STALE_PRICE))); // correct +// ethArbPriceSource = IBaseOracle(address(new CamelotRelayer(MAINNET_ALGEBRA_FACTORY, ETH, ARB, STALE_PRICE))); // inverted + +// // --- Denominated --- +// arbUsdPriceSource = IDenominatedOracle(address(new DenominatedOracle(arbEthPriceSource, ethUsdPriceSource, false))); +// arbUsdPriceSourceL2Verified = +// IDenominatedOracle(address(new DenominatedOracle(arbEthPriceSource, ethUsdPriceSourceL2Verified, false))); +// arbUsdPriceSourceInverted = +// IDenominatedOracle(address(new DenominatedOracle(ethArbPriceSource, ethUsdPriceSource, true))); +// } + +// // --- Setup --- + +// function test_ArbitrumFork() public { +// emit log_named_uint('L1 Block Number Oracle Fork', block.number); +// assertEq(block.number, ETHEREUM_BLOCK); +// } + +// function test_MockSequencerFeedUp() public { +// assertEq(mockSeqFeed.answer(), UP); +// assertEq(mockSeqFeed.startedAt(), startTime); +// (uint256 _roundId, int256 _answer, uint256 _startedAt, uint256 _updatedAt, uint256 _answeredInRound) = +// mockSeqFeed.latestRoundData(); +// assertEq(_roundId, 1); +// assertEq(_answer, UP); +// assertEq(_startedAt, startTime); +// assertEq(_updatedAt, 1); +// assertEq(_answeredInRound, 1); +// } + +// function test_MockSequencerFeedDown() public { +// mockSeqFeed.switchSequencer(); +// assertEq(mockSeqFeed.answer(), DOWN); +// (uint256 _roundId, int256 _answer, uint256 _startedAt, uint256 _updatedAt, uint256 _answeredInRound) = +// mockSeqFeed.latestRoundData(); +// assertEq(_roundId, 1); +// assertEq(_answer, DOWN); +// assertEq(_startedAt, startTime); +// assertEq(_updatedAt, 1); +// assertEq(_answeredInRound, 1); +// } + +// // --- Chainlink --- +// function test_ChainlinkOracle() public { +// int256 price = IChainlinkOracle(MAINNET_CHAINLINK_ETH_USD_FEED).latestAnswer(); +// assertTrue(price >= ETH_USD_PRICE_L && price <= ETH_USD_PRICE_H); +// } + +// function test_InitializeChainlinkRelayer() public { +// vm.expectRevert(); +// new ChainlinkRelayer(address(0), STALE_PRICE); +// vm.expectRevert(); +// new ChainlinkRelayer(address(0x1234), 0); +// } + +// function test_ChainlinkRelayer() public { +// uint256 price = ethUsdPriceSource.read(); +// assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); +// } + +// function test_ChainlinkRelayerWithValidity() public { +// (uint256 price, bool valid) = ethUsdPriceSource.getResultWithValidity(); +// assertTrue(valid); +// assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); +// } + +// function test_ChainlinkRelayerSymbol() public { +// assertEq(ethUsdPriceSource.symbol(), 'ETH / USD'); +// } + +// function test_InitializeChainlinkRelayerL2Verified() public { +// ChainlinkRelayerWithL2Validity _testRelayer; +// vm.expectRevert(); +// _testRelayer = new ChainlinkRelayerWithL2Validity(address(0), address(0x1234), STALE_PRICE, GRACE_PERIOD); +// vm.expectRevert(); +// _testRelayer = new ChainlinkRelayerWithL2Validity(address(0x1234), address(0), STALE_PRICE, GRACE_PERIOD); +// vm.expectRevert(); +// _testRelayer = new ChainlinkRelayerWithL2Validity(address(0x1234), address(0x1234), 0, GRACE_PERIOD); +// vm.expectRevert(); +// _testRelayer = new ChainlinkRelayerWithL2Validity(address(0x1234), address(0x1234), STALE_PRICE, 0); +// } + +// function test_ChainlinkRelayerL2Verified() public { +// uint256 price = ethUsdPriceSourceL2Verified.read(); +// assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); +// } + +// function test_ChainlinkRelayerL2VerifiedWithValidity() public { +// (uint256 price, bool valid) = ethUsdPriceSourceL2Verified.getResultWithValidity(); +// assertTrue(valid); +// assertTrue(price >= CHAINLINK_ETH_USD_PRICE_L && price <= CHAINLINK_ETH_USD_PRICE_H); +// } + +// function test_ChainlinkRelayerL2Verified_RevertAfterInit() public { +// vm.expectRevert('SequencerDown'); +// ethUsdPriceSourceL2VerifiedMock.read(); // sequencer up, grace period deny +// (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); +// assertFalse(_validity); +// } + +// function test_ChainlinkRelayerL2Verified_RevertGracePeriod() public { +// vm.warp(startTime + GRACE_PERIOD - 1); +// vm.expectRevert('SequencerDown'); // sequencer up, grace period deny +// ethUsdPriceSourceL2VerifiedMock.read(); +// (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); +// assertFalse(_validity); +// } + +// function test_ChainlinkRelayerL2Verified_RevertNetworkDown() public { +// vm.warp(startTime + GRACE_PERIOD); +// mockSeqFeed.switchSequencer(); +// vm.expectRevert('SequencerDown'); // sequencer down, grace period accept +// ethUsdPriceSourceL2VerifiedMock.read(); +// (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); +// assertFalse(_validity); +// } + +// function test_ChainlinkRelayerL2Verified_RevertAll() public { +// vm.warp(startTime + GRACE_PERIOD - 1); +// mockSeqFeed.switchSequencer(); +// vm.expectRevert('SequencerDown'); // sequencer down, grace period deny +// ethUsdPriceSourceL2VerifiedMock.read(); +// (uint256 _result, bool _validity) = ethUsdPriceSourceL2VerifiedMock.getResultWithValidity(); +// assertFalse(_validity); +// } + +// function test_ChainlinkRelayerSymbolL2Verified() public { +// assertEq(ethUsdPriceSourceL2Verified.symbol(), 'ETH / USD'); +// } + +// // --- Algebra/Camelot --- + +// function test_CamelotRelayer() public { +// assertEq(arbEthPriceSource.read(), ARB_ETH_PRICE); +// } + +// function test_CamelotRelayerSymbol() public { +// assertEq(arbEthPriceSource.symbol(), 'ARB / WETH'); +// } + +// function test_CamelotRelayer_Inverted() public { +// assertEq(ethArbPriceSource.read(), ETH_ARB_PRICE); +// } + +// function test_CamelotRelayerSymbolInverted() public { +// assertEq(ethArbPriceSource.symbol(), 'WETH / ARB'); +// } + +// // --- Denominated --- + +// function test_DenominatedOracle() public { +// assertEq(arbUsdPriceSource.read(), ARB_USD_PRICE); +// } + +// function test_DenominatedOracleL2Verified() public { +// assertEq(arbUsdPriceSourceL2Verified.read(), ARB_USD_PRICE); +// } + +// function test_DenominatedOracleSymbol() public { +// assertEq(arbUsdPriceSource.symbol(), '(ARB / WETH) * (ETH / USD)'); +// } + +// function test_DenominatedOracleSymbolL2Verified() public { +// assertEq(arbUsdPriceSourceL2Verified.symbol(), '(ARB / WETH) * (ETH / USD)'); +// } + +// function test_DenominatedInvertedOracle() public { +// assertEq(arbUsdPriceSourceInverted.read(), ARB_USD_PRICE); +// } + +// function test_DenominatedOracleInvertedSymbol() public { +// IDenominatedOracle arbUsdPriceSourceInvert = +// IDenominatedOracle(address(new DenominatedOracle(ethArbPriceSource, ethUsdPriceSource, true))); + +// assertEq(arbUsdPriceSourceInvert.symbol(), '(WETH / ARB)^-1 / (ETH / USD)'); +// } } diff --git a/test/unit/RelayerFactories.t.sol b/test/unit/RelayerFactories.t.sol index 548ba88..5917159 100644 --- a/test/unit/RelayerFactories.t.sol +++ b/test/unit/RelayerFactories.t.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import '@script/Registry.s.sol'; import {DSTestPlus} from '@test/utils/DSTestPlus.t.sol'; +import {IERC20Metadata} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol'; import {ChainlinkRelayerFactory} from '@contracts/factories/ChainlinkRelayerFactory.sol'; import {ChainlinkRelayerChild} from '@contracts/factories/ChainlinkRelayerChild.sol'; import {PendleRelayerFactory} from '@contracts/factories/pendle/PendleRelayerFactory.sol'; @@ -18,330 +19,330 @@ import {IPendleRelayerFactory} from '@interfaces/factories/IPendleRelayerFactory import {IPendleRelayer} from '@interfaces/oracles/pendle/IPendleRelayer.sol'; abstract contract Base is DSTestPlus { - address deployer = label('deployer'); - address authorizedAccount = label('authorizedAccount'); - address user = label('user'); - - IERC20Metadata mockBaseToken = IERC20Metadata(mockContract('BaseToken')); - IERC20Metadata mockQuoteToken = IERC20Metadata(mockContract('QuoteToken')); - - ChainlinkRelayerFactory chainlinkRelayerFactory; - IBaseOracle chainlinkRelayerChild; - - DenominatedOracleFactory denominatedOracleFactory; - IBaseOracle denominatedOracleChild; - - IDelayedOracleFactory delayedOracleFactory; - IBaseOracle delayedOracleChild; - - address mockAggregator = mockContract('ChainlinkAggregator'); - - function setUp() public virtual { - vm.startPrank(deployer); - chainlinkRelayerFactory = new ChainlinkRelayerFactory(); - label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); - - chainlinkRelayerFactory.addAuthorization(authorizedAccount); - - denominatedOracleFactory = new DenominatedOracleFactory(); - label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); - - denominatedOracleFactory.addAuthorization(authorizedAccount); - - vm.stopPrank(); - } - - function _mockSymbol(string memory _symbol) internal { - vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); - vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); - vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode(_symbol)); - } - - function _mockDecimals(uint8 _decimals) internal { - vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); - vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); - vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); - } -} - -contract Unit_ChainlinkRelayerFactory_Constructor is Base { - event AddAuthorization(address _account); - - modifier happyPath() { - vm.startPrank(user); - _; - } - - function test_Emit_AddAuthorization() public happyPath { - vm.expectEmit(); - emit AddAuthorization(user); - - chainlinkRelayerFactory = new ChainlinkRelayerFactory(); - } -} - -contract Unit_RelayerFactory_DeployChainlinkRelayer is Base { - event NewChainlinkRelayer(address indexed _chainlinkRelayer, address _aggregator, uint256 _staleThreshold); - - address chainlinkRelayer = 0x56D9e6a12fC3E3f589Ee5E685C9f118D62ce9C8D; - - modifier happyPath(string memory _symbol, uint8 _decimals, uint256 _staleThreshold) { - vm.startPrank(authorizedAccount); - vm.assume(_staleThreshold > 0); - _assumeHappyPath(_decimals); - _mockSymbol(_symbol); - _mockDecimals(_decimals); - _; - } - - function _assumeHappyPath(uint8 _decimals) internal pure { - vm.assume(_decimals <= 18 && _decimals > 0); - } - - function test_Deploy_RelayerChild( - string memory _symbol, - uint8 _decimals, - uint256 _staleThreshold - ) public happyPath(_symbol, _decimals, _staleThreshold) { - vm.expectEmit(); - emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); - - chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); - assertEq(chainlinkRelayerChild.symbol(), _symbol); - } - - function test_Set_Relayers( - string memory _symbol, - uint8 _decimals, - uint256 _staleThreshold - ) public happyPath(_symbol, _decimals, _staleThreshold) { - chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); - - assertEq(chainlinkRelayerFactory.relayerById(1), address(chainlinkRelayerChild)); - } - - function test_Set_Relayers_WithL2Validity( - string memory _symbol, - uint8 _decimals, - uint256 _staleThreshold - ) public happyPath(_symbol, _decimals, _staleThreshold) { - chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( - mockAggregator, mockAggregator, _staleThreshold, _staleThreshold - ); - - assertEq(chainlinkRelayerFactory.relayerWithL2ValidityById(1), address(chainlinkRelayerChild)); - } - - function test_Emit_NewRelayer( - string memory _symbol, - uint8 _decimals, - uint256 _staleThreshold - ) public happyPath(_symbol, _decimals, _staleThreshold) { - vm.expectEmit(); - emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); - - chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); - assertEq(chainlinkRelayerChild.symbol(), _symbol); - } - - function test_Return_Relayer( - string memory _symbol, - uint8 _decimals, - uint256 _staleThreshold - ) public happyPath(_symbol, _decimals, _staleThreshold) { - assertEq( - address(chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold)), - address(chainlinkRelayer) - ); - } -} - -contract Unit_DenominatedPriceOracleFactory_Constructor is Base { - event AddAuthorization(address _account); - - modifier happyPath() { - vm.startPrank(user); - _; - } - - function test_Emit_AddAuthorization() public happyPath { - vm.expectEmit(); - emit AddAuthorization(user); - - denominatedOracleFactory = new DenominatedOracleFactory(); - } -} - -contract Unit_DenominatedPriceOracleFactory_DeployDenominatedOracle is Base { - event NewDenominatedOracle( - address indexed _denominatedOracle, address _priceSource, address _denominationPriceSource, bool _inverted - ); - - address denominatedOracle = 0xb2A72B7BA8156A59fD84c61e5eF539d385D8652a; - - modifier happyPath() { - vm.startPrank(authorizedAccount); - _; - } - - function setUp() public override { - super.setUp(); - vm.startPrank(authorizedAccount); - vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode('BaseToken')); - vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode('QuoteToken')); - vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode('Aggregator')); - vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(18)); - vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(18)); - vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(18)); - - chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, 100); - _mockToken0(address(mockBaseToken)); - _mockToken1(address(mockQuoteToken)); - - vm.stopPrank(); - } - - function test_Deploy_RelayerChild() public happyPath { - vm.expectEmit(); - emit NewDenominatedOracle( - address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), false - ); - denominatedOracleChild = - denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); - - string memory symbol = - string(abi.encodePacked('(', mockBaseToken.symbol(), ' / ', mockQuoteToken.symbol(), ') * (Aggregator)')); - assertEq(denominatedOracleChild.symbol(), symbol); - } - - function test_Deploy_RelayerChildInverted() public happyPath { - vm.expectEmit(); - emit NewDenominatedOracle( - address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), true - ); - denominatedOracleChild = - denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, true); - - string memory symbol = - string(abi.encodePacked('(', mockBaseToken.symbol(), ' / ', mockQuoteToken.symbol(), ')^-1 / (Aggregator)')); - assertEq(denominatedOracleChild.symbol(), symbol); - } - - function test_Set_Relayers() public happyPath { - denominatedOracleChild = - denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); - assertEq(denominatedOracleFactory.oracleById(1), address(denominatedOracleChild)); - } - - function test_Emit_NewRelayer() public happyPath { - vm.expectEmit(); - emit NewDenominatedOracle( - address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), false - ); - denominatedOracleChild = - denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); - } - - function test_Return_Relayer() public happyPath { - assertEq( - address(denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false)), - address(denominatedOracle) - ); - } -} - -contract Unit_Pendle_Renzo_Deploy_Oracle is Base { - address mainnetAuthorizedAccount = 0xF78dA2A37049627636546E0cFAaB2aD664950917; - IPendleRelayerFactory public pendleFactory; - - function setUp() public virtual override { - super.setUp(); - vm.createSelectFork(vm.envString('ARB_MAINNET_RPC')); - delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); - chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); - denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); - pendleFactory = IPendleRelayerFactory(address(new PendleRelayerFactory())); - label(address(delayedOracleFactory), 'DelayedOracleFactory'); - label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); - label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); - } - - function test_DeployEzEthRelayer() public { - vm.startPrank(mainnetAuthorizedAccount); - IBaseOracle _ezEthEthPriceFeed = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( - MAINNET_CHAINLINK_EZETH_ETH_FEED, - MAINNET_CHAINLINK_SEQUENCER_FEED, - MAINNET_ORACLE_DELAY, - MAINNET_CHAINLINK_L2VALIDITY_GRACE_PERIOD - ); - - IBaseOracle _ezEthUsdOracle = denominatedOracleFactory.deployDenominatedOracle( - _ezEthEthPriceFeed, IBaseOracle(MAINNET_CHAINLINK_ETH_USD_RELAYER), false - ); - - IBaseOracle _ezEthUsdDelayedOracle = delayedOracleFactory.deployDelayedOracle(_ezEthUsdOracle, MAINNET_ORACLE_DELAY); - - string memory _ezEthSymbol = _ezEthUsdDelayedOracle.symbol(); // "(EZETH / ETH) * (ETH / USD)" - vm.stopPrank(); - assertEq(_ezEthSymbol, '(ezETH / ETH) * (ETH / USD)'); - } - - function test_Deploy_PendleFactory() public { - assertEq(pendleFactory.relayerId(), 0); - assertEq(pendleFactory.authorizedAccounts()[0], address(this)); - } - - function test_Deploy_PT_Oracle() public { - IBaseOracle ptOracle = - pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); - assertTrue(keccak256(abi.encode(ptOracle.symbol())) != keccak256(abi.encode(''))); - assertEq(uint256(IPendleRelayer(address(ptOracle)).twapDuration()), 900); - assertEq(address(IPendleRelayer(address(ptOracle)).market()), MAINNET_PENDLE_RETH_MARKET); - assertEq(address(IPendleRelayer(address(ptOracle)).oracle()), MAINNET_PENDLE_ORACLE); - assertEq(address(IPendleRelayer(address(ptOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); - assertEq(address(IPendleRelayer(address(ptOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); - assertEq(address(IPendleRelayer(address(ptOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); - } - - function test_Deploy_YT_Oracle() public { - IBaseOracle ytOracle = - pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); - assertTrue(keccak256(abi.encode(ytOracle.symbol())) != keccak256(abi.encode(''))); - assertEq(uint256(IPendleRelayer(address(ytOracle)).twapDuration()), 900); - assertEq(address(IPendleRelayer(address(ytOracle)).market()), MAINNET_PENDLE_RETH_MARKET); - assertEq(address(IPendleRelayer(address(ytOracle)).oracle()), MAINNET_PENDLE_ORACLE); - assertEq(address(IPendleRelayer(address(ytOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); - assertEq(address(IPendleRelayer(address(ytOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); - assertEq(address(IPendleRelayer(address(ytOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); - } - - function test_Deploy_LP_Oracle() public { - IBaseOracle lpOracle = - pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); - assertTrue(keccak256(abi.encode(lpOracle.symbol())) != keccak256(abi.encode(''))); - assertEq(uint256(IPendleRelayer(address(lpOracle)).twapDuration()), 900); - assertEq(address(IPendleRelayer(address(lpOracle)).market()), MAINNET_PENDLE_RETH_MARKET); - assertEq(address(IPendleRelayer(address(lpOracle)).oracle()), MAINNET_PENDLE_ORACLE); - assertEq(address(IPendleRelayer(address(lpOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); - assertEq(address(IPendleRelayer(address(lpOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); - assertEq(address(IPendleRelayer(address(lpOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); - } - - function test_Deploy_Oracle_Revert_Invalid_Twap() public { - vm.expectRevert('Invalid TWAP duration'); - pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); - vm.expectRevert('Invalid TWAP duration'); - pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); - vm.expectRevert('Invalid TWAP duration'); - pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); - } - - function test_Deploy_Oracle_Revert_Invalid_Address() public { - vm.expectRevert('Invalid address'); - pendleFactory.deployPendlePtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); - vm.expectRevert('Invalid address'); - pendleFactory.deployPendleYtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); - vm.expectRevert('Invalid address'); - pendleFactory.deployPendleLpRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); - } +// address deployer = label('deployer'); +// address authorizedAccount = label('authorizedAccount'); +// address user = label('user'); + +// IERC20Metadata mockBaseToken = IERC20Metadata(mockContract('BaseToken')); +// IERC20Metadata mockQuoteToken = IERC20Metadata(mockContract('QuoteToken')); + +// ChainlinkRelayerFactory chainlinkRelayerFactory; +// IBaseOracle chainlinkRelayerChild; + +// DenominatedOracleFactory denominatedOracleFactory; +// IBaseOracle denominatedOracleChild; + +// IDelayedOracleFactory delayedOracleFactory; +// IBaseOracle delayedOracleChild; + +// address mockAggregator = mockContract('ChainlinkAggregator'); + +// function setUp() public virtual { +// vm.startPrank(deployer); +// chainlinkRelayerFactory = new ChainlinkRelayerFactory(); +// label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); + +// chainlinkRelayerFactory.addAuthorization(authorizedAccount); + +// denominatedOracleFactory = new DenominatedOracleFactory(); +// label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); + +// denominatedOracleFactory.addAuthorization(authorizedAccount); + +// vm.stopPrank(); +// } + +// function _mockSymbol(string memory _symbol) internal { +// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); +// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); +// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode(_symbol)); +// } + +// function _mockDecimals(uint8 _decimals) internal { +// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); +// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); +// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); +// } +// } + +// contract Unit_ChainlinkRelayerFactory_Constructor is Base { +// event AddAuthorization(address _account); + +// modifier happyPath() { +// vm.startPrank(user); +// _; +// } + +// function test_Emit_AddAuthorization() public happyPath { +// vm.expectEmit(); +// emit AddAuthorization(user); + +// chainlinkRelayerFactory = new ChainlinkRelayerFactory(); +// } +// } + +// contract Unit_RelayerFactory_DeployChainlinkRelayer is Base { +// event NewChainlinkRelayer(address indexed _chainlinkRelayer, address _aggregator, uint256 _staleThreshold); + +// address chainlinkRelayer = 0x56D9e6a12fC3E3f589Ee5E685C9f118D62ce9C8D; + +// modifier happyPath(string memory _symbol, uint8 _decimals, uint256 _staleThreshold) { +// vm.startPrank(authorizedAccount); +// vm.assume(_staleThreshold > 0); +// _assumeHappyPath(_decimals); +// _mockSymbol(_symbol); +// _mockDecimals(_decimals); +// _; +// } + +// function _assumeHappyPath(uint8 _decimals) internal pure { +// vm.assume(_decimals <= 18 && _decimals > 0); +// } + +// function test_Deploy_RelayerChild( +// string memory _symbol, +// uint8 _decimals, +// uint256 _staleThreshold +// ) public happyPath(_symbol, _decimals, _staleThreshold) { +// vm.expectEmit(); +// emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); + +// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); +// assertEq(chainlinkRelayerChild.symbol(), _symbol); +// } + +// function test_Set_Relayers( +// string memory _symbol, +// uint8 _decimals, +// uint256 _staleThreshold +// ) public happyPath(_symbol, _decimals, _staleThreshold) { +// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); + +// assertEq(chainlinkRelayerFactory.relayerById(1), address(chainlinkRelayerChild)); +// } + +// function test_Set_Relayers_WithL2Validity( +// string memory _symbol, +// uint8 _decimals, +// uint256 _staleThreshold +// ) public happyPath(_symbol, _decimals, _staleThreshold) { +// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( +// mockAggregator, mockAggregator, _staleThreshold, _staleThreshold +// ); + +// assertEq(chainlinkRelayerFactory.relayerWithL2ValidityById(1), address(chainlinkRelayerChild)); +// } + +// function test_Emit_NewRelayer( +// string memory _symbol, +// uint8 _decimals, +// uint256 _staleThreshold +// ) public happyPath(_symbol, _decimals, _staleThreshold) { +// vm.expectEmit(); +// emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); + +// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); +// assertEq(chainlinkRelayerChild.symbol(), _symbol); +// } + +// function test_Return_Relayer( +// string memory _symbol, +// uint8 _decimals, +// uint256 _staleThreshold +// ) public happyPath(_symbol, _decimals, _staleThreshold) { +// assertEq( +// address(chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold)), +// address(chainlinkRelayer) +// ); +// } +// } + +// contract Unit_DenominatedPriceOracleFactory_Constructor is Base { +// event AddAuthorization(address _account); + +// modifier happyPath() { +// vm.startPrank(user); +// _; +// } + +// function test_Emit_AddAuthorization() public happyPath { +// vm.expectEmit(); +// emit AddAuthorization(user); + +// denominatedOracleFactory = new DenominatedOracleFactory(); +// } +// } + +// contract Unit_DenominatedPriceOracleFactory_DeployDenominatedOracle is Base { +// event NewDenominatedOracle( +// address indexed _denominatedOracle, address _priceSource, address _denominationPriceSource, bool _inverted +// ); + +// address denominatedOracle = 0xb2A72B7BA8156A59fD84c61e5eF539d385D8652a; + +// modifier happyPath() { +// vm.startPrank(authorizedAccount); +// _; +// } + +// function setUp() public override { +// super.setUp(); +// vm.startPrank(authorizedAccount); +// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode('BaseToken')); +// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode('QuoteToken')); +// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode('Aggregator')); +// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(18)); +// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(18)); +// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(18)); + +// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, 100); +// _mockToken0(address(mockBaseToken)); +// _mockToken1(address(mockQuoteToken)); + +// vm.stopPrank(); +// } + +// function test_Deploy_RelayerChild() public happyPath { +// vm.expectEmit(); +// emit NewDenominatedOracle( +// address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), false +// ); +// denominatedOracleChild = +// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); + +// string memory symbol = +// string(abi.encodePacked('(', mockBaseToken.symbol(), ' / ', mockQuoteToken.symbol(), ') * (Aggregator)')); +// assertEq(denominatedOracleChild.symbol(), symbol); +// } + +// function test_Deploy_RelayerChildInverted() public happyPath { +// vm.expectEmit(); +// emit NewDenominatedOracle( +// address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), true +// ); +// denominatedOracleChild = +// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, true); + +// string memory symbol = +// string(abi.encodePacked('(', mockBaseToken.symbol(), ' / ', mockQuoteToken.symbol(), ')^-1 / (Aggregator)')); +// assertEq(denominatedOracleChild.symbol(), symbol); +// } + +// function test_Set_Relayers() public happyPath { +// denominatedOracleChild = +// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); +// assertEq(denominatedOracleFactory.oracleById(1), address(denominatedOracleChild)); +// } + +// function test_Emit_NewRelayer() public happyPath { +// vm.expectEmit(); +// emit NewDenominatedOracle( +// address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), false +// ); +// denominatedOracleChild = +// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); +// } + +// function test_Return_Relayer() public happyPath { +// assertEq( +// address(denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false)), +// address(denominatedOracle) +// ); +// } +// } + +// contract Unit_Pendle_Renzo_Deploy_Oracle is Base { +// address mainnetAuthorizedAccount = 0xF78dA2A37049627636546E0cFAaB2aD664950917; +// IPendleRelayerFactory public pendleFactory; + +// function setUp() public virtual override { +// super.setUp(); +// vm.createSelectFork(vm.envString('ARB_MAINNET_RPC')); +// delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); +// chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); +// denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); +// pendleFactory = IPendleRelayerFactory(address(new PendleRelayerFactory())); +// label(address(delayedOracleFactory), 'DelayedOracleFactory'); +// label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); +// label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); +// } + +// function test_DeployEzEthRelayer() public { +// vm.startPrank(mainnetAuthorizedAccount); +// IBaseOracle _ezEthEthPriceFeed = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( +// MAINNET_CHAINLINK_EZETH_ETH_FEED, +// MAINNET_CHAINLINK_SEQUENCER_FEED, +// MAINNET_ORACLE_DELAY, +// MAINNET_CHAINLINK_L2VALIDITY_GRACE_PERIOD +// ); + +// IBaseOracle _ezEthUsdOracle = denominatedOracleFactory.deployDenominatedOracle( +// _ezEthEthPriceFeed, IBaseOracle(MAINNET_CHAINLINK_ETH_USD_RELAYER), false +// ); + +// IBaseOracle _ezEthUsdDelayedOracle = delayedOracleFactory.deployDelayedOracle(_ezEthUsdOracle, MAINNET_ORACLE_DELAY); + +// string memory _ezEthSymbol = _ezEthUsdDelayedOracle.symbol(); // "(EZETH / ETH) * (ETH / USD)" +// vm.stopPrank(); +// assertEq(_ezEthSymbol, '(ezETH / ETH) * (ETH / USD)'); +// } + +// function test_Deploy_PendleFactory() public { +// assertEq(pendleFactory.relayerId(), 0); +// assertEq(pendleFactory.authorizedAccounts()[0], address(this)); +// } + +// function test_Deploy_PT_Oracle() public { +// IBaseOracle ptOracle = +// pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); +// assertTrue(keccak256(abi.encode(ptOracle.symbol())) != keccak256(abi.encode(''))); +// assertEq(uint256(IPendleRelayer(address(ptOracle)).twapDuration()), 900); +// assertEq(address(IPendleRelayer(address(ptOracle)).market()), MAINNET_PENDLE_RETH_MARKET); +// assertEq(address(IPendleRelayer(address(ptOracle)).oracle()), MAINNET_PENDLE_ORACLE); +// assertEq(address(IPendleRelayer(address(ptOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); +// assertEq(address(IPendleRelayer(address(ptOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); +// assertEq(address(IPendleRelayer(address(ptOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); +// } + +// function test_Deploy_YT_Oracle() public { +// IBaseOracle ytOracle = +// pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); +// assertTrue(keccak256(abi.encode(ytOracle.symbol())) != keccak256(abi.encode(''))); +// assertEq(uint256(IPendleRelayer(address(ytOracle)).twapDuration()), 900); +// assertEq(address(IPendleRelayer(address(ytOracle)).market()), MAINNET_PENDLE_RETH_MARKET); +// assertEq(address(IPendleRelayer(address(ytOracle)).oracle()), MAINNET_PENDLE_ORACLE); +// assertEq(address(IPendleRelayer(address(ytOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); +// assertEq(address(IPendleRelayer(address(ytOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); +// assertEq(address(IPendleRelayer(address(ytOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); +// } + +// function test_Deploy_LP_Oracle() public { +// IBaseOracle lpOracle = +// pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); +// assertTrue(keccak256(abi.encode(lpOracle.symbol())) != keccak256(abi.encode(''))); +// assertEq(uint256(IPendleRelayer(address(lpOracle)).twapDuration()), 900); +// assertEq(address(IPendleRelayer(address(lpOracle)).market()), MAINNET_PENDLE_RETH_MARKET); +// assertEq(address(IPendleRelayer(address(lpOracle)).oracle()), MAINNET_PENDLE_ORACLE); +// assertEq(address(IPendleRelayer(address(lpOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); +// assertEq(address(IPendleRelayer(address(lpOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); +// assertEq(address(IPendleRelayer(address(lpOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); +// } + +// function test_Deploy_Oracle_Revert_Invalid_Twap() public { +// vm.expectRevert('Invalid TWAP duration'); +// pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); +// vm.expectRevert('Invalid TWAP duration'); +// pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); +// vm.expectRevert('Invalid TWAP duration'); +// pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); +// } + +// function test_Deploy_Oracle_Revert_Invalid_Address() public { +// vm.expectRevert('Invalid address'); +// pendleFactory.deployPendlePtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); +// vm.expectRevert('Invalid address'); +// pendleFactory.deployPendleYtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); +// vm.expectRevert('Invalid address'); +// pendleFactory.deployPendleLpRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); +// } } diff --git a/test/utils/Create2Address.sol b/test/utils/Create2Address.sol index e54ede6..4cd9203 100644 --- a/test/utils/Create2Address.sol +++ b/test/utils/Create2Address.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; /// @title Provides functions for deriving a contract address using Create2 library Create2Address { diff --git a/test/utils/DSTestPlus.t.sol b/test/utils/DSTestPlus.t.sol index 56879c9..1935b20 100644 --- a/test/utils/DSTestPlus.t.sol +++ b/test/utils/DSTestPlus.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.7.6; +pragma solidity 0.8.26; pragma abicoder v2; import {Create2Address} from '@test/utils/Create2Address.sol'; From 7b39a3dba761ebb1dda287bdcba6afbcc1c9f6a2 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 19:27:31 -0500 Subject: [PATCH 03/11] fixed tests --- test/unit/RelayerFactories.t.sol | 570 +++++++++++++------------------ 1 file changed, 244 insertions(+), 326 deletions(-) diff --git a/test/unit/RelayerFactories.t.sol b/test/unit/RelayerFactories.t.sol index 5917159..96a9740 100644 --- a/test/unit/RelayerFactories.t.sol +++ b/test/unit/RelayerFactories.t.sol @@ -19,330 +19,248 @@ import {IPendleRelayerFactory} from '@interfaces/factories/IPendleRelayerFactory import {IPendleRelayer} from '@interfaces/oracles/pendle/IPendleRelayer.sol'; abstract contract Base is DSTestPlus { -// address deployer = label('deployer'); -// address authorizedAccount = label('authorizedAccount'); -// address user = label('user'); - -// IERC20Metadata mockBaseToken = IERC20Metadata(mockContract('BaseToken')); -// IERC20Metadata mockQuoteToken = IERC20Metadata(mockContract('QuoteToken')); - -// ChainlinkRelayerFactory chainlinkRelayerFactory; -// IBaseOracle chainlinkRelayerChild; - -// DenominatedOracleFactory denominatedOracleFactory; -// IBaseOracle denominatedOracleChild; - -// IDelayedOracleFactory delayedOracleFactory; -// IBaseOracle delayedOracleChild; - -// address mockAggregator = mockContract('ChainlinkAggregator'); - -// function setUp() public virtual { -// vm.startPrank(deployer); -// chainlinkRelayerFactory = new ChainlinkRelayerFactory(); -// label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); - -// chainlinkRelayerFactory.addAuthorization(authorizedAccount); - -// denominatedOracleFactory = new DenominatedOracleFactory(); -// label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); - -// denominatedOracleFactory.addAuthorization(authorizedAccount); - -// vm.stopPrank(); -// } - -// function _mockSymbol(string memory _symbol) internal { -// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); -// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); -// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode(_symbol)); -// } - -// function _mockDecimals(uint8 _decimals) internal { -// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); -// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); -// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); -// } -// } - -// contract Unit_ChainlinkRelayerFactory_Constructor is Base { -// event AddAuthorization(address _account); - -// modifier happyPath() { -// vm.startPrank(user); -// _; -// } - -// function test_Emit_AddAuthorization() public happyPath { -// vm.expectEmit(); -// emit AddAuthorization(user); - -// chainlinkRelayerFactory = new ChainlinkRelayerFactory(); -// } -// } - -// contract Unit_RelayerFactory_DeployChainlinkRelayer is Base { -// event NewChainlinkRelayer(address indexed _chainlinkRelayer, address _aggregator, uint256 _staleThreshold); - -// address chainlinkRelayer = 0x56D9e6a12fC3E3f589Ee5E685C9f118D62ce9C8D; - -// modifier happyPath(string memory _symbol, uint8 _decimals, uint256 _staleThreshold) { -// vm.startPrank(authorizedAccount); -// vm.assume(_staleThreshold > 0); -// _assumeHappyPath(_decimals); -// _mockSymbol(_symbol); -// _mockDecimals(_decimals); -// _; -// } - -// function _assumeHappyPath(uint8 _decimals) internal pure { -// vm.assume(_decimals <= 18 && _decimals > 0); -// } - -// function test_Deploy_RelayerChild( -// string memory _symbol, -// uint8 _decimals, -// uint256 _staleThreshold -// ) public happyPath(_symbol, _decimals, _staleThreshold) { -// vm.expectEmit(); -// emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); - -// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); -// assertEq(chainlinkRelayerChild.symbol(), _symbol); -// } - -// function test_Set_Relayers( -// string memory _symbol, -// uint8 _decimals, -// uint256 _staleThreshold -// ) public happyPath(_symbol, _decimals, _staleThreshold) { -// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); - -// assertEq(chainlinkRelayerFactory.relayerById(1), address(chainlinkRelayerChild)); -// } - -// function test_Set_Relayers_WithL2Validity( -// string memory _symbol, -// uint8 _decimals, -// uint256 _staleThreshold -// ) public happyPath(_symbol, _decimals, _staleThreshold) { -// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( -// mockAggregator, mockAggregator, _staleThreshold, _staleThreshold -// ); - -// assertEq(chainlinkRelayerFactory.relayerWithL2ValidityById(1), address(chainlinkRelayerChild)); -// } - -// function test_Emit_NewRelayer( -// string memory _symbol, -// uint8 _decimals, -// uint256 _staleThreshold -// ) public happyPath(_symbol, _decimals, _staleThreshold) { -// vm.expectEmit(); -// emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); - -// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); -// assertEq(chainlinkRelayerChild.symbol(), _symbol); -// } - -// function test_Return_Relayer( -// string memory _symbol, -// uint8 _decimals, -// uint256 _staleThreshold -// ) public happyPath(_symbol, _decimals, _staleThreshold) { -// assertEq( -// address(chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold)), -// address(chainlinkRelayer) -// ); -// } -// } - -// contract Unit_DenominatedPriceOracleFactory_Constructor is Base { -// event AddAuthorization(address _account); - -// modifier happyPath() { -// vm.startPrank(user); -// _; -// } - -// function test_Emit_AddAuthorization() public happyPath { -// vm.expectEmit(); -// emit AddAuthorization(user); - -// denominatedOracleFactory = new DenominatedOracleFactory(); -// } -// } - -// contract Unit_DenominatedPriceOracleFactory_DeployDenominatedOracle is Base { -// event NewDenominatedOracle( -// address indexed _denominatedOracle, address _priceSource, address _denominationPriceSource, bool _inverted -// ); - -// address denominatedOracle = 0xb2A72B7BA8156A59fD84c61e5eF539d385D8652a; - -// modifier happyPath() { -// vm.startPrank(authorizedAccount); -// _; -// } - -// function setUp() public override { -// super.setUp(); -// vm.startPrank(authorizedAccount); -// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode('BaseToken')); -// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode('QuoteToken')); -// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode('Aggregator')); -// vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(18)); -// vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(18)); -// vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(18)); - -// chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, 100); -// _mockToken0(address(mockBaseToken)); -// _mockToken1(address(mockQuoteToken)); - -// vm.stopPrank(); -// } - -// function test_Deploy_RelayerChild() public happyPath { -// vm.expectEmit(); -// emit NewDenominatedOracle( -// address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), false -// ); -// denominatedOracleChild = -// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); - -// string memory symbol = -// string(abi.encodePacked('(', mockBaseToken.symbol(), ' / ', mockQuoteToken.symbol(), ') * (Aggregator)')); -// assertEq(denominatedOracleChild.symbol(), symbol); -// } - -// function test_Deploy_RelayerChildInverted() public happyPath { -// vm.expectEmit(); -// emit NewDenominatedOracle( -// address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), true -// ); -// denominatedOracleChild = -// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, true); - -// string memory symbol = -// string(abi.encodePacked('(', mockBaseToken.symbol(), ' / ', mockQuoteToken.symbol(), ')^-1 / (Aggregator)')); -// assertEq(denominatedOracleChild.symbol(), symbol); -// } - -// function test_Set_Relayers() public happyPath { -// denominatedOracleChild = -// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); -// assertEq(denominatedOracleFactory.oracleById(1), address(denominatedOracleChild)); -// } - -// function test_Emit_NewRelayer() public happyPath { -// vm.expectEmit(); -// emit NewDenominatedOracle( -// address(denominatedOracle), address(camelotRelayerChild), address(chainlinkRelayerChild), false -// ); -// denominatedOracleChild = -// denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false); -// } - -// function test_Return_Relayer() public happyPath { -// assertEq( -// address(denominatedOracleFactory.deployDenominatedOracle(camelotRelayerChild, chainlinkRelayerChild, false)), -// address(denominatedOracle) -// ); -// } -// } - -// contract Unit_Pendle_Renzo_Deploy_Oracle is Base { -// address mainnetAuthorizedAccount = 0xF78dA2A37049627636546E0cFAaB2aD664950917; -// IPendleRelayerFactory public pendleFactory; - -// function setUp() public virtual override { -// super.setUp(); -// vm.createSelectFork(vm.envString('ARB_MAINNET_RPC')); -// delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); -// chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); -// denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); -// pendleFactory = IPendleRelayerFactory(address(new PendleRelayerFactory())); -// label(address(delayedOracleFactory), 'DelayedOracleFactory'); -// label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); -// label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); -// } - -// function test_DeployEzEthRelayer() public { -// vm.startPrank(mainnetAuthorizedAccount); -// IBaseOracle _ezEthEthPriceFeed = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( -// MAINNET_CHAINLINK_EZETH_ETH_FEED, -// MAINNET_CHAINLINK_SEQUENCER_FEED, -// MAINNET_ORACLE_DELAY, -// MAINNET_CHAINLINK_L2VALIDITY_GRACE_PERIOD -// ); - -// IBaseOracle _ezEthUsdOracle = denominatedOracleFactory.deployDenominatedOracle( -// _ezEthEthPriceFeed, IBaseOracle(MAINNET_CHAINLINK_ETH_USD_RELAYER), false -// ); - -// IBaseOracle _ezEthUsdDelayedOracle = delayedOracleFactory.deployDelayedOracle(_ezEthUsdOracle, MAINNET_ORACLE_DELAY); - -// string memory _ezEthSymbol = _ezEthUsdDelayedOracle.symbol(); // "(EZETH / ETH) * (ETH / USD)" -// vm.stopPrank(); -// assertEq(_ezEthSymbol, '(ezETH / ETH) * (ETH / USD)'); -// } - -// function test_Deploy_PendleFactory() public { -// assertEq(pendleFactory.relayerId(), 0); -// assertEq(pendleFactory.authorizedAccounts()[0], address(this)); -// } - -// function test_Deploy_PT_Oracle() public { -// IBaseOracle ptOracle = -// pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); -// assertTrue(keccak256(abi.encode(ptOracle.symbol())) != keccak256(abi.encode(''))); -// assertEq(uint256(IPendleRelayer(address(ptOracle)).twapDuration()), 900); -// assertEq(address(IPendleRelayer(address(ptOracle)).market()), MAINNET_PENDLE_RETH_MARKET); -// assertEq(address(IPendleRelayer(address(ptOracle)).oracle()), MAINNET_PENDLE_ORACLE); -// assertEq(address(IPendleRelayer(address(ptOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); -// assertEq(address(IPendleRelayer(address(ptOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); -// assertEq(address(IPendleRelayer(address(ptOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); -// } - -// function test_Deploy_YT_Oracle() public { -// IBaseOracle ytOracle = -// pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); -// assertTrue(keccak256(abi.encode(ytOracle.symbol())) != keccak256(abi.encode(''))); -// assertEq(uint256(IPendleRelayer(address(ytOracle)).twapDuration()), 900); -// assertEq(address(IPendleRelayer(address(ytOracle)).market()), MAINNET_PENDLE_RETH_MARKET); -// assertEq(address(IPendleRelayer(address(ytOracle)).oracle()), MAINNET_PENDLE_ORACLE); -// assertEq(address(IPendleRelayer(address(ytOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); -// assertEq(address(IPendleRelayer(address(ytOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); -// assertEq(address(IPendleRelayer(address(ytOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); -// } - -// function test_Deploy_LP_Oracle() public { -// IBaseOracle lpOracle = -// pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); -// assertTrue(keccak256(abi.encode(lpOracle.symbol())) != keccak256(abi.encode(''))); -// assertEq(uint256(IPendleRelayer(address(lpOracle)).twapDuration()), 900); -// assertEq(address(IPendleRelayer(address(lpOracle)).market()), MAINNET_PENDLE_RETH_MARKET); -// assertEq(address(IPendleRelayer(address(lpOracle)).oracle()), MAINNET_PENDLE_ORACLE); -// assertEq(address(IPendleRelayer(address(lpOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); -// assertEq(address(IPendleRelayer(address(lpOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); -// assertEq(address(IPendleRelayer(address(lpOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); -// } - -// function test_Deploy_Oracle_Revert_Invalid_Twap() public { -// vm.expectRevert('Invalid TWAP duration'); -// pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); -// vm.expectRevert('Invalid TWAP duration'); -// pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); -// vm.expectRevert('Invalid TWAP duration'); -// pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); -// } - -// function test_Deploy_Oracle_Revert_Invalid_Address() public { -// vm.expectRevert('Invalid address'); -// pendleFactory.deployPendlePtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); -// vm.expectRevert('Invalid address'); -// pendleFactory.deployPendleYtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); -// vm.expectRevert('Invalid address'); -// pendleFactory.deployPendleLpRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); -// } + address deployer = label('deployer'); + address authorizedAccount = label('authorizedAccount'); + address user = label('user'); + + IERC20Metadata mockBaseToken = IERC20Metadata(mockContract('BaseToken')); + IERC20Metadata mockQuoteToken = IERC20Metadata(mockContract('QuoteToken')); + + ChainlinkRelayerFactory chainlinkRelayerFactory; + IBaseOracle chainlinkRelayerChild; + + DenominatedOracleFactory denominatedOracleFactory; + IBaseOracle denominatedOracleChild; + + IDelayedOracleFactory delayedOracleFactory; + IBaseOracle delayedOracleChild; + + address mockAggregator = mockContract('ChainlinkAggregator'); + + function setUp() public virtual { + vm.startPrank(deployer); + chainlinkRelayerFactory = new ChainlinkRelayerFactory(); + label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); + + chainlinkRelayerFactory.addAuthorization(authorizedAccount); + + denominatedOracleFactory = new DenominatedOracleFactory(); + label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); + + denominatedOracleFactory.addAuthorization(authorizedAccount); + + vm.stopPrank(); + } + + function _mockSymbol(string memory _symbol) internal { + vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); + vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('symbol()'), abi.encode(_symbol)); + vm.mockCall(address(mockAggregator), abi.encodeWithSignature('description()'), abi.encode(_symbol)); + } + + function _mockDecimals(uint8 _decimals) internal { + vm.mockCall(address(mockBaseToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); + vm.mockCall(address(mockQuoteToken), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); + vm.mockCall(address(mockAggregator), abi.encodeWithSignature('decimals()'), abi.encode(_decimals)); + } +} + +contract Unit_ChainlinkRelayerFactory_Constructor is Base { + event AddAuthorization(address _account); + + modifier happyPath() { + vm.startPrank(user); + _; + } + + function test_Emit_AddAuthorization() public happyPath { + vm.expectEmit(); + emit AddAuthorization(user); + + chainlinkRelayerFactory = new ChainlinkRelayerFactory(); + } +} + +contract Unit_RelayerFactory_DeployChainlinkRelayer is Base { + event NewChainlinkRelayer(address indexed _chainlinkRelayer, address _aggregator, uint256 _staleThreshold); + + address chainlinkRelayer = 0x7F85e9e000597158AED9320B5A5E11AB8cC7329A; //0x56D9e6a12fC3E3f589Ee5E685C9f118D62ce9C8D; + + modifier happyPath(string memory _symbol, uint8 _decimals, uint256 _staleThreshold) { + vm.startPrank(authorizedAccount); + vm.assume(_staleThreshold > 0); + _assumeHappyPath(_decimals); + _mockSymbol(_symbol); + _mockDecimals(_decimals); + _; + } + + function _assumeHappyPath(uint8 _decimals) internal pure { + vm.assume(_decimals <= 18 && _decimals > 0); + } + + function test_Deploy_RelayerChild( + string memory _symbol, + uint8 _decimals, + uint256 _staleThreshold + ) public happyPath(_symbol, _decimals, _staleThreshold) { + vm.expectEmit(); + emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); + + chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); + assertEq(chainlinkRelayerChild.symbol(), _symbol); + } + + function test_Set_Relayers( + string memory _symbol, + uint8 _decimals, + uint256 _staleThreshold + ) public happyPath(_symbol, _decimals, _staleThreshold) { + chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); + + assertEq(chainlinkRelayerFactory.relayerById(1), address(chainlinkRelayerChild)); + } + + function test_Set_Relayers_WithL2Validity( + string memory _symbol, + uint8 _decimals, + uint256 _staleThreshold + ) public happyPath(_symbol, _decimals, _staleThreshold) { + chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( + mockAggregator, mockAggregator, _staleThreshold, _staleThreshold + ); + + assertEq(chainlinkRelayerFactory.relayerWithL2ValidityById(1), address(chainlinkRelayerChild)); + } + + function test_Emit_NewRelayer( + string memory _symbol, + uint8 _decimals, + uint256 _staleThreshold + ) public happyPath(_symbol, _decimals, _staleThreshold) { + vm.expectEmit(); + emit NewChainlinkRelayer(address(chainlinkRelayer), mockAggregator, _staleThreshold); + + chainlinkRelayerChild = chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold); + assertEq(chainlinkRelayerChild.symbol(), _symbol); + } + + function test_Return_Relayer( + string memory _symbol, + uint8 _decimals, + uint256 _staleThreshold + ) public happyPath(_symbol, _decimals, _staleThreshold) { + assertEq( + address(chainlinkRelayerFactory.deployChainlinkRelayer(mockAggregator, _staleThreshold)), + address(chainlinkRelayer) + ); + } +} + +contract Unit_DenominatedPriceOracleFactory_Constructor is Base { + event AddAuthorization(address _account); + + modifier happyPath() { + vm.startPrank(user); + _; + } + + function test_Emit_AddAuthorization() public happyPath { + vm.expectEmit(); + emit AddAuthorization(user); + + denominatedOracleFactory = new DenominatedOracleFactory(); + } +} + +contract Unit_Pendle_Renzo_Deploy_Oracle is Base { + address mainnetAuthorizedAccount = 0xF78dA2A37049627636546E0cFAaB2aD664950917; + IPendleRelayerFactory public pendleFactory; + + function setUp() public virtual override { + super.setUp(); + vm.createSelectFork(vm.envString('ARB_MAINNET_RPC')); + delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); + chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); + denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); + pendleFactory = IPendleRelayerFactory(address(new PendleRelayerFactory())); + label(address(delayedOracleFactory), 'DelayedOracleFactory'); + label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); + label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); + } + + function test_DeployEzEthRelayer() public { + vm.startPrank(mainnetAuthorizedAccount); + IBaseOracle _ezEthEthPriceFeed = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( + MAINNET_CHAINLINK_EZETH_ETH_FEED, + MAINNET_CHAINLINK_SEQUENCER_FEED, + MAINNET_ORACLE_DELAY, + MAINNET_CHAINLINK_L2VALIDITY_GRACE_PERIOD + ); + + IBaseOracle _ezEthUsdOracle = denominatedOracleFactory.deployDenominatedOracle( + _ezEthEthPriceFeed, IBaseOracle(MAINNET_CHAINLINK_ETH_USD_RELAYER), false + ); + + IBaseOracle _ezEthUsdDelayedOracle = delayedOracleFactory.deployDelayedOracle(_ezEthUsdOracle, MAINNET_ORACLE_DELAY); + + string memory _ezEthSymbol = _ezEthUsdDelayedOracle.symbol(); // "(EZETH / ETH) * (ETH / USD)" + vm.stopPrank(); + assertEq(_ezEthSymbol, '(ezETH / ETH) * (ETH / USD)'); + } + + function test_Deploy_PendleFactory() public view { + assertEq(pendleFactory.relayerId(), 0); + assertEq(pendleFactory.authorizedAccounts()[0], address(this)); + } + + function test_Deploy_PT_Oracle() public { + IBaseOracle ptOracle = + pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); + assertTrue(keccak256(abi.encode(ptOracle.symbol())) != keccak256(abi.encode(''))); + assertEq(uint256(IPendleRelayer(address(ptOracle)).twapDuration()), 900); + assertEq(address(IPendleRelayer(address(ptOracle)).market()), MAINNET_PENDLE_RETH_MARKET); + assertEq(address(IPendleRelayer(address(ptOracle)).oracle()), MAINNET_PENDLE_ORACLE); + assertEq(address(IPendleRelayer(address(ptOracle)).PT()), 0x685155D3BD593508Fe32Be39729810A591ED9c87); + assertEq(address(IPendleRelayer(address(ptOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); + } + + function test_Deploy_YT_Oracle() public { + IBaseOracle ytOracle = + pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); + assertTrue(keccak256(abi.encode(ytOracle.symbol())) != keccak256(abi.encode(''))); + assertEq(uint256(IPendleRelayer(address(ytOracle)).twapDuration()), 900); + assertEq(address(IPendleRelayer(address(ytOracle)).market()), MAINNET_PENDLE_RETH_MARKET); + assertEq(address(IPendleRelayer(address(ytOracle)).oracle()), MAINNET_PENDLE_ORACLE); + assertEq(address(IPendleRelayer(address(ytOracle)).YT()), 0xe822AE44EB2466B4E263b1cbC94b4833dDEf9700); + assertEq(address(IPendleRelayer(address(ytOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); + } + + function test_Deploy_LP_Oracle() public { + IBaseOracle lpOracle = + pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(900)); + assertTrue(keccak256(abi.encode(lpOracle.symbol())) != keccak256(abi.encode(''))); + assertEq(uint256(IPendleRelayer(address(lpOracle)).twapDuration()), 900); + assertEq(address(IPendleRelayer(address(lpOracle)).market()), MAINNET_PENDLE_RETH_MARKET); + assertEq(address(IPendleRelayer(address(lpOracle)).oracle()), MAINNET_PENDLE_ORACLE); + assertEq(address(IPendleRelayer(address(lpOracle)).SY()), 0xc0Cf4b266bE5B3229C49590B59E67A09c15b22f4); + } + + function test_Deploy_Oracle_Revert_Invalid_Twap() public { + vm.expectRevert('Invalid TWAP duration'); + pendleFactory.deployPendlePtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); + vm.expectRevert('Invalid TWAP duration'); + pendleFactory.deployPendleYtRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); + vm.expectRevert('Invalid TWAP duration'); + pendleFactory.deployPendleLpRelayer(MAINNET_PENDLE_RETH_MARKET, MAINNET_PENDLE_ORACLE, uint32(0)); + } + + function test_Deploy_Oracle_Revert_Invalid_Address() public { + vm.expectRevert('Invalid address'); + pendleFactory.deployPendlePtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); + vm.expectRevert('Invalid address'); + pendleFactory.deployPendleYtRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); + vm.expectRevert('Invalid address'); + pendleFactory.deployPendleLpRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); + } } From 3c70c0eabaac3f655f77c82f97a6b359a155b9d8 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 20:03:21 -0500 Subject: [PATCH 04/11] added templates for factory and oracle --- .vscode/settings.json | 3 ++ gmx-synthetics | 1 + .../factories/gmx/GMXGmRelayerChild.sol | 16 ++++++++++ .../factories/gmx/GMXRelayerFactory.sol | 29 +++++++++++++++++++ src/contracts/oracles/gmx/GMXGmRelayer.sol | 22 ++++++++++++++ 5 files changed, 71 insertions(+) create mode 100644 .vscode/settings.json create mode 160000 gmx-synthetics create mode 100644 src/contracts/factories/gmx/GMXGmRelayerChild.sol create mode 100644 src/contracts/factories/gmx/GMXRelayerFactory.sol create mode 100644 src/contracts/oracles/gmx/GMXGmRelayer.sol diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8e94afc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "solidity.compileUsingRemoteVersion": "v0.8.26+commit.8a97fa7a" +} diff --git a/gmx-synthetics b/gmx-synthetics new file mode 160000 index 0000000..5173cbe --- /dev/null +++ b/gmx-synthetics @@ -0,0 +1 @@ +Subproject commit 5173cbeb196ed5596373acd71c75a5c7a60a98f5 diff --git a/src/contracts/factories/gmx/GMXGmRelayerChild.sol b/src/contracts/factories/gmx/GMXGmRelayerChild.sol new file mode 100644 index 0000000..da5e03f --- /dev/null +++ b/src/contracts/factories/gmx/GMXGmRelayerChild.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.26; + +import {GMXGmRelayer} from '@contracts/oracles/gmx/GMXGmRelayer.sol'; +import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; + +contract GMXGmRelayerChild is GMXGmRelayer, FactoryChild { + // --- Init --- + + /** + * @param _market The address pendle market + * @param _oracle The address of the pendle oracle + * @param _twapDuration the amount in seconds of the desired twap observations (recommended 900s) + */ + constructor() GMXGmRelayer() {} +} diff --git a/src/contracts/factories/gmx/GMXRelayerFactory.sol b/src/contracts/factories/gmx/GMXRelayerFactory.sol new file mode 100644 index 0000000..4c46381 --- /dev/null +++ b/src/contracts/factories/gmx/GMXRelayerFactory.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.26; + +import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; +import {Authorizable} from '@contracts/utils/Authorizable.sol'; +import {GMXGmRelayerChild} from './GMXGmRelayerChild.sol'; +import 'forge-std/console2.sol'; + +contract PendleRelayerFactory is Authorizable { + uint256 public relayerId; + + // --- Events --- + event NewGMXGmRelayer(address indexed _market, address _oracle, uint32 _twapDuration); + + // --- Data --- + mapping(uint256 => address) public relayerById; + + // --- Init --- + constructor() Authorizable(msg.sender) {} + + // --- Methods --- + + function deployGMXGmRelayer(address market) external isAuthorized returns (IBaseOracle _pendlePtRelayerChild) { + _gmxGmRelayerChild = IBaseOracle(address(0)); + relayerId++; + relayerById[relayerId] = address(_pendlePtRelayerChild); + emit NewPendlePtRelayer(address(_market), _oracle, _twapDuration); + } +} diff --git a/src/contracts/oracles/gmx/GMXGmRelayer.sol b/src/contracts/oracles/gmx/GMXGmRelayer.sol new file mode 100644 index 0000000..9ac5d76 --- /dev/null +++ b/src/contracts/oracles/gmx/GMXGmRelayer.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.26; + +/** + * @title PendleRelayer + * @notice This contracts transforms a Pendle TWAP price feed into a standard IBaseOracle feed + * + */ +contract GMXGmRelayer { + string public symbol; + + constructor(address _market, address _oracle, uint32 _twapDuration) {} + + function getResultWithValidity() external view returns (uint256 _result, bool _validity) { + _result; + _validity = true; + } + + function read() external view returns (uint256 _value) { + _value; + } +} From 4d30bb5a6ef5b5d171c4493d4c47eb8cb1a72402 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 20:12:26 -0500 Subject: [PATCH 05/11] added gmx contracts submodule --- .gitmodules | 3 +++ gmx-synthetics => lib/gmx-synthetics | 0 src/contracts/factories/gmx/GMXGmRelayerChild.sol | 3 --- src/contracts/factories/gmx/GMXRelayerFactory.sol | 8 ++++---- src/contracts/oracles/gmx/GMXGmRelayer.sol | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename gmx-synthetics => lib/gmx-synthetics (100%) diff --git a/.gitmodules b/.gitmodules index 8269a2b..23317f9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ url = https://github.com/foundry-rs/forge-std [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts +[submodule "lib/gmx-synthetics"] + path = lib/gmx-synthetics + url = https://github.com/gmx-io/gmx-synthetics.git diff --git a/gmx-synthetics b/lib/gmx-synthetics similarity index 100% rename from gmx-synthetics rename to lib/gmx-synthetics diff --git a/src/contracts/factories/gmx/GMXGmRelayerChild.sol b/src/contracts/factories/gmx/GMXGmRelayerChild.sol index da5e03f..f20ae5b 100644 --- a/src/contracts/factories/gmx/GMXGmRelayerChild.sol +++ b/src/contracts/factories/gmx/GMXGmRelayerChild.sol @@ -8,9 +8,6 @@ contract GMXGmRelayerChild is GMXGmRelayer, FactoryChild { // --- Init --- /** - * @param _market The address pendle market - * @param _oracle The address of the pendle oracle - * @param _twapDuration the amount in seconds of the desired twap observations (recommended 900s) */ constructor() GMXGmRelayer() {} } diff --git a/src/contracts/factories/gmx/GMXRelayerFactory.sol b/src/contracts/factories/gmx/GMXRelayerFactory.sol index 4c46381..3033ec3 100644 --- a/src/contracts/factories/gmx/GMXRelayerFactory.sol +++ b/src/contracts/factories/gmx/GMXRelayerFactory.sol @@ -10,7 +10,7 @@ contract PendleRelayerFactory is Authorizable { uint256 public relayerId; // --- Events --- - event NewGMXGmRelayer(address indexed _market, address _oracle, uint32 _twapDuration); + event NewGMXGmRelayer(); // --- Data --- mapping(uint256 => address) public relayerById; @@ -20,10 +20,10 @@ contract PendleRelayerFactory is Authorizable { // --- Methods --- - function deployGMXGmRelayer(address market) external isAuthorized returns (IBaseOracle _pendlePtRelayerChild) { + function deployGMXGmRelayer(address market) external isAuthorized returns (IBaseOracle _gmxGmRelayerChild) { _gmxGmRelayerChild = IBaseOracle(address(0)); relayerId++; - relayerById[relayerId] = address(_pendlePtRelayerChild); - emit NewPendlePtRelayer(address(_market), _oracle, _twapDuration); + relayerById[relayerId] = address(_gmxGmRelayerChild); + emit NewGMXGmRelayer(); } } diff --git a/src/contracts/oracles/gmx/GMXGmRelayer.sol b/src/contracts/oracles/gmx/GMXGmRelayer.sol index 9ac5d76..fab60c5 100644 --- a/src/contracts/oracles/gmx/GMXGmRelayer.sol +++ b/src/contracts/oracles/gmx/GMXGmRelayer.sol @@ -9,7 +9,7 @@ pragma solidity 0.8.26; contract GMXGmRelayer { string public symbol; - constructor(address _market, address _oracle, uint32 _twapDuration) {} + constructor() {} function getResultWithValidity() external view returns (uint256 _result, bool _validity) { _result; From b06c3ec3434bbf977098deb931428cc3201d59a3 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 21:43:26 -0500 Subject: [PATCH 06/11] adding gmx interfaces and libraries --- remappings.txt | 1 + .../factories/gmx/GMXGmRelayerChild.sol | 13 --------- .../factories/gmx/GMXRelayerFactory.sol | 29 ------------------- src/contracts/oracles/gmx/GMXGmRelayer.sol | 22 -------------- 4 files changed, 1 insertion(+), 64 deletions(-) delete mode 100644 src/contracts/factories/gmx/GMXGmRelayerChild.sol delete mode 100644 src/contracts/factories/gmx/GMXRelayerFactory.sol delete mode 100644 src/contracts/oracles/gmx/GMXGmRelayer.sol diff --git a/remappings.txt b/remappings.txt index 24d88ba..3d7abe1 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,5 +1,6 @@ @openzeppelin/=lib/openzeppelin-contracts/ @isolmate/=lib/isolmate/src/ +@gmx/=lib/gmx-synthetics/ @script/=script/ @contracts/=src/contracts/ diff --git a/src/contracts/factories/gmx/GMXGmRelayerChild.sol b/src/contracts/factories/gmx/GMXGmRelayerChild.sol deleted file mode 100644 index f20ae5b..0000000 --- a/src/contracts/factories/gmx/GMXGmRelayerChild.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.26; - -import {GMXGmRelayer} from '@contracts/oracles/gmx/GMXGmRelayer.sol'; -import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; - -contract GMXGmRelayerChild is GMXGmRelayer, FactoryChild { - // --- Init --- - - /** - */ - constructor() GMXGmRelayer() {} -} diff --git a/src/contracts/factories/gmx/GMXRelayerFactory.sol b/src/contracts/factories/gmx/GMXRelayerFactory.sol deleted file mode 100644 index 3033ec3..0000000 --- a/src/contracts/factories/gmx/GMXRelayerFactory.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.26; - -import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; -import {Authorizable} from '@contracts/utils/Authorizable.sol'; -import {GMXGmRelayerChild} from './GMXGmRelayerChild.sol'; -import 'forge-std/console2.sol'; - -contract PendleRelayerFactory is Authorizable { - uint256 public relayerId; - - // --- Events --- - event NewGMXGmRelayer(); - - // --- Data --- - mapping(uint256 => address) public relayerById; - - // --- Init --- - constructor() Authorizable(msg.sender) {} - - // --- Methods --- - - function deployGMXGmRelayer(address market) external isAuthorized returns (IBaseOracle _gmxGmRelayerChild) { - _gmxGmRelayerChild = IBaseOracle(address(0)); - relayerId++; - relayerById[relayerId] = address(_gmxGmRelayerChild); - emit NewGMXGmRelayer(); - } -} diff --git a/src/contracts/oracles/gmx/GMXGmRelayer.sol b/src/contracts/oracles/gmx/GMXGmRelayer.sol deleted file mode 100644 index fab60c5..0000000 --- a/src/contracts/oracles/gmx/GMXGmRelayer.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.26; - -/** - * @title PendleRelayer - * @notice This contracts transforms a Pendle TWAP price feed into a standard IBaseOracle feed - * - */ -contract GMXGmRelayer { - string public symbol; - - constructor() {} - - function getResultWithValidity() external view returns (uint256 _result, bool _validity) { - _result; - _validity = true; - } - - function read() external view returns (uint256 _value) { - _value; - } -} From 0cfe2e72a4167389d94cbcb7495291baf76ae6bc Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 21:43:36 -0500 Subject: [PATCH 07/11] adding gmx interfaces and libraries --- .../factories/gmx/GmxGmRelayerChild.sol | 17 + .../factories/gmx/GmxRelayerFactory.sol | 33 ++ src/contracts/oracles/gmx/GmxGmRelayer.sol | 48 +++ src/interfaces/oracles/gmx/IGmxDataStore.sol | 22 + src/interfaces/oracles/gmx/IGmxReader.sol | 387 ++++++++++++++++++ src/interfaces/oracles/gmx/IGmxRoleStore.sol | 20 + src/libraries/gmx/GmxDeposit.sol | 60 +++ src/libraries/gmx/GmxMarket.sol | 24 ++ src/libraries/gmx/GmxMarketPoolValueInfo.sol | 36 ++ src/libraries/gmx/GmxPrice.sol | 13 + src/libraries/gmx/GmxWithdrawal.sol | 57 +++ 11 files changed, 717 insertions(+) create mode 100644 src/contracts/factories/gmx/GmxGmRelayerChild.sol create mode 100644 src/contracts/factories/gmx/GmxRelayerFactory.sol create mode 100644 src/contracts/oracles/gmx/GmxGmRelayer.sol create mode 100644 src/interfaces/oracles/gmx/IGmxDataStore.sol create mode 100644 src/interfaces/oracles/gmx/IGmxReader.sol create mode 100644 src/interfaces/oracles/gmx/IGmxRoleStore.sol create mode 100644 src/libraries/gmx/GmxDeposit.sol create mode 100644 src/libraries/gmx/GmxMarket.sol create mode 100644 src/libraries/gmx/GmxMarketPoolValueInfo.sol create mode 100644 src/libraries/gmx/GmxPrice.sol create mode 100644 src/libraries/gmx/GmxWithdrawal.sol diff --git a/src/contracts/factories/gmx/GmxGmRelayerChild.sol b/src/contracts/factories/gmx/GmxGmRelayerChild.sol new file mode 100644 index 0000000..1e9567c --- /dev/null +++ b/src/contracts/factories/gmx/GmxGmRelayerChild.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.26; + +import {GmxGmRelayer} from '@contracts/oracles/gmx/GmxGmRelayer.sol'; +import {FactoryChild} from '@contracts/factories/FactoryChild.sol'; + +contract GmxGmRelayerChild is GmxGmRelayer, FactoryChild { + // --- Init --- + + /** + */ + constructor( + address _marketToken, + address _gmxReader, + address _dataStore + ) GmxGmRelayer(_marketToken, _gmxReader, _dataStore) {} +} diff --git a/src/contracts/factories/gmx/GmxRelayerFactory.sol b/src/contracts/factories/gmx/GmxRelayerFactory.sol new file mode 100644 index 0000000..d6b7d1f --- /dev/null +++ b/src/contracts/factories/gmx/GmxRelayerFactory.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.26; + +import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; +import {Authorizable} from '@contracts/utils/Authorizable.sol'; +import {GmxGmRelayerChild} from './GmxGmRelayerChild.sol'; +import 'forge-std/console2.sol'; + +contract PendleRelayerFactory is Authorizable { + uint256 public relayerId; + + // --- Events --- + event NewGmxGmRelayer(address _newGmxRelayerChild, address _marketToken); + + // --- Data --- + mapping(uint256 => address) public relayerById; + + // --- Init --- + constructor() Authorizable(msg.sender) {} + + // --- Methods --- + + function deployGmxGmRelayer( + address _marketToken, + address _gmxReader, + address _dataStore + ) external isAuthorized returns (IBaseOracle _gmxGmRelayerChild) { + _gmxGmRelayerChild = IBaseOracle(address(new GmxGmRelayerChild(_marketToken, _gmxReader, _dataStore))); + relayerId++; + relayerById[relayerId] = address(_gmxGmRelayerChild); + emit NewGmxGmRelayer(address(_gmxGmRelayerChild), _marketToken); + } +} diff --git a/src/contracts/oracles/gmx/GmxGmRelayer.sol b/src/contracts/oracles/gmx/GmxGmRelayer.sol new file mode 100644 index 0000000..f4a9080 --- /dev/null +++ b/src/contracts/oracles/gmx/GmxGmRelayer.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity 0.8.26; + +import {OracleUtils} from '@gmx/contracts/oracle/OracleUtils.sol'; +import {IOracleProvider} from '@gmx/contracts/oracle/IOracleProvider.sol'; +import {GmxPrice} from '@libraries/gmx/GmxPrice.sol'; +import {IGmxDataStore} from '@interfaces/oracles/gmx/IGmxDataStore.sol'; + +/** + * @title GmxGmRelayer + * @notice This contracts transforms a Gmx GM oracle into a standard IBaseOracle feed + * + */ +contract GmxGmRelayer { + string public symbol; + + // ============================ Constants ============================ + + /// @dev All of the GM tokens listed have, at-worst, 25 bp for the price deviation + uint256 public constant PRICE_DEVIATION_BP = 25; + uint256 public constant BASIS_POINTS = 10_000; + uint256 public constant SUPPLY_CAP_USAGE_NUMERATOR = 5; + uint256 public constant SUPPLY_CAP_USAGE_DENOMINATOR = 100; + uint256 public constant Gmx_DECIMAL_ADJUSTMENT = 10 ** 6; + uint256 public constant RETURN_DECIMAL_ADJUSTMENT = 10 ** 12; + uint256 public constant FEE_FACTOR_DECIMAL_ADJUSTMENT = 10 ** 26; + + bytes32 public constant MAX_PNL_FACTOR_FOR_DEPOSITS_KEY = keccak256(abi.encode('MAX_PNL_FACTOR_FOR_DEPOSITS')); // solhint-disable-line max-line-length + bytes32 public constant SWAP_FEE_FACTOR_KEY = keccak256(abi.encode('SWAP_FEE_FACTOR')); + bytes32 public constant SWAP_FEE_RECEIVER_FACTOR_KEY = keccak256(abi.encode('SWAP_FEE_RECEIVER_FACTOR')); + + address marketToken; + IGmxDataStore dataStore; + + constructor(address _marketToken, address _gmxReader, address _dataStore) { + marketToken = _marketToken; + dataStore = IGmxDataStore(_dataStore); + } + + function getResultWithValidity() external view returns (uint256 _result, bool _validity) { + _result; + _validity = true; + } + + function read() external view returns (uint256 _value) { + _value; + } +} diff --git a/src/interfaces/oracles/gmx/IGmxDataStore.sol b/src/interfaces/oracles/gmx/IGmxDataStore.sol new file mode 100644 index 0000000..f7ab1a1 --- /dev/null +++ b/src/interfaces/oracles/gmx/IGmxDataStore.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity ^0.8.9; + +import {IGmxRoleStore} from './IGmxRoleStore.sol'; + +/** + * @title IGmxDataStore + * + * @notice Gmx DataStore interface + */ +interface IGmxDataStore { + function setUint(bytes32 _key, uint256 _value) external returns (uint256); + + function setBool(bytes32 _key, bool _bool) external returns (bool); + + function getBool(bytes32 _key) external view returns (bool); + + function getUint(bytes32 _key) external view returns (uint256); + + function roleStore() external view returns (IGmxRoleStore); +} diff --git a/src/interfaces/oracles/gmx/IGmxReader.sol b/src/interfaces/oracles/gmx/IGmxReader.sol new file mode 100644 index 0000000..f98e207 --- /dev/null +++ b/src/interfaces/oracles/gmx/IGmxReader.sol @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.9; + +import {IGmxDataStore} from './IGmxDataStore.sol'; +import {GmxDeposit} from '@libraries/gmx/GmxDeposit.sol'; +import {GmxMarket} from '@libraries/gmx/GmxMarket.sol'; +import {GmxMarketPoolValueInfo} from '@libraries/gmx/GmxMarketPoolValueInfo.sol'; +import {GmxPrice} from '@libraries/gmx/GmxPrice.sol'; +import {GmxWithdrawal} from '@libraries/gmx/GmxWithdrawal.sol'; + +/** + * @title IGmxReader + * + * @notice GMX Reader Interface + */ +interface IGmxReader { + enum SwapPricingType { + TwoStep, + Shift, + Atomic + } + + // ================ Errors ================ + + // AdlHandler errors + error AdlNotRequired(int256 pnlToPoolFactor, uint256 maxPnlFactorForAdl); + error InvalidAdl(int256 nextPnlToPoolFactor, int256 pnlToPoolFactor); + error PnlOvercorrected(int256 nextPnlToPoolFactor, uint256 minPnlFactorForAdl); + + // AdlUtils errors + error InvalidSizeDeltaForAdl(uint256 sizeDeltaUsd, uint256 positionSizeInUsd); + error AdlNotEnabled(); + + // Bank errors + error SelfTransferNotSupported(address receiver); + error InvalidNativeTokenSender(address msgSender); + + // BaseRouter + error CouldNotSendNativeToken(address receiver, uint256 amount); + + // CallbackUtils errors + error MaxCallbackGasLimitExceeded(uint256 callbackGasLimit, uint256 maxCallbackGasLimit); + + // Config errors + error InvalidBaseKey(bytes32 baseKey); + error InvalidFeeFactor(bytes32 baseKey, uint256 value); + + // Timelock errors + error ActionAlreadySignalled(); + error ActionNotSignalled(); + error SignalTimeNotYetPassed(uint256 signalTime); + error InvalidTimelockDelay(uint256 timelockDelay); + error MaxTimelockDelayExceeded(uint256 timelockDelay); + error InvalidFeeReceiver(address receiver); + error InvalidOracleSigner(address receiver); + + // DepositStoreUtils errors + error DepositNotFound(bytes32 key); + + // DepositUtils errors + error EmptyDeposit(); + error EmptyDepositAmounts(); + + // ExecuteDepositUtils errors + error MinMarketTokens(uint256 received, uint256 expected); + error EmptyDepositAmountsAfterSwap(); + error InvalidPoolValueForDeposit(int256 poolValue); + error InvalidSwapOutputToken(address outputToken, address expectedOutputToken); + error InvalidReceiverForFirstDeposit(address receiver, address expectedReceiver); + error InvalidMinMarketTokensForFirstDeposit(uint256 minMarketTokens, uint256 expectedMinMarketTokens); + + // ExchangeUtils errors + error RequestNotYetCancellable(uint256 requestAge, uint256 requestExpirationAge, string requestType); + + // GlpMigrator errors + error InvalidGlpAmount(uint256 totalGlpAmountToRedeem, uint256 totalGlpAmount); + error InvalidLongTokenForMigration(address market, address migrationLongToken, address marketLongToken); + error InvalidShortTokenForMigration(address market, address migrationShortToken, address marketShortToken); + + // OrderHandler errors + error OrderNotUpdatable(uint256 orderType); + error InvalidKeeperForFrozenOrder(address keeper); + + // FeatureUtils errors + error DisabledFeature(bytes32 key); + + // FeeHandler errors + error InvalidClaimFeesInput(uint256 marketsLength, uint256 tokensLength); + + // GasUtils errors + error InsufficientExecutionFee(uint256 minExecutionFee, uint256 executionFee); + error InsufficientWntAmountForExecutionFee(uint256 wntAmount, uint256 executionFee); + error InsufficientExecutionGasForErrorHandling(uint256 startingGas, uint256 minHandleErrorGas); + error InsufficientExecutionGas(uint256 startingGas, uint256 estimatedGasLimit, uint256 minAdditionalGasForExecution); + error InsufficientHandleExecutionErrorGas(uint256 gas, uint256 minHandleExecutionErrorGas); + + // MarketFactory errors + error MarketAlreadyExists(bytes32 salt, address existingMarketAddress); + + // MarketStoreUtils errors + error MarketNotFound(address key); + + // MarketUtils errors + error EmptyMarket(); + error DisabledMarket(address market); + error MaxSwapPathLengthExceeded(uint256 swapPathLengh, uint256 maxSwapPathLength); + error InsufficientPoolAmount(uint256 poolAmount, uint256 amount); + error InsufficientReserve(uint256 reservedUsd, uint256 maxReservedUsd); + error InsufficientReserveForOpenInterest(uint256 reservedUsd, uint256 maxReservedUsd); + error UnableToGetOppositeToken(address inputToken, address market); + error UnexpectedTokenForVirtualInventory(address token, address market); + error EmptyMarketTokenSupply(); + error InvalidSwapMarket(address market); + error UnableToGetCachedTokenPrice(address token, address market); + error CollateralAlreadyClaimed(uint256 adjustedClaimableAmount, uint256 claimedAmount); + error OpenInterestCannotBeUpdatedForSwapOnlyMarket(address market); + error MaxOpenInterestExceeded(uint256 openInterest, uint256 maxOpenInterest); + error MaxPoolAmountExceeded(uint256 poolAmount, uint256 maxPoolAmount); + error MaxPoolAmountForDepositExceeded(uint256 poolAmount, uint256 maxPoolAmountForDeposit); + error UnexpectedBorrowingFactor(uint256 positionBorrowingFactor, uint256 cumulativeBorrowingFactor); + error UnableToGetBorrowingFactorEmptyPoolUsd(); + error UnableToGetFundingFactorEmptyOpenInterest(); + error InvalidPositionMarket(address market); + error InvalidCollateralTokenForMarket(address market, address token); + error PnlFactorExceededForLongs(int256 pnlToPoolFactor, uint256 maxPnlFactor); + error PnlFactorExceededForShorts(int256 pnlToPoolFactor, uint256 maxPnlFactor); + error InvalidUiFeeFactor(uint256 uiFeeFactor, uint256 maxUiFeeFactor); + error EmptyAddressInMarketTokenBalanceValidation(address market, address token); + error InvalidMarketTokenBalance(address market, address token, uint256 balance, uint256 expectedMinBalance); + error InvalidMarketTokenBalanceForCollateralAmount( + address market, address token, uint256 balance, uint256 collateralAmount + ); + error InvalidMarketTokenBalanceForClaimableFunding( + address market, address token, uint256 balance, uint256 claimableFundingFeeAmount + ); + error UnexpectedPoolValue(int256 poolValue); + + // Oracle errors + error EmptySigner(uint256 signerIndex); + error InvalidBlockNumber(uint256 minOracleBlockNumber, uint256 currentBlockNumber); + error InvalidMinMaxBlockNumber(uint256 minOracleBlockNumber, uint256 maxOracleBlockNumber); + error HasRealtimeFeedId(address token, bytes32 feedId); + error InvalidRealtimeFeedLengths(uint256 tokensLength, uint256 dataLength); + error EmptyRealtimeFeedId(address token); + error InvalidRealtimeFeedId(address token, bytes32 feedId, bytes32 expectedFeedId); + error InvalidRealtimeBidAsk(address token, int192 bid, int192 ask); + error InvalidRealtimeBlockHash(address token, bytes32 blockHash, bytes32 expectedBlockHash); + error InvalidRealtimePrices(address token, int192 bid, int192 ask); + error RealtimeMaxPriceAgeExceeded(address token, uint256 oracleTimestamp, uint256 currentTimestamp); + error MaxPriceAgeExceeded(uint256 oracleTimestamp, uint256 currentTimestamp); + error MinOracleSigners(uint256 oracleSigners, uint256 minOracleSigners); + error MaxOracleSigners(uint256 oracleSigners, uint256 maxOracleSigners); + error BlockNumbersNotSorted(uint256 minOracleBlockNumber, uint256 prevMinOracleBlockNumber); + error MinPricesNotSorted(address token, uint256 price, uint256 prevPrice); + error MaxPricesNotSorted(address token, uint256 price, uint256 prevPrice); + error EmptyPriceFeedMultiplier(address token); + error EmptyRealtimeFeedMultiplier(address token); + error InvalidFeedPrice(address token, int256 price); + error PriceFeedNotUpdated(address token, uint256 timestamp, uint256 heartbeatDuration); + error MaxSignerIndex(uint256 signerIndex, uint256 maxSignerIndex); + error InvalidOraclePrice(address token); + error InvalidSignerMinMaxPrice(uint256 minPrice, uint256 maxPrice); + error InvalidMedianMinMaxPrice(uint256 minPrice, uint256 maxPrice); + error NonEmptyTokensWithPrices(uint256 tokensWithPricesLength); + error InvalidMinMaxForPrice(address token, uint256 min, uint256 max); + error EmptyPriceFeed(address token); + error PriceAlreadySet(address token, uint256 minPrice, uint256 maxPrice); + error MaxRefPriceDeviationExceeded(address token, uint256 price, uint256 refPrice, uint256 maxRefPriceDeviationFactor); + error InvalidBlockRangeSet(uint256 largestMinBlockNumber, uint256 smallestMaxBlockNumber); + + // OracleModule errors + error InvalidPrimaryPricesForSimulation(uint256 primaryTokensLength, uint256 primaryPricesLength); + error EndOfOracleSimulation(); + + // OracleUtils errors + error EmptyCompactedPrice(uint256 index); + error EmptyCompactedBlockNumber(uint256 index); + error EmptyCompactedTimestamp(uint256 index); + error UnsupportedOracleBlockNumberType(uint256 oracleBlockNumberType); + error InvalidSignature(address recoveredSigner, address expectedSigner); + + error EmptyPrimaryPrice(address token); + + error OracleBlockNumbersAreSmallerThanRequired(uint256[] oracleBlockNumbers, uint256 expectedBlockNumber); + error OracleBlockNumberNotWithinRange( + uint256[] minOracleBlockNumbers, uint256[] maxOracleBlockNumbers, uint256 blockNumber + ); + + // BaseOrderUtils errors + error EmptyOrder(); + error UnsupportedOrderType(); + error InvalidOrderPrices(uint256 primaryPriceMin, uint256 primaryPriceMax, uint256 triggerPrice, uint256 orderType); + error EmptySizeDeltaInTokens(); + error PriceImpactLargerThanOrderSize(int256 priceImpactUsd, uint256 sizeDeltaUsd); + error NegativeExecutionPrice( + int256 executionPrice, uint256 price, uint256 positionSizeInUsd, int256 priceImpactUsd, uint256 sizeDeltaUsd + ); + error OrderNotFulfillableAtAcceptablePrice(uint256 price, uint256 acceptablePrice); + + // IncreaseOrderUtils errors + error UnexpectedPositionState(); + + // OrderUtils errors + error OrderTypeCannotBeCreated(uint256 orderType); + error OrderAlreadyFrozen(); + + // OrderStoreUtils errors + error OrderNotFound(bytes32 key); + + // SwapOrderUtils errors + error UnexpectedMarket(); + + // DecreasePositionCollateralUtils errors + error InsufficientFundsToPayForCosts(uint256 remainingCostUsd, string step); + error InvalidOutputToken(address tokenOut, address expectedTokenOut); + + // DecreasePositionUtils errors + error InvalidDecreaseOrderSize(uint256 sizeDeltaUsd, uint256 positionSizeInUsd); + error UnableToWithdrawCollateral(int256 estimatedRemainingCollateralUsd); + error InvalidDecreasePositionSwapType(uint256 decreasePositionSwapType); + error PositionShouldNotBeLiquidated( + string reason, int256 remainingCollateralUsd, int256 minCollateralUsd, int256 minCollateralUsdForLeverage + ); + + // IncreasePositionUtils errors + error InsufficientCollateralAmount(uint256 collateralAmount, int256 collateralDeltaAmount); + error InsufficientCollateralUsd(int256 remainingCollateralUsd); + + // PositionStoreUtils errors + error PositionNotFound(bytes32 key); + + // PositionUtils errors + error LiquidatablePosition( + string reason, int256 remainingCollateralUsd, int256 minCollateralUsd, int256 minCollateralUsdForLeverage + ); + + error EmptyPosition(); + error InvalidPositionSizeValues(uint256 sizeInUsd, uint256 sizeInTokens); + error MinPositionSize(uint256 positionSizeInUsd, uint256 minPositionSizeUsd); + + // PositionPricingUtils errors + error UsdDeltaExceedsLongOpenInterest(int256 usdDelta, uint256 longOpenInterest); + error UsdDeltaExceedsShortOpenInterest(int256 usdDelta, uint256 shortOpenInterest); + + // SwapPricingUtils errors + error UsdDeltaExceedsPoolValue(int256 usdDelta, uint256 poolUsd); + + // RoleModule errors + error Unauthorized(address msgSender, string role); + + // RoleStore errors + error ThereMustBeAtLeastOneRoleAdmin(); + error ThereMustBeAtLeastOneTimelockMultiSig(); + + // ExchangeRouter errors + error InvalidClaimFundingFeesInput(uint256 marketsLength, uint256 tokensLength); + error InvalidClaimCollateralInput(uint256 marketsLength, uint256 tokensLength, uint256 timeKeysLength); + error InvalidClaimAffiliateRewardsInput(uint256 marketsLength, uint256 tokensLength); + error InvalidClaimUiFeesInput(uint256 marketsLength, uint256 tokensLength); + + // SwapUtils errors + error InvalidTokenIn(address tokenIn, address market); + error InsufficientOutputAmount(uint256 outputAmount, uint256 minOutputAmount); + error InsufficientSwapOutputAmount(uint256 outputAmount, uint256 minOutputAmount); + error DuplicatedMarketInSwapPath(address market); + error SwapPriceImpactExceedsAmountIn(uint256 amountAfterFees, int256 negativeImpactAmount); + + // SubaccountRouter errors + error InvalidReceiverForSubaccountOrder(address receiver, address expectedReceiver); + + // SubaccountUtils errors + error SubaccountNotAuthorized(address account, address subaccount); + error MaxSubaccountActionCountExceeded(address account, address subaccount, uint256 count, uint256 maxCount); + + // TokenUtils errors + error EmptyTokenTranferGasLimit(address token); + error TokenTransferError(address token, address receiver, uint256 amount); + error EmptyHoldingAddress(); + + // AccountUtils errors + error EmptyAccount(); + error EmptyReceiver(); + + // Array errors + error CompactedArrayOutOfBounds(uint256[] compactedValues, uint256 index, uint256 slotIndex, string label); + + error ArrayOutOfBoundsUint256(uint256[] values, uint256 index, string label); + + error ArrayOutOfBoundsBytes(bytes[] values, uint256 index, string label); + + // WithdrawalStoreUtils errors + error WithdrawalNotFound(bytes32 key); + + // WithdrawalUtils errors + error EmptyWithdrawal(); + error EmptyWithdrawalAmount(); + error MinLongTokens(uint256 received, uint256 expected); + error MinShortTokens(uint256 received, uint256 expected); + error InsufficientMarketTokens(uint256 balance, uint256 expected); + error InsufficientWntAmount(uint256 wntAmount, uint256 executionFee); + error InvalidPoolValueForWithdrawal(int256 poolValue); + + // Uint256Mask errors + error MaskIndexOutOfBounds(uint256 index, string label); + error DuplicatedIndex(uint256 index, string label); + + // =============== Structs ============== + + // @dev SwapFees struct to contain swap fee values + // @param feeReceiverAmount The fee amount for the fee receiver + // @param feeAmountForPool The fee amount for the pool + // @param amountAfterFees The output amount after fees + struct SwapFees { + uint256 feeReceiverAmount; + uint256 feeAmountForPool; + uint256 amountAfterFees; + address uiFeeReceiver; + uint256 uiFeeReceiverFactor; + uint256 uiFeeAmount; + } + + // =============== Functions ============== + + function getMarketTokenPrice( + IGmxDataStore _dataStore, + GmxMarket.MarketProps memory _market, + GmxPrice.PriceProps memory _indexTokenPrice, + GmxPrice.PriceProps memory _longTokenPrice, + GmxPrice.PriceProps memory _shortTokenPrice, + bytes32 _pnlFactorType, + bool _maximize + ) external view returns (int256, GmxMarketPoolValueInfo.PoolValueInfoProps memory); + + function getDeposit(IGmxDataStore _dataStore, bytes32 _key) external view returns (GmxDeposit.DepositProps memory); + + function getWithdrawal( + IGmxDataStore _dataStore, + bytes32 _key + ) external view returns (GmxWithdrawal.WithdrawalProps memory); + + function getPnlToPoolFactor( + IGmxDataStore _dataStore, + address _marketAddress, + GmxMarket.MarketPrices memory _prices, + bool _isLong, + bool _maximize + ) external view returns (int256); + + function getSwapPriceImpact( + IGmxDataStore _dataStore, + address _marketKey, + address _tokenIn, + address _tokenOut, + uint256 _amountIn, + GmxPrice.PriceProps memory _tokenInPrice, + GmxPrice.PriceProps memory _tokenOutPrice + ) external view returns (int256, int256); + + function getSwapAmountOut( + IGmxDataStore _dataStore, + GmxMarket.MarketProps memory _market, + GmxMarket.MarketPrices memory _prices, + address _tokenIn, + uint256 _amountIn, + address _uiFeeReceiver + ) external view returns (uint256, int256, SwapFees memory fees); + + function getDepositAmountOut( + IGmxDataStore _dataStore, + GmxMarket.MarketProps memory _market, + GmxMarket.MarketPrices memory _prices, + uint256 _longTokenAmount, + uint256 _shortTokenAmount, + address _uiFeeReceiver, + SwapPricingType _swapPricingType, + bool includeVirtualInventoryImpact + ) external view returns (uint256); + + function getWithdrawalAmountOut( + IGmxDataStore _dataStore, + GmxMarket.MarketProps memory _market, + GmxMarket.MarketPrices memory _prices, + uint256 _marketTokenAmount, + address _uiFeeReceiver, + SwapPricingType _swapPricingType + ) external view returns (uint256, uint256); +} diff --git a/src/interfaces/oracles/gmx/IGmxRoleStore.sol b/src/interfaces/oracles/gmx/IGmxRoleStore.sol new file mode 100644 index 0000000..cf8f489 --- /dev/null +++ b/src/interfaces/oracles/gmx/IGmxRoleStore.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity ^0.8.9; + +/** + * @title IGmxRoleStore + * + * @notice Gmx RoleStore interface + */ +interface IGmxRoleStore { + /** + * @dev Returns the members of the specified role. + * + * @param _roleKey The key of the role. + * @param _start The start index, the value for this index will be included. + * @param _end The end index, the value for this index will not be included. + * @return The members of the role. + */ + function getRoleMembers(bytes32 _roleKey, uint256 _start, uint256 _end) external view returns (address[] memory); +} diff --git a/src/libraries/gmx/GmxDeposit.sol b/src/libraries/gmx/GmxDeposit.sol new file mode 100644 index 0000000..377941c --- /dev/null +++ b/src/libraries/gmx/GmxDeposit.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.9; + +/** + * @title GmxDeposit + * @author Dolomite + * + */ +library GmxDeposit { + // @dev there is a limit on the number of fields a struct can have when being passed + // or returned as a memory variable which can cause "Stack too deep" errors + // use sub-structs to avoid this issue + // @param addresses address values + // @param numbers number values + // @param flags boolean values + struct DepositProps { + Addresses addresses; + Numbers numbers; + Flags flags; + } + + // @param account the account depositing liquidity + // @param receiver the address to send the liquidity tokens to + // @param callbackContract the callback contract + // @param uiFeeReceiver the ui fee receiver + // @param market the market to deposit to + struct Addresses { + address account; + address receiver; + address callbackContract; + address uiFeeReceiver; + address market; + address initialLongToken; + address initialShortToken; + address[] longTokenSwapPath; + address[] shortTokenSwapPath; + } + + // @param initialLongTokenAmount the amount of long tokens to deposit + // @param initialShortTokenAmount the amount of short tokens to deposit + // @param minMarketTokens the minimum acceptable number of liquidity tokens + // @param updatedAtBlock the block that the deposit was last updated at + // sending funds back to the user in case the deposit gets cancelled + // @param executionFee the execution fee for keepers + // @param callbackGasLimit the gas limit for the callbackContract + struct Numbers { + uint256 initialLongTokenAmount; + uint256 initialShortTokenAmount; + uint256 minMarketTokens; + uint256 updatedAtBlock; + uint256 updatedAtTime; + uint256 executionFee; + uint256 callbackGasLimit; + } + + // @param shouldUnwrapNativeToken whether to unwrap the native token when + struct Flags { + bool shouldUnwrapNativeToken; + } +} diff --git a/src/libraries/gmx/GmxMarket.sol b/src/libraries/gmx/GmxMarket.sol new file mode 100644 index 0000000..4118cf7 --- /dev/null +++ b/src/libraries/gmx/GmxMarket.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.9; + +import {GmxPrice} from './GmxPrice.sol'; + +/** + * @title GmxMarket + * + * @notice GMX Market Library + */ +library GmxMarket { + struct MarketProps { + address marketToken; + address indexToken; + address longToken; + address shortToken; + } + + struct MarketPrices { + GmxPrice.PriceProps indexTokenPrice; + GmxPrice.PriceProps longTokenPrice; + GmxPrice.PriceProps shortTokenPrice; + } +} diff --git a/src/libraries/gmx/GmxMarketPoolValueInfo.sol b/src/libraries/gmx/GmxMarketPoolValueInfo.sol new file mode 100644 index 0000000..54e983a --- /dev/null +++ b/src/libraries/gmx/GmxMarketPoolValueInfo.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.9; + +/** + * @title GmxMarketPoolValueInfo + * @author Dolomite + * + * @notice GMX MarketPoolVaultInfo Library + */ +library GmxMarketPoolValueInfo { + // @dev struct to avoid stack too deep errors for the getPoolValue call + // @param value the pool value + // @param longTokenAmount the amount of long token in the pool + // @param shortTokenAmount the amount of short token in the pool + // @param longTokenUsd the USD value of the long tokens in the pool + // @param shortTokenUsd the USD value of the short tokens in the pool + // @param totalBorrowingFees the total pending borrowing fees for the market + // @param borrowingFeePoolFactor the pool factor for borrowing fees + // @param impactPoolAmount the amount of tokens in the impact pool + // @param longPnl the pending pnl of long positions + // @param shortPnl the pending pnl of short positions + // @param netPnl the net pnl of long and short positions + struct PoolValueInfoProps { + int256 poolValue; + int256 longPnl; + int256 shortPnl; + int256 netPnl; + uint256 longTokenAmount; + uint256 shortTokenAmount; + uint256 longTokenUsd; + uint256 shortTokenUsd; + uint256 totalBorrowingFees; + uint256 borrowingFeePoolFactor; + uint256 impactPoolAmount; + } +} diff --git a/src/libraries/gmx/GmxPrice.sol b/src/libraries/gmx/GmxPrice.sol new file mode 100644 index 0000000..179b2d9 --- /dev/null +++ b/src/libraries/gmx/GmxPrice.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.9; + +/** + * @title GmxPrice + * @notice GMX Price Library + */ +library GmxPrice { + struct PriceProps { + uint256 min; + uint256 max; + } +} diff --git a/src/libraries/gmx/GmxWithdrawal.sol b/src/libraries/gmx/GmxWithdrawal.sol new file mode 100644 index 0000000..36ebea5 --- /dev/null +++ b/src/libraries/gmx/GmxWithdrawal.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.9; + +/** + * @title GmxWithdrawal + * @author Dolomite + * + */ +library GmxWithdrawal { + // @dev there is a limit on the number of fields a struct can have when being passed + // or returned as a memory variable which can cause "Stack too deep" errors + // use sub-structs to avoid this issue + // @param addresses address values + // @param numbers number values + // @param flags boolean values + struct WithdrawalProps { + Addresses addresses; + Numbers numbers; + Flags flags; + } + + // @param account The account to withdraw for. + // @param receiver The address that will receive the withdrawn tokens. + // @param callbackContract The contract that will be called back. + // @param uiFeeReceiver The ui fee receiver. + // @param market The market on which the withdrawal will be executed. + struct Addresses { + address account; + address receiver; + address callbackContract; + address uiFeeReceiver; + address market; + address[] longTokenSwapPath; + address[] shortTokenSwapPath; + } + + // @param marketTokenAmount The amount of market tokens that will be withdrawn. + // @param minLongTokenAmount The minimum amount of long tokens that must be withdrawn. + // @param minShortTokenAmount The minimum amount of short tokens that must be withdrawn. + // @param updatedAtBlock The block at which the withdrawal was last updated. + // @param executionFee The execution fee for the withdrawal. + // @param callbackGasLimit The gas limit for calling the callback contract. + struct Numbers { + uint256 marketTokenAmount; + uint256 minLongTokenAmount; + uint256 minShortTokenAmount; + uint256 updatedAtBlock; + uint256 updatedAtTime; + uint256 executionFee; + uint256 callbackGasLimit; + } + + // @param shouldUnwrapNativeToken whether to unwrap the native token when + struct Flags { + bool shouldUnwrapNativeToken; + } +} From 22dc720c8ba503e6037208017744f76b4d7043c9 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Wed, 17 Jul 2024 22:34:07 -0500 Subject: [PATCH 08/11] single oracle in place --- .../factories/gmx/GmxGmRelayerChild.sol | 7 +- .../factories/gmx/GmxRelayerFactory.sol | 13 ++- src/contracts/oracles/gmx/GmxGmRelayer.sol | 93 ++++++++++++++++++- src/interfaces/oracles/gmx/IGmxDataStore.sol | 17 +++- src/interfaces/oracles/gmx/IGmxReader.sol | 1 + 5 files changed, 119 insertions(+), 12 deletions(-) diff --git a/src/contracts/factories/gmx/GmxGmRelayerChild.sol b/src/contracts/factories/gmx/GmxGmRelayerChild.sol index 1e9567c..ada101c 100644 --- a/src/contracts/factories/gmx/GmxGmRelayerChild.sol +++ b/src/contracts/factories/gmx/GmxGmRelayerChild.sol @@ -12,6 +12,9 @@ contract GmxGmRelayerChild is GmxGmRelayer, FactoryChild { constructor( address _marketToken, address _gmxReader, - address _dataStore - ) GmxGmRelayer(_marketToken, _gmxReader, _dataStore) {} + address _dataStore, + address _indexTokenOracle, + address _longTokenOracle, + address _shortTokenOracle + ) GmxGmRelayer(_marketToken, _gmxReader, _dataStore, _indexTokenOracle, _longTokenOracle, _shortTokenOracle) {} } diff --git a/src/contracts/factories/gmx/GmxRelayerFactory.sol b/src/contracts/factories/gmx/GmxRelayerFactory.sol index d6b7d1f..bffeba6 100644 --- a/src/contracts/factories/gmx/GmxRelayerFactory.sol +++ b/src/contracts/factories/gmx/GmxRelayerFactory.sol @@ -23,9 +23,18 @@ contract PendleRelayerFactory is Authorizable { function deployGmxGmRelayer( address _marketToken, address _gmxReader, - address _dataStore + address _dataStore, + address _indexTokenOracle, + address _longTokenOracle, + address _shortTokenOracle ) external isAuthorized returns (IBaseOracle _gmxGmRelayerChild) { - _gmxGmRelayerChild = IBaseOracle(address(new GmxGmRelayerChild(_marketToken, _gmxReader, _dataStore))); + _gmxGmRelayerChild = IBaseOracle( + address( + new GmxGmRelayerChild( + _marketToken, _gmxReader, _dataStore, _indexTokenOracle, _longTokenOracle, _shortTokenOracle + ) + ) + ); relayerId++; relayerById[relayerId] = address(_gmxGmRelayerChild); emit NewGmxGmRelayer(address(_gmxGmRelayerChild), _marketToken); diff --git a/src/contracts/oracles/gmx/GmxGmRelayer.sol b/src/contracts/oracles/gmx/GmxGmRelayer.sol index f4a9080..01cbd68 100644 --- a/src/contracts/oracles/gmx/GmxGmRelayer.sol +++ b/src/contracts/oracles/gmx/GmxGmRelayer.sol @@ -2,9 +2,12 @@ pragma solidity 0.8.26; import {OracleUtils} from '@gmx/contracts/oracle/OracleUtils.sol'; +import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; import {IOracleProvider} from '@gmx/contracts/oracle/IOracleProvider.sol'; import {GmxPrice} from '@libraries/gmx/GmxPrice.sol'; +import {GmxMarket} from '@libraries/gmx/GmxMarket.sol'; import {IGmxDataStore} from '@interfaces/oracles/gmx/IGmxDataStore.sol'; +import {IGmxReader} from '@interfaces/oracles/gmx/IGmxReader.sol'; /** * @title GmxGmRelayer @@ -21,28 +24,108 @@ contract GmxGmRelayer { uint256 public constant BASIS_POINTS = 10_000; uint256 public constant SUPPLY_CAP_USAGE_NUMERATOR = 5; uint256 public constant SUPPLY_CAP_USAGE_DENOMINATOR = 100; - uint256 public constant Gmx_DECIMAL_ADJUSTMENT = 10 ** 6; + uint256 public constant GMX_DECIMAL_ADJUSTMENT = 10 ** 6; uint256 public constant RETURN_DECIMAL_ADJUSTMENT = 10 ** 12; uint256 public constant FEE_FACTOR_DECIMAL_ADJUSTMENT = 10 ** 26; + uint256 public constant FEE_BP_FOR_MARKET_TOKEN = 10 ** 26; bytes32 public constant MAX_PNL_FACTOR_FOR_DEPOSITS_KEY = keccak256(abi.encode('MAX_PNL_FACTOR_FOR_DEPOSITS')); // solhint-disable-line max-line-length bytes32 public constant SWAP_FEE_FACTOR_KEY = keccak256(abi.encode('SWAP_FEE_FACTOR')); bytes32 public constant SWAP_FEE_RECEIVER_FACTOR_KEY = keccak256(abi.encode('SWAP_FEE_RECEIVER_FACTOR')); - address marketToken; - IGmxDataStore dataStore; + address public marketToken; + IGmxDataStore public dataStore; + IGmxReader public reader; + IBaseOracle public indexTokenOracle; + IBaseOracle public longTokenOracle; + IBaseOracle public shortTokenOracle; - constructor(address _marketToken, address _gmxReader, address _dataStore) { + constructor( + address _marketToken, + address _gmxReader, + address _dataStore, + address _indexTokenOracle, + address _longTokenOracle, + address _shortTokenOracle + ) { marketToken = _marketToken; dataStore = IGmxDataStore(_dataStore); + reader = IGmxReader(_gmxReader); + indexTokenOracle = IBaseOracle(_indexTokenOracle); + longTokenOracle = IBaseOracle(_longTokenOracle); + shortTokenOracle = IBaseOracle(_shortTokenOracle); } function getResultWithValidity() external view returns (uint256 _result, bool _validity) { - _result; + _result = _getCurrentPrice(); _validity = true; } function read() external view returns (uint256 _value) { _value; } + + function _getCurrentPrice() internal view returns (uint256) { + GmxMarket.MarketProps memory marketProps = reader.getMarket(dataStore, marketToken); + + uint256 longTokenPrice = longTokenOracle.read(); + + GmxPrice.PriceProps memory longTokenPriceProps = GmxPrice.PriceProps({ + min: _adjustDownForBasisPoints(longTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT, + max: _adjustUpForBasisPoints(longTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT + }); + + uint256 shortTokenPrice = shortTokenOracle.read(); + GmxPrice.PriceProps memory shortTokenPriceProps = GmxPrice.PriceProps({ + min: _adjustDownForBasisPoints(shortTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT, + max: _adjustUpForBasisPoints(shortTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT + }); + + uint256 gmPrice = _getGmTokenPrice(marketProps, longTokenPriceProps, shortTokenPriceProps); + + return gmPrice; //_adjustDownForBasisPoints(gmPrice, getFeeBpByMarketToken(factory.UNDERLYING_TOKEN())); + } + + function _getGmTokenPrice( + GmxMarket.MarketProps memory _marketProps, + GmxPrice.PriceProps memory _longTokenPriceProps, + GmxPrice.PriceProps memory _shortTokenPriceProps + ) internal view returns (uint256) { + uint256 indexTokenPrice = indexTokenOracle.read(); + + // Dolomite returns price as 36 decimals - token decimals + // GMX expects 30 decimals - token decimals so we divide by 10 ** 6 + GmxPrice.PriceProps memory indexTokenPriceProps = GmxPrice.PriceProps({ + min: _adjustDownForBasisPoints(indexTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT, + max: _adjustUpForBasisPoints(indexTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT + }); + + (int256 value,) = reader.getMarketTokenPrice( + dataStore, + _marketProps, + indexTokenPriceProps, + _longTokenPriceProps, + _shortTokenPriceProps, + MAX_PNL_FACTOR_FOR_DEPOSITS_KEY, + /* _maximize = */ + false + ); + + require(value > 0, 'Invalid oracle response'); + + // GMX returns the price in 30 decimals. We convert to (36 - GM token decimals == 18) for Dolomite's system + return uint256(value) / RETURN_DECIMAL_ADJUSTMENT; + } + + function _adjustDownForBasisPoints(uint256 _value, uint256 _basisPoints) internal pure returns (uint256) { + return _value - (_value * _basisPoints / BASIS_POINTS); + } + + function _adjustUpForBasisPoints(uint256 _value, uint256 _basisPoints) internal pure returns (uint256) { + return _value + (_value * _basisPoints / BASIS_POINTS); + } + + function _swapFeeFactorKey(address _marketToken, bool _forPositiveImpact) private pure returns (bytes32) { + return keccak256(abi.encode(SWAP_FEE_FACTOR_KEY, _marketToken, _forPositiveImpact)); + } } diff --git a/src/interfaces/oracles/gmx/IGmxDataStore.sol b/src/interfaces/oracles/gmx/IGmxDataStore.sol index f7ab1a1..7c7c117 100644 --- a/src/interfaces/oracles/gmx/IGmxDataStore.sol +++ b/src/interfaces/oracles/gmx/IGmxDataStore.sol @@ -11,12 +11,23 @@ import {IGmxRoleStore} from './IGmxRoleStore.sol'; */ interface IGmxDataStore { function setUint(bytes32 _key, uint256 _value) external returns (uint256); - function setBool(bytes32 _key, bool _bool) external returns (bool); function getBool(bytes32 _key) external view returns (bool); - function getUint(bytes32 _key) external view returns (uint256); - + function getInt(bytes32 key) external view returns (int256); + function getAddress(bytes32 key) external view returns (address); + function getString(bytes32 key) external view returns (string memory); + function getBytes32(bytes32 key) external view returns (bytes32); + function getUintArray(bytes32 key) external view returns (uint256[] memory); + function getAddressArray(bytes32 key) external view returns (address[] memory); + function getBoolArray(bytes32 key) external view returns (bool[] memory); + function getStringArray(bytes32 key) external view returns (string[] memory); + function getBytes32Array(bytes32 key) external view returns (bytes32[] memory); + function getBytes32Count(bytes32 setKey) external view returns (uint256); + function getBytes32ValuesAt(bytes32 setKey, uint256 start, uint256 end) external view returns (bytes32[] memory); + function getAddressCount(bytes32 setKey) external view returns (uint256); + function getAddressValuesAt(bytes32 setKey, uint256 start, uint256 end) external view returns (address[] memory); + function getUintCount(bytes32 setKey) external view returns (uint256); function roleStore() external view returns (IGmxRoleStore); } diff --git a/src/interfaces/oracles/gmx/IGmxReader.sol b/src/interfaces/oracles/gmx/IGmxReader.sol index f98e207..d16a766 100644 --- a/src/interfaces/oracles/gmx/IGmxReader.sol +++ b/src/interfaces/oracles/gmx/IGmxReader.sol @@ -320,6 +320,7 @@ interface IGmxReader { } // =============== Functions ============== + function getMarket(IGmxDataStore dataStore, address key) external view returns (GmxMarket.MarketProps memory); function getMarketTokenPrice( IGmxDataStore _dataStore, From 707e100b199c04bdb9ec859e18cb0e3e539963ec Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Fri, 19 Jul 2024 01:14:52 -0500 Subject: [PATCH 09/11] building out gm oracle for WETH perp market for testing --- script/Registry.s.sol | 10 +++++ .../factories/gmx/GmxRelayerFactory.sol | 2 +- src/contracts/oracles/gmx/GmxGmRelayer.sol | 9 +++- src/interfaces/oracles/gmx/IGmxReader.sol | 5 +++ test/unit/RelayerFactories.t.sol | 44 +++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/script/Registry.s.sol b/script/Registry.s.sol index 491dd66..aa073ad 100644 --- a/script/Registry.s.sol +++ b/script/Registry.s.sol @@ -104,3 +104,13 @@ address constant MAINNET_PENDLE_ORACLE = 0x9a9Fa8338dd5E5B2188006f1Cd2Ef26d92165 address constant MAINNET_PENDLE_RETH_MARKET = 0x14FbC760eFaF36781cB0eb3Cb255aD976117B9Bd; address constant MAINNET_PENDLE_WSTETH_MARKET = 0x08a152834de126d2ef83D612ff36e4523FD0017F; address constant MAINNET_PENDLE_RELAYER_FACTORY = 0x0000000000000000000000000000000000000000; + +//GMX +address constant MAINNET_GMX_DATA_STORE = 0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8; +address constant MAINNET_GMX_READER = 0x5Ca84c34a381434786738735265b9f3FD814b824; + +// GM WETH PERP MARKET +address constant MAINNET_GMX_WETH_PERP_MARKET_TOKEN = 0x70d95587d40A2caf56bd97485aB3Eec10Bee6336; +address constant MAINNET_GMX_WETH_PERP_INDEX_TOKEN = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; //WETH +address constant MAINNET_GMX_WETH_PERP_LONG_TOKEN = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; //WETH +address constant MAINNET_GMX_WETH_PERP_shortToken = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831; //usdc diff --git a/src/contracts/factories/gmx/GmxRelayerFactory.sol b/src/contracts/factories/gmx/GmxRelayerFactory.sol index bffeba6..ab4eac3 100644 --- a/src/contracts/factories/gmx/GmxRelayerFactory.sol +++ b/src/contracts/factories/gmx/GmxRelayerFactory.sol @@ -6,7 +6,7 @@ import {Authorizable} from '@contracts/utils/Authorizable.sol'; import {GmxGmRelayerChild} from './GmxGmRelayerChild.sol'; import 'forge-std/console2.sol'; -contract PendleRelayerFactory is Authorizable { +contract GmxRelayerFactory is Authorizable { uint256 public relayerId; // --- Events --- diff --git a/src/contracts/oracles/gmx/GmxGmRelayer.sol b/src/contracts/oracles/gmx/GmxGmRelayer.sol index 01cbd68..e72dbbc 100644 --- a/src/contracts/oracles/gmx/GmxGmRelayer.sol +++ b/src/contracts/oracles/gmx/GmxGmRelayer.sol @@ -62,7 +62,7 @@ contract GmxGmRelayer { } function read() external view returns (uint256 _value) { - _value; + _value = _getCurrentPrice(); } function _getCurrentPrice() internal view returns (uint256) { @@ -83,7 +83,7 @@ contract GmxGmRelayer { uint256 gmPrice = _getGmTokenPrice(marketProps, longTokenPriceProps, shortTokenPriceProps); - return gmPrice; //_adjustDownForBasisPoints(gmPrice, getFeeBpByMarketToken(factory.UNDERLYING_TOKEN())); + return _adjustDownForBasisPoints(gmPrice, getFeeBpByMarketToken(marketToken)); } function _getGmTokenPrice( @@ -128,4 +128,9 @@ contract GmxGmRelayer { function _swapFeeFactorKey(address _marketToken, bool _forPositiveImpact) private pure returns (bytes32) { return keccak256(abi.encode(SWAP_FEE_FACTOR_KEY, _marketToken, _forPositiveImpact)); } + + function getFeeBpByMarketToken(address _gmToken) public view returns (uint256) { + bytes32 key = _swapFeeFactorKey(_gmToken, /* _forPositiveImpact = */ false); + return dataStore.getUint(key) / FEE_FACTOR_DECIMAL_ADJUSTMENT; + } } diff --git a/src/interfaces/oracles/gmx/IGmxReader.sol b/src/interfaces/oracles/gmx/IGmxReader.sol index d16a766..fb978ba 100644 --- a/src/interfaces/oracles/gmx/IGmxReader.sol +++ b/src/interfaces/oracles/gmx/IGmxReader.sol @@ -321,6 +321,11 @@ interface IGmxReader { // =============== Functions ============== function getMarket(IGmxDataStore dataStore, address key) external view returns (GmxMarket.MarketProps memory); + function getMarkets( + IGmxDataStore dataStore, + uint256 start, + uint256 end + ) external view returns (GmxMarket.MarketProps[] memory); function getMarketTokenPrice( IGmxDataStore _dataStore, diff --git a/test/unit/RelayerFactories.t.sol b/test/unit/RelayerFactories.t.sol index 96a9740..69b64c2 100644 --- a/test/unit/RelayerFactories.t.sol +++ b/test/unit/RelayerFactories.t.sol @@ -17,6 +17,12 @@ import {MAINNET_PENDLE_ORACLE, MAINNET_PENDLE_RETH_MARKET} from '@script/Registr import {IAuthorizable} from '@interfaces/utils/IAuthorizable.sol'; import {IPendleRelayerFactory} from '@interfaces/factories/IPendleRelayerFactory.sol'; import {IPendleRelayer} from '@interfaces/oracles/pendle/IPendleRelayer.sol'; +import {IGmxRelayerFactory} from '@interfaces/factories/IGmxRelayerFactory.sol'; +import {IGmxReader} from '@interfaces/oracles/gmx/IGmxReader.sol'; +import {IGmxDataStore} from '@interfaces/oracles/gmx/IGmxDataStore.sol'; +import {GmxRelayerFactory} from '@contracts/factories/gmx/GmxRelayerFactory.sol'; +import {GmxMarket} from '@libraries/gmx/GmxMarket.sol'; +import 'forge-std/console2.sol'; abstract contract Base is DSTestPlus { address deployer = label('deployer'); @@ -264,3 +270,41 @@ contract Unit_Pendle_Renzo_Deploy_Oracle is Base { pendleFactory.deployPendleLpRelayer(address(0), MAINNET_PENDLE_ORACLE, uint32(900)); } } + +contract Unit_GMX_Relayer_Factory is Base { + IGmxRelayerFactory public gmxFactory; + IGmxReader public gmxReader; + IGmxDataStore public gmxDataStore; + + function setUp() public virtual override { + super.setUp(); + vm.createSelectFork(vm.envString('ARB_MAINNET_RPC')); + delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); + chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); + denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); + gmxFactory = IGmxRelayerFactory(address(new GmxRelayerFactory())); + gmxReader = IGmxReader(MAINNET_GMX_READER); + gmxDataStore = IGmxDataStore(MAINNET_GMX_DATA_STORE); + + label(address(delayedOracleFactory), 'DelayedOracleFactory'); + label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); + label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); + label(address(gmxFactory), 'gmxFactory'); + } + + function test_GmxFactory_Deployment() public view { + assertEq(gmxFactory.relayerId(), 0); + assertEq(gmxFactory.authorizedAccounts()[0], address(this)); + } + + function test_Create_GmxGm_Relayer() public { + GmxMarket.MarketProps[] memory newProps = gmxReader.getMarkets(gmxDataStore, 0, 100); + for (uint256 i; i < newProps.length; i++) { + console2.log('maket %s', i); + console2.log('marketToken', newProps[i].marketToken); + console2.log('indexToken', newProps[i].indexToken); + console2.log('longtoken', newProps[i].longToken); + console2.log('shortToken', newProps[i].shortToken); + } + } +} From c5fe089020fa51a91b8034485bd57985c2bd2b76 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Fri, 19 Jul 2024 01:39:32 -0500 Subject: [PATCH 10/11] tested gm weth perp market oracle deployment and results --- script/Registry.s.sol | 1 + src/contracts/oracles/gmx/GmxGmRelayer.sol | 6 ++-- test/unit/RelayerFactories.t.sol | 34 +++++++++++++++++----- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/script/Registry.s.sol b/script/Registry.s.sol index aa073ad..0ba0d41 100644 --- a/script/Registry.s.sol +++ b/script/Registry.s.sol @@ -75,6 +75,7 @@ address constant MAINNET_DELAYED_ETH_USD_ORACLE = 0x562CCE2F4dc383862dC6A926AF10 // Price feeds to USD address constant MAINNET_CHAINLINK_ETH_USD_FEED = 0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612; address constant MAINNET_CHAINLINK_ARB_USD_FEED = 0xb2A824043730FE05F3DA2efaFa1CBbe83fa548D6; +address constant MAINNET_CHAINLINK_USDC_USD_FEED = 0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3; // Price feeds to ETH address constant MAINNET_CHAINLINK_RETH_ETH_FEED = 0xD6aB2298946840262FcC278fF31516D39fF611eF; address constant MAINNET_CHAINLINK_WSTETH_ETH_FEED = 0xb523AE262D20A936BC152e6023996e46FDC2A95D; diff --git a/src/contracts/oracles/gmx/GmxGmRelayer.sol b/src/contracts/oracles/gmx/GmxGmRelayer.sol index e72dbbc..5426b2f 100644 --- a/src/contracts/oracles/gmx/GmxGmRelayer.sol +++ b/src/contracts/oracles/gmx/GmxGmRelayer.sol @@ -68,14 +68,14 @@ contract GmxGmRelayer { function _getCurrentPrice() internal view returns (uint256) { GmxMarket.MarketProps memory marketProps = reader.getMarket(dataStore, marketToken); - uint256 longTokenPrice = longTokenOracle.read(); + (uint256 longTokenPrice,) = longTokenOracle.getResultWithValidity(); GmxPrice.PriceProps memory longTokenPriceProps = GmxPrice.PriceProps({ min: _adjustDownForBasisPoints(longTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT, max: _adjustUpForBasisPoints(longTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT }); - uint256 shortTokenPrice = shortTokenOracle.read(); + (uint256 shortTokenPrice,) = shortTokenOracle.getResultWithValidity(); GmxPrice.PriceProps memory shortTokenPriceProps = GmxPrice.PriceProps({ min: _adjustDownForBasisPoints(shortTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT, max: _adjustUpForBasisPoints(shortTokenPrice, PRICE_DEVIATION_BP) / GMX_DECIMAL_ADJUSTMENT @@ -91,7 +91,7 @@ contract GmxGmRelayer { GmxPrice.PriceProps memory _longTokenPriceProps, GmxPrice.PriceProps memory _shortTokenPriceProps ) internal view returns (uint256) { - uint256 indexTokenPrice = indexTokenOracle.read(); + (uint256 indexTokenPrice,) = indexTokenOracle.getResultWithValidity(); // Dolomite returns price as 36 decimals - token decimals // GMX expects 30 decimals - token decimals so we divide by 10 ** 6 diff --git a/test/unit/RelayerFactories.t.sol b/test/unit/RelayerFactories.t.sol index 69b64c2..95987f1 100644 --- a/test/unit/RelayerFactories.t.sol +++ b/test/unit/RelayerFactories.t.sol @@ -275,6 +275,9 @@ contract Unit_GMX_Relayer_Factory is Base { IGmxRelayerFactory public gmxFactory; IGmxReader public gmxReader; IGmxDataStore public gmxDataStore; + IBaseOracle public wethUsdFeed; + IBaseOracle public usdcUsdFeed; + address mainnetAuthorizedAccount = 0xF78dA2A37049627636546E0cFAaB2aD664950917; function setUp() public virtual override { super.setUp(); @@ -282,14 +285,26 @@ contract Unit_GMX_Relayer_Factory is Base { delayedOracleFactory = IDelayedOracleFactory(MAINNET_DELAYED_ORACLE_FACTORY); chainlinkRelayerFactory = ChainlinkRelayerFactory(MAINNET_CHAINLINK_RELAYER_FACTORY); denominatedOracleFactory = DenominatedOracleFactory(MAINNET_DENOMINATED_ORACLE_FACTORY); + gmxFactory = IGmxRelayerFactory(address(new GmxRelayerFactory())); gmxReader = IGmxReader(MAINNET_GMX_READER); gmxDataStore = IGmxDataStore(MAINNET_GMX_DATA_STORE); + vm.startPrank(mainnetAuthorizedAccount); + usdcUsdFeed = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( + MAINNET_CHAINLINK_USDC_USD_FEED, MAINNET_CHAINLINK_SEQUENCER_FEED, 3600, 3600 + ); + wethUsdFeed = chainlinkRelayerFactory.deployChainlinkRelayerWithL2Validity( + MAINNET_CHAINLINK_ETH_USD_FEED, MAINNET_CHAINLINK_SEQUENCER_FEED, 3600, 3600 + ); + vm.stopPrank(); + label(address(delayedOracleFactory), 'DelayedOracleFactory'); label(address(chainlinkRelayerFactory), 'ChainlinkRelayerFactory'); label(address(denominatedOracleFactory), 'DenominatedOracleFactory'); label(address(gmxFactory), 'gmxFactory'); + label(address(usdcUsdFeed), 'usdcUsdFeed'); + label(address(wethUsdFeed), 'wethUsdFeed'); } function test_GmxFactory_Deployment() public view { @@ -298,13 +313,16 @@ contract Unit_GMX_Relayer_Factory is Base { } function test_Create_GmxGm_Relayer() public { - GmxMarket.MarketProps[] memory newProps = gmxReader.getMarkets(gmxDataStore, 0, 100); - for (uint256 i; i < newProps.length; i++) { - console2.log('maket %s', i); - console2.log('marketToken', newProps[i].marketToken); - console2.log('indexToken', newProps[i].indexToken); - console2.log('longtoken', newProps[i].longToken); - console2.log('shortToken', newProps[i].shortToken); - } + IBaseOracle wethGmMarket = gmxFactory.deployGmxGmRelayer( + MAINNET_GMX_WETH_PERP_MARKET_TOKEN, + address(gmxReader), + address(gmxDataStore), + address(wethUsdFeed), + address(wethUsdFeed), + address(usdcUsdFeed) + ); + (uint256 readValue, bool valid) = wethGmMarket.getResultWithValidity(); + assertGt(readValue, 0); + assertTrue(valid); } } From 940cfa2be52d2533975f138d527a01a4ec07d5a2 Mon Sep 17 00:00:00 2001 From: MrDeadCe11 Date: Fri, 19 Jul 2024 17:56:27 -0500 Subject: [PATCH 11/11] added relayer factory interface --- .../factories/IGmxRelayerFactory.sol | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/interfaces/factories/IGmxRelayerFactory.sol diff --git a/src/interfaces/factories/IGmxRelayerFactory.sol b/src/interfaces/factories/IGmxRelayerFactory.sol new file mode 100644 index 0000000..ee1d847 --- /dev/null +++ b/src/interfaces/factories/IGmxRelayerFactory.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.20; + +import {IBaseOracle} from '@interfaces/oracles/IBaseOracle.sol'; +import {IAuthorizable} from '@interfaces/utils/IAuthorizable.sol'; + +interface IGmxRelayerFactory is IAuthorizable { + // --- Events --- + event NewGmxGmRelayer(address _newGmxRelayerChild, address _marketToken); + + // --- Methods --- + + function relayerId() external view returns (uint256); + + function deployGmxGmRelayer( + address _marketToken, + address _gmxReader, + address _dataStore, + address _indexTokenOracle, + address _longTokenOracle, + address _shortTokenOracle + ) external returns (IBaseOracle _gmxGmRelayerChild); +}