diff --git a/nest/src/AggregateToken.sol b/nest/src/AggregateToken.sol index dd6bcb7..608fab8 100644 --- a/nest/src/AggregateToken.sol +++ b/nest/src/AggregateToken.sol @@ -477,7 +477,7 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder { function supportsInterface( bytes4 interfaceId ) public view virtual override(ComponentToken, ERC1155Holder) returns (bool) { - return super.supportsInterface(interfaceId); + return super.supportsInterface(interfaceId) || interfaceId == type(IAggregateToken).interfaceId; } } diff --git a/nest/src/ComponentToken.sol b/nest/src/ComponentToken.sol index 55a953d..8bc6d44 100644 --- a/nest/src/ComponentToken.sol +++ b/nest/src/ComponentToken.sol @@ -230,8 +230,8 @@ abstract contract ComponentToken is ComponentTokenStorage storage $ = _getComponentTokenStorage(); return super.supportsInterface(interfaceId) || interfaceId == type(IERC20).interfaceId || interfaceId == type(IAccessControl).interfaceId || interfaceId == type(IERC7575).interfaceId - || interfaceId == 0xe3bc4e65 || ($.asyncDeposit && interfaceId == 0xce3bbe50) - || ($.asyncRedeem && interfaceId == 0x620ee8e4); + || interfaceId == type(IComponentToken).interfaceId || interfaceId == 0xe3bc4e65 + || ($.asyncDeposit && interfaceId == 0xce3bbe50) || ($.asyncRedeem && interfaceId == 0x620ee8e4); } /// @inheritdoc IERC4626 diff --git a/nest/src/interfaces/IAggregateToken.sol b/nest/src/interfaces/IAggregateToken.sol index 30353ce..ae87fc2 100644 --- a/nest/src/interfaces/IAggregateToken.sol +++ b/nest/src/interfaces/IAggregateToken.sol @@ -5,6 +5,122 @@ import { IComponentToken } from "./IComponentToken.sol"; interface IAggregateToken is IComponentToken { + // ========== PUBLIC VIEW FUNCTIONS ========== + + /** + * @notice Get the current ask price for buying the AggregateToken + * @return uint256 Current ask price + */ + function getAskPrice() external view returns (uint256); + + /** + * @notice Get the current bid price for selling the AggregateToken + * @return uint256 Current bid price + */ + function getBidPrice() external view returns (uint256); + + /** + * @notice Get the list of all component tokens ever added + * @return IComponentToken[] Array of component token addresses + */ + function getComponentTokenList() external view returns (IComponentToken[] memory); + + /** + * @notice Check if an address is a registered component token + * @param componentToken ComponentToken to check + * @return bool indicating whether the address is a component token + */ + function getComponentToken( + IComponentToken componentToken + ) external view returns (bool); + + /** + * @notice Check if trading operations are paused + * @return bool indicating whether trading is paused + */ + function isPaused() external view returns (bool); + + // ========== ADMIN FUNCTIONS ========== + + /** + * @notice Add a new component token to the aggregate token + * @dev Only callable by ADMIN_ROLE + * @param componentToken Address of the component token to add + */ + function addComponentToken( + IComponentToken componentToken + ) external; + + /** + * @notice Approve a component token to spend aggregate token's assets + * @dev Only callable by ADMIN_ROLE + * @param componentToken Address of the component token to approve + * @param amount Amount of assets to approve + */ + function approveComponentToken(IComponentToken componentToken, uint256 amount) external; + + /** + * @notice Buy component tokens using the aggregate token's assets + * @dev Only callable by ADMIN_ROLE + * @param componentToken Address of the component token to buy + * @param assets Amount of assets to spend + */ + function buyComponentToken(IComponentToken componentToken, uint256 assets) external; + + /** + * @notice Sell component tokens to receive aggregate token's assets + * @dev Only callable by ADMIN_ROLE + * @param componentToken Address of the component token to sell + * @param componentTokenAmount Amount of component tokens to sell + */ + function sellComponentToken(IComponentToken componentToken, uint256 componentTokenAmount) external; + + /** + * @notice Request to buy component tokens (for async operations) + * @dev Only callable by ADMIN_ROLE + * @param componentToken Address of the component token to buy + * @param assets Amount of assets to spend + */ + function requestBuyComponentToken(IComponentToken componentToken, uint256 assets) external; + + /** + * @notice Request to sell component tokens (for async operations) + * @dev Only callable by ADMIN_ROLE + * @param componentToken Address of the component token to sell + * @param componentTokenAmount Amount of component tokens to sell + */ + function requestSellComponentToken(IComponentToken componentToken, uint256 componentTokenAmount) external; + + /** + * @notice Set the ask price for the aggregate token + * @dev Only callable by PRICE_UPDATER_ROLE + * @param newAskPrice New ask price to set + */ + function setAskPrice( + uint256 newAskPrice + ) external; + + /** + * @notice Set the bid price for the aggregate token + * @dev Only callable by PRICE_UPDATER_ROLE + * @param newBidPrice New bid price to set + */ + function setBidPrice( + uint256 newBidPrice + ) external; + + /** + * @notice Pause all trading operations + * @dev Only callable by ADMIN_ROLE + */ + function pause() external; + + /** + * @notice Unpause all trading operations + * @dev Only callable by ADMIN_ROLE + */ + function unpause() external; + // Events /** diff --git a/nest/src/interfaces/IBoringVaultAdapter.sol b/nest/src/interfaces/IBoringVaultAdapter.sol new file mode 100644 index 0000000..b227676 --- /dev/null +++ b/nest/src/interfaces/IBoringVaultAdapter.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol"; + +interface IBoringVaultAdapter { + + // View Functions + function getVault() external view returns (address); + function getTeller() external view returns (address); + function getAtomicQueue() external view returns (address); + function version() external view returns (uint256); + + // Core Functions + function deposit( + uint256 assets, + address receiver, + address controller, + uint256 minimumMint + ) external returns (uint256 shares); + + function requestRedeem( + uint256 shares, + address receiver, + address controller, + uint256 price, + uint64 deadline + ) external returns (uint256); + + function notifyRedeem(uint256 assets, uint256 shares, address controller) external; + + function redeem(uint256 shares, address receiver, address controller) external returns (uint256 assets); + + // Preview Functions + function previewDeposit( + uint256 assets + ) external view returns (uint256); + function previewRedeem( + uint256 shares + ) external view returns (uint256 assets); + function convertToShares( + uint256 assets + ) external view returns (uint256 shares); + function convertToAssets( + uint256 shares + ) external view returns (uint256 assets); + + // Balance Functions + function balanceOf( + address account + ) external view returns (uint256); + function assetsOf( + address account + ) external view returns (uint256); + + // Events + event VaultChanged(address oldVault, address newVault); + event Reinitialized(uint256 version); + +} diff --git a/nest/src/token/BoringVaultAdapter.sol b/nest/src/token/BoringVaultAdapter.sol index 845a6c1..bbb3f62 100644 --- a/nest/src/token/BoringVaultAdapter.sol +++ b/nest/src/token/BoringVaultAdapter.sol @@ -16,6 +16,7 @@ import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol"; import { IAccountantWithRateProviders } from "../interfaces/IAccountantWithRateProviders.sol"; import { IAtomicQueue } from "../interfaces/IAtomicQueue.sol"; import { IBoringVault } from "../interfaces/IBoringVault.sol"; +import { IBoringVaultAdapter } from "../interfaces/IBoringVaultAdapter.sol"; import { IComponentToken } from "../interfaces/IComponentToken.sol"; import { ILens } from "../interfaces/ILens.sol"; import { ITeller } from "../interfaces/ITeller.sol"; @@ -487,7 +488,7 @@ abstract contract BoringVaultAdapter is function supportsInterface( bytes4 interfaceId ) public view virtual override(ComponentToken, AccessControlUpgradeable) returns (bool) { - return super.supportsInterface(interfaceId); + return super.supportsInterface(interfaceId) || interfaceId == type(IBoringVaultAdapter).interfaceId; } }