From d8d8b878d1145934f9530c26e375cbf01c39f11b Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Feb 2025 20:56:55 +0530 Subject: [PATCH 1/7] feat: initial version --- scripts/DeployBase.s.sol | 26 +++++++- src/contracts/PriceCapAdapterStable.sol | 4 +- .../EURPriceCapAdapterStable.sol | 61 +++++++++++++++++++ src/interfaces/IEURPriceCapAdapterStable.sol | 23 +++++++ tests/base/EURCPriceCapAdapter.t.sol | 15 +++++ 5 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/contracts/misc-adapters/EURPriceCapAdapterStable.sol create mode 100644 src/interfaces/IEURPriceCapAdapterStable.sol create mode 100644 tests/base/EURCPriceCapAdapter.t.sol diff --git a/scripts/DeployBase.s.sol b/scripts/DeployBase.s.sol index 7bbb163..3e3f667 100644 --- a/scripts/DeployBase.s.sol +++ b/scripts/DeployBase.s.sol @@ -4,12 +4,14 @@ pragma solidity ^0.8.0; import {GovV3Helpers} from 'aave-helpers/GovV3Helpers.sol'; import {BaseScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol'; import {AaveV3Base, AaveV3BaseAssets} from 'aave-address-book/AaveV3Base.sol'; - +import {EURPriceCapAdapterStable, IEURPriceCapAdapterStable, IChainlinkAggregator} from '../src/contracts/misc-adapters/EURPriceCapAdapterStable.sol'; import {CLRatePriceCapAdapter, IPriceCapAdapter} from '../src/contracts/CLRatePriceCapAdapter.sol'; library CapAdaptersCodeBase { address public constant weETH_eETH_AGGREGATOR = 0x35e9D7001819Ea3B39Da906aE6b06A62cfe2c181; address public constant ezETH_ETH_AGGREGATOR = 0xC4300B7CF0646F0Fe4C5B2ACFCCC4dCA1346f5d8; + address public constant EURC_PRICE_FEED = 0xDAe398520e2B67cd3f27aeF9Cf14D93D927f8250; + address public constant EUR_PRICE_FEED = 0xc91D87E81faB8f93699ECf7Ee9B44D11e1D53F0F; function weETHAdapterCode() internal pure returns (bytes memory) { return @@ -52,6 +54,22 @@ library CapAdaptersCodeBase { ) ); } + + function EURCAdapterCode() internal pure returns (bytes memory) { + return + abi.encodePacked( + type(EURPriceCapAdapterStable).creationCode, + abi.encode( + IEURPriceCapAdapterStable.CapAdapterStableParamsEUR({ + aclManager: AaveV3Base.ACL_MANAGER, + assetToUsdAggregator: IChainlinkAggregator(EURC_PRICE_FEED), + baseToUsdAggregator: IChainlinkAggregator(EUR_PRICE_FEED), + adapterDescription: 'Capped EURC/USD', + priceCap: int256(1.04 * 1e8) + }) + ) + ); + } } contract DeployWeEthBase is BaseScript { @@ -65,3 +83,9 @@ contract DeployEzEthBase is BaseScript { GovV3Helpers.deployDeterministic(CapAdaptersCodeBase.ezETHAdapterCode()); } } + +contract DeployEURCBase is BaseScript { + function run() external broadcast { + GovV3Helpers.deployDeterministic(CapAdaptersCodeBase.EURCAdapterCode()); + } +} diff --git a/src/contracts/PriceCapAdapterStable.sol b/src/contracts/PriceCapAdapterStable.sol index cebf486..7618904 100644 --- a/src/contracts/PriceCapAdapterStable.sol +++ b/src/contracts/PriceCapAdapterStable.sol @@ -40,7 +40,7 @@ contract PriceCapAdapterStable is IPriceCapAdapterStable { } /// @inheritdoc ICLSynchronicityPriceAdapter - function latestAnswer() external view override returns (int256) { + function latestAnswer() external view override virtual returns (int256) { int256 basePrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); int256 priceCap = _priceCap; @@ -74,7 +74,7 @@ contract PriceCapAdapterStable is IPriceCapAdapterStable { * @notice Updates price cap * @param priceCap the new price cap */ - function _setPriceCap(int256 priceCap) internal { + function _setPriceCap(int256 priceCap) internal virtual { int256 basePrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); if (priceCap < basePrice) { diff --git a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol new file mode 100644 index 0000000..0abd14d --- /dev/null +++ b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.19; + +import {PriceCapAdapterStable, IChainlinkAggregator, ICLSynchronicityPriceAdapter, IPriceCapAdapterStable} from '../PriceCapAdapterStable.sol'; +import {IEURPriceCapAdapterStable} from '../../interfaces/IEURPriceCapAdapterStable.sol'; + +/** + * @title EURPriceCapAdapterStable + * @author BGD Labs + * @notice Price capped adapter to cap the price of the EUR asset using the + * @notice chainlink market feeds ASSET/USD and EUR/USD + */ +contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable, PriceCapAdapterStable { + /// @inheritdoc IEURPriceCapAdapterStable + IChainlinkAggregator public immutable BASE_TO_USD_AGGREGATOR; + + /** + * @param capAdapterStableParams parameters to create eur stable cap adapter + */ + constructor(CapAdapterStableParamsEUR memory capAdapterStableParams) + PriceCapAdapterStable( + CapAdapterStableParams( + capAdapterStableParams.aclManager, + capAdapterStableParams.assetToUsdAggregator, + capAdapterStableParams.adapterDescription, + capAdapterStableParams.priceCap + ) + ) { + BASE_TO_USD_AGGREGATOR = capAdapterStableParams.baseToUsdAggregator; + } + + /// @inheritdoc ICLSynchronicityPriceAdapter + function latestAnswer() external view override(ICLSynchronicityPriceAdapter, PriceCapAdapterStable) virtual returns (int256) { + int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); + int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); + int256 maxPrice = (basePrice * _priceCap) / 1e8; + + if (assetPrice > maxPrice) { + return maxPrice; + } + + return assetPrice; + } + + /** + * @notice Updates price cap + * @param priceCap the new price cap + */ + function _setPriceCap(int256 priceCap) internal override { + int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); + int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); + + if ((basePrice * priceCap) / 1e8 < assetPrice) { + revert CapLowerThanActualPrice(); + } + + _priceCap = priceCap; + + emit PriceCapUpdated(priceCap); + } +} diff --git a/src/interfaces/IEURPriceCapAdapterStable.sol b/src/interfaces/IEURPriceCapAdapterStable.sol new file mode 100644 index 0000000..bf5570e --- /dev/null +++ b/src/interfaces/IEURPriceCapAdapterStable.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IPriceCapAdapterStable, IACLManager, IChainlinkAggregator} from './IPriceCapAdapterStable.sol'; + +interface IEURPriceCapAdapterStable is IPriceCapAdapterStable { + /** + * @notice Parameters to create eur stable cap adapter + * @param capAdapterStableParams parameters to create eur stable cap adapter + */ + struct CapAdapterStableParamsEUR { + IACLManager aclManager; + IChainlinkAggregator assetToUsdAggregator; + IChainlinkAggregator baseToUsdAggregator; + string adapterDescription; + int256 priceCap; + } + + /** + * @notice Price feed for (BASE / USD) pair + */ + function BASE_TO_USD_AGGREGATOR() external view returns (IChainlinkAggregator); +} diff --git a/tests/base/EURCPriceCapAdapter.t.sol b/tests/base/EURCPriceCapAdapter.t.sol new file mode 100644 index 0000000..9a89445 --- /dev/null +++ b/tests/base/EURCPriceCapAdapter.t.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.0; + +import '../BaseStableTest.sol'; +import {CapAdaptersCodeBase} from '../../scripts/DeployBase.s.sol'; + +contract EURCBasePriceCapAdapterTest is BaseStableTest { + constructor() + BaseStableTest( + CapAdaptersCodeBase.EURCAdapterCode(), + 10, + ForkParams({network: 'base', blockNumber: 26853575}) + ) + {} +} From 09808caea84c1bbbd2a6a035e40a0dfb60e96c7f Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Feb 2025 21:21:06 +0530 Subject: [PATCH 2/7] fix: remove abstraction --- scripts/DeployBase.s.sol | 2 +- .../EURPriceCapAdapterStable.sol | 76 ++++++++++++++----- src/interfaces/IEURPriceCapAdapterStable.sol | 44 ++++++++++- 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/scripts/DeployBase.s.sol b/scripts/DeployBase.s.sol index 3e3f667..fb0021f 100644 --- a/scripts/DeployBase.s.sol +++ b/scripts/DeployBase.s.sol @@ -65,7 +65,7 @@ library CapAdaptersCodeBase { assetToUsdAggregator: IChainlinkAggregator(EURC_PRICE_FEED), baseToUsdAggregator: IChainlinkAggregator(EUR_PRICE_FEED), adapterDescription: 'Capped EURC/USD', - priceCap: int256(1.04 * 1e8) + priceCapRatio: int256(1.04 * 1e8) }) ) ); diff --git a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol index 0abd14d..b41324c 100644 --- a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol +++ b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol @@ -1,8 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.19; -import {PriceCapAdapterStable, IChainlinkAggregator, ICLSynchronicityPriceAdapter, IPriceCapAdapterStable} from '../PriceCapAdapterStable.sol'; -import {IEURPriceCapAdapterStable} from '../../interfaces/IEURPriceCapAdapterStable.sol'; +import {IEURPriceCapAdapterStable, ICLSynchronicityPriceAdapter, IACLManager, IChainlinkAggregator} from '../../interfaces/IEURPriceCapAdapterStable.sol'; /** * @title EURPriceCapAdapterStable @@ -10,30 +9,46 @@ import {IEURPriceCapAdapterStable} from '../../interfaces/IEURPriceCapAdapterSta * @notice Price capped adapter to cap the price of the EUR asset using the * @notice chainlink market feeds ASSET/USD and EUR/USD */ -contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable, PriceCapAdapterStable { +contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable { + /// @inheritdoc IEURPriceCapAdapterStable + IChainlinkAggregator public immutable ASSET_TO_USD_AGGREGATOR; + /// @inheritdoc IEURPriceCapAdapterStable IChainlinkAggregator public immutable BASE_TO_USD_AGGREGATOR; + /// @inheritdoc IEURPriceCapAdapterStable + IACLManager public immutable ACL_MANAGER; + + /// @inheritdoc ICLSynchronicityPriceAdapter + uint8 public decimals; + + /// @inheritdoc ICLSynchronicityPriceAdapter + string public description; + + int256 internal _priceCapRatio; + /** * @param capAdapterStableParams parameters to create eur stable cap adapter */ - constructor(CapAdapterStableParamsEUR memory capAdapterStableParams) - PriceCapAdapterStable( - CapAdapterStableParams( - capAdapterStableParams.aclManager, - capAdapterStableParams.assetToUsdAggregator, - capAdapterStableParams.adapterDescription, - capAdapterStableParams.priceCap - ) - ) { - BASE_TO_USD_AGGREGATOR = capAdapterStableParams.baseToUsdAggregator; + constructor(CapAdapterStableParamsEUR memory capAdapterStableParams) { + if (address(capAdapterStableParams.aclManager) == address(0)) { + revert ACLManagerIsZeroAddress(); + } + + ASSET_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; + BASE_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; + ACL_MANAGER = capAdapterStableParams.aclManager; + description = capAdapterStableParams.adapterDescription; + decimals = ASSET_TO_USD_AGGREGATOR.decimals(); + + _setPriceCapRatio(capAdapterStableParams.priceCapRatio); } /// @inheritdoc ICLSynchronicityPriceAdapter - function latestAnswer() external view override(ICLSynchronicityPriceAdapter, PriceCapAdapterStable) virtual returns (int256) { + function latestAnswer() external view returns (int256) { int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); - int256 maxPrice = (basePrice * _priceCap) / 1e8; + int256 maxPrice = (basePrice * _priceCapRatio) / 1e8; if (assetPrice > maxPrice) { return maxPrice; @@ -42,20 +57,39 @@ contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable, PriceCapAdapterS return assetPrice; } + /// @inheritdoc IEURPriceCapAdapterStable + function setPriceCapRatio(int256 priceCapRatio) external { + if (!ACL_MANAGER.isRiskAdmin(msg.sender) && !ACL_MANAGER.isPoolAdmin(msg.sender)) { + revert CallerIsNotRiskOrPoolAdmin(); + } + + _setPriceCapRatio(priceCapRatio); + } + + /// @inheritdoc IEURPriceCapAdapterStable + function getPriceCapRatio() external view returns (int256) { + return _priceCapRatio; + } + + /// @inheritdoc IEURPriceCapAdapterStable + function isCapped() public view virtual returns (bool) { + return (ASSET_TO_USD_AGGREGATOR.latestAnswer() > this.latestAnswer()); + } + /** - * @notice Updates price cap - * @param priceCap the new price cap + * @notice Updates price cap ratio + * @param priceCapRatio the new price cap ratio */ - function _setPriceCap(int256 priceCap) internal override { + function _setPriceCapRatio(int256 priceCapRatio) internal virtual { int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); - if ((basePrice * priceCap) / 1e8 < assetPrice) { + if ((basePrice * priceCapRatio) / 1e8 < assetPrice) { revert CapLowerThanActualPrice(); } - _priceCap = priceCap; + _priceCapRatio = priceCapRatio; - emit PriceCapUpdated(priceCap); + emit PriceCapRatioUpdated(priceCapRatio); } } diff --git a/src/interfaces/IEURPriceCapAdapterStable.sol b/src/interfaces/IEURPriceCapAdapterStable.sol index bf5570e..0f436db 100644 --- a/src/interfaces/IEURPriceCapAdapterStable.sol +++ b/src/interfaces/IEURPriceCapAdapterStable.sol @@ -1,9 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {IPriceCapAdapterStable, IACLManager, IChainlinkAggregator} from './IPriceCapAdapterStable.sol'; +import {IACLManager} from 'aave-address-book/AaveV3.sol'; +import {IChainlinkAggregator} from 'cl-synchronicity-price-adapter/interfaces/IChainlinkAggregator.sol'; +import {ICLSynchronicityPriceAdapter} from 'cl-synchronicity-price-adapter/interfaces/ICLSynchronicityPriceAdapter.sol'; -interface IEURPriceCapAdapterStable is IPriceCapAdapterStable { +interface IEURPriceCapAdapterStable is ICLSynchronicityPriceAdapter { /** * @notice Parameters to create eur stable cap adapter * @param capAdapterStableParams parameters to create eur stable cap adapter @@ -13,11 +15,47 @@ interface IEURPriceCapAdapterStable is IPriceCapAdapterStable { IChainlinkAggregator assetToUsdAggregator; IChainlinkAggregator baseToUsdAggregator; string adapterDescription; - int256 priceCap; + int256 priceCapRatio; } + /** + * @dev Emitted when the price cap ratio gets updated + * @param priceCapRatio the new price cap ratio + **/ + event PriceCapRatioUpdated(int256 priceCapRatio); + + /** + * @notice Price feed for (ASSET / USD) pair + */ + function ASSET_TO_USD_AGGREGATOR() external view returns (IChainlinkAggregator); + /** * @notice Price feed for (BASE / USD) pair */ function BASE_TO_USD_AGGREGATOR() external view returns (IChainlinkAggregator); + + /** + * @notice ACL manager contract + */ + function ACL_MANAGER() external view returns (IACLManager); + + /** + * @notice Updates price cap ratio + * @param priceCapRatio the new price cap ratio + */ + function setPriceCapRatio(int256 priceCapRatio) external; + + /** + * @notice Get price cap ratio value + */ + function getPriceCapRatio() external view returns (int256); + + /** + * @notice Returns if the price is currently capped + */ + function isCapped() external view returns (bool); + + error ACLManagerIsZeroAddress(); + error CallerIsNotRiskOrPoolAdmin(); + error CapLowerThanActualPrice(); } From b996e7c77fa5cb2a615882b77f71b7823bf35045 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Feb 2025 21:27:15 +0530 Subject: [PATCH 3/7] chore: deploy script --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 5f9e0a1..04c07c5 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,8 @@ deploy-weETH-zksync :; forge script --zksync scripts/DeployZkSync.s.sol:DeployWe deploy-sUSDe-zksync :; forge script --zksync scripts/DeployZkSync.s.sol:DeploySUSDeZkSync --rpc-url zksync $(common-flags) deploy-USDe-zksync :; forge script --zksync scripts/DeployZkSync.s.sol:DeployUSDeZkSync --rpc-url zksync $(common-flags) +deploy-eurc-base :; forge script scripts/DeployBase.s.sol:DeployEURCBase --rpc-url base $(common-flags) + # Utilities download :; cast etherscan-source --chain ${chain} -d src/etherscan/${chain}_${address} ${address} git-diff : From 0e1108eb2e32fed2d4b93df0b52bab8e261898eb Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Feb 2025 22:45:48 +0530 Subject: [PATCH 4/7] Update src/contracts/PriceCapAdapterStable.sol Co-authored-by: Ian Flexa <85500650+ianflexa@users.noreply.github.com> --- src/contracts/PriceCapAdapterStable.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/PriceCapAdapterStable.sol b/src/contracts/PriceCapAdapterStable.sol index 7618904..122cd02 100644 --- a/src/contracts/PriceCapAdapterStable.sol +++ b/src/contracts/PriceCapAdapterStable.sol @@ -40,7 +40,7 @@ contract PriceCapAdapterStable is IPriceCapAdapterStable { } /// @inheritdoc ICLSynchronicityPriceAdapter - function latestAnswer() external view override virtual returns (int256) { + function latestAnswer() external view override returns (int256) { int256 basePrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); int256 priceCap = _priceCap; From d99c82204b4b0a8851508e8bde04a3fe02c7be27 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Feb 2025 22:45:55 +0530 Subject: [PATCH 5/7] Update src/contracts/PriceCapAdapterStable.sol Co-authored-by: Ian Flexa <85500650+ianflexa@users.noreply.github.com> --- src/contracts/PriceCapAdapterStable.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/PriceCapAdapterStable.sol b/src/contracts/PriceCapAdapterStable.sol index 122cd02..cebf486 100644 --- a/src/contracts/PriceCapAdapterStable.sol +++ b/src/contracts/PriceCapAdapterStable.sol @@ -74,7 +74,7 @@ contract PriceCapAdapterStable is IPriceCapAdapterStable { * @notice Updates price cap * @param priceCap the new price cap */ - function _setPriceCap(int256 priceCap) internal virtual { + function _setPriceCap(int256 priceCap) internal { int256 basePrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); if (priceCap < basePrice) { From a7e30fb744af4725ffaae32019ae4315e406c8c8 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Tue, 25 Feb 2025 22:57:51 +0530 Subject: [PATCH 6/7] fix: use ratio decimals --- scripts/DeployBase.s.sol | 3 ++- src/contracts/misc-adapters/EURPriceCapAdapterStable.sol | 8 ++++++-- src/interfaces/IEURPriceCapAdapterStable.sol | 6 ++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/DeployBase.s.sol b/scripts/DeployBase.s.sol index fb0021f..65035af 100644 --- a/scripts/DeployBase.s.sol +++ b/scripts/DeployBase.s.sol @@ -65,7 +65,8 @@ library CapAdaptersCodeBase { assetToUsdAggregator: IChainlinkAggregator(EURC_PRICE_FEED), baseToUsdAggregator: IChainlinkAggregator(EUR_PRICE_FEED), adapterDescription: 'Capped EURC/USD', - priceCapRatio: int256(1.04 * 1e8) + priceCapRatio: int256(1.04 * 1e8), + ratioDecimals: 8 }) ) ); diff --git a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol index b41324c..77583d3 100644 --- a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol +++ b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol @@ -19,6 +19,9 @@ contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable { /// @inheritdoc IEURPriceCapAdapterStable IACLManager public immutable ACL_MANAGER; + /// @inheritdoc IEURPriceCapAdapterStable + uint8 public immutable RATIO_DECIMALS; + /// @inheritdoc ICLSynchronicityPriceAdapter uint8 public decimals; @@ -38,6 +41,7 @@ contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable { ASSET_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; BASE_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; ACL_MANAGER = capAdapterStableParams.aclManager; + RATIO_DECIMALS = capAdapterStableParams.ratioDecimals; description = capAdapterStableParams.adapterDescription; decimals = ASSET_TO_USD_AGGREGATOR.decimals(); @@ -48,7 +52,7 @@ contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable { function latestAnswer() external view returns (int256) { int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); - int256 maxPrice = (basePrice * _priceCapRatio) / 1e8; + int256 maxPrice = (basePrice * _priceCapRatio) / int256(10 ** RATIO_DECIMALS); if (assetPrice > maxPrice) { return maxPrice; @@ -84,7 +88,7 @@ contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable { int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); - if ((basePrice * priceCapRatio) / 1e8 < assetPrice) { + if ((basePrice * priceCapRatio) / int256(10 ** RATIO_DECIMALS) < assetPrice) { revert CapLowerThanActualPrice(); } diff --git a/src/interfaces/IEURPriceCapAdapterStable.sol b/src/interfaces/IEURPriceCapAdapterStable.sol index 0f436db..cd49603 100644 --- a/src/interfaces/IEURPriceCapAdapterStable.sol +++ b/src/interfaces/IEURPriceCapAdapterStable.sol @@ -16,6 +16,7 @@ interface IEURPriceCapAdapterStable is ICLSynchronicityPriceAdapter { IChainlinkAggregator baseToUsdAggregator; string adapterDescription; int256 priceCapRatio; + uint8 ratioDecimals; } /** @@ -34,6 +35,11 @@ interface IEURPriceCapAdapterStable is ICLSynchronicityPriceAdapter { */ function BASE_TO_USD_AGGREGATOR() external view returns (IChainlinkAggregator); + /** + * @notice Number of decimals of the priceCap ratio + */ + function RATIO_DECIMALS() external view returns (uint8); + /** * @notice ACL manager contract */ From 867d04b2ac1be4957414373f9d904ea37a6b3575 Mon Sep 17 00:00:00 2001 From: Harsh Pandey Date: Fri, 28 Feb 2025 15:51:21 +0530 Subject: [PATCH 7/7] chore: fix adapter --- src/contracts/misc-adapters/EURPriceCapAdapterStable.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol index 77583d3..d958873 100644 --- a/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol +++ b/src/contracts/misc-adapters/EURPriceCapAdapterStable.sol @@ -39,7 +39,7 @@ contract EURPriceCapAdapterStable is IEURPriceCapAdapterStable { } ASSET_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; - BASE_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; + BASE_TO_USD_AGGREGATOR = capAdapterStableParams.baseToUsdAggregator; ACL_MANAGER = capAdapterStableParams.aclManager; RATIO_DECIMALS = capAdapterStableParams.ratioDecimals; description = capAdapterStableParams.adapterDescription;