generated from bgd-labs/bgd-forge-template
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from bgd-labs/feat/eurc
feat: eur stable price cap adapter
- Loading branch information
Showing
5 changed files
with
209 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
pragma solidity ^0.8.19; | ||
|
||
import {IEURPriceCapAdapterStable, ICLSynchronicityPriceAdapter, IACLManager, IChainlinkAggregator} 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 { | ||
/// @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 IEURPriceCapAdapterStable | ||
uint8 public immutable RATIO_DECIMALS; | ||
|
||
/// @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) { | ||
if (address(capAdapterStableParams.aclManager) == address(0)) { | ||
revert ACLManagerIsZeroAddress(); | ||
} | ||
|
||
ASSET_TO_USD_AGGREGATOR = capAdapterStableParams.assetToUsdAggregator; | ||
BASE_TO_USD_AGGREGATOR = capAdapterStableParams.baseToUsdAggregator; | ||
ACL_MANAGER = capAdapterStableParams.aclManager; | ||
RATIO_DECIMALS = capAdapterStableParams.ratioDecimals; | ||
description = capAdapterStableParams.adapterDescription; | ||
decimals = ASSET_TO_USD_AGGREGATOR.decimals(); | ||
|
||
_setPriceCapRatio(capAdapterStableParams.priceCapRatio); | ||
} | ||
|
||
/// @inheritdoc ICLSynchronicityPriceAdapter | ||
function latestAnswer() external view returns (int256) { | ||
int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); | ||
int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); | ||
int256 maxPrice = (basePrice * _priceCapRatio) / int256(10 ** RATIO_DECIMALS); | ||
|
||
if (assetPrice > maxPrice) { | ||
return maxPrice; | ||
} | ||
|
||
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 ratio | ||
* @param priceCapRatio the new price cap ratio | ||
*/ | ||
function _setPriceCapRatio(int256 priceCapRatio) internal virtual { | ||
int256 assetPrice = ASSET_TO_USD_AGGREGATOR.latestAnswer(); | ||
int256 basePrice = BASE_TO_USD_AGGREGATOR.latestAnswer(); | ||
|
||
if ((basePrice * priceCapRatio) / int256(10 ** RATIO_DECIMALS) < assetPrice) { | ||
revert CapLowerThanActualPrice(); | ||
} | ||
|
||
_priceCapRatio = priceCapRatio; | ||
|
||
emit PriceCapRatioUpdated(priceCapRatio); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
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 ICLSynchronicityPriceAdapter { | ||
/** | ||
* @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 priceCapRatio; | ||
uint8 ratioDecimals; | ||
} | ||
|
||
/** | ||
* @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 Number of decimals of the priceCap ratio | ||
*/ | ||
function RATIO_DECIMALS() external view returns (uint8); | ||
|
||
/** | ||
* @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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}) | ||
) | ||
{} | ||
} |