From 1ec88bce42a6467f46690c9833649f92c2a8b102 Mon Sep 17 00:00:00 2001 From: ungaro Date: Mon, 9 Dec 2024 12:10:05 -0500 Subject: [PATCH 1/5] add componenttoken interface and script to calculate interfaceid --- .../CalculateComponentTokenInterfaceId.s.sol | 82 +++++++++++++++++++ nest/src/ComponentToken.sol | 4 +- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol diff --git a/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol b/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol new file mode 100644 index 0000000..5885608 --- /dev/null +++ b/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { IComponentToken } from "../../src/interfaces/IComponentToken.sol"; +import { Script } from "forge-std/Script.sol"; +import { console2 } from "forge-std/console2.sol"; + +contract CalculateComponentTokenInterfaceId is Script { + + function run() public view { + bytes4 interfaceId = calculateInterfaceId(); + + // Log results + console2.log("\nIComponentToken Interface ID Calculation Results:"); + console2.log("----------------------------------------"); + console2.log("Interface ID: ", vm.toString(interfaceId)); + + // Log individual function selectors + logFunctionSelectors(); + } + + function calculateInterfaceId() public pure returns (bytes4) { + // Split calculations into groups to avoid stack too deep + bytes4 group1 = calculateGroup1(); + bytes4 group2 = calculateGroup2(); + bytes4 group3 = calculateGroup3(); + + return group1 ^ group2 ^ group3; + } + + function calculateGroup1() public pure returns (bytes4) { + return bytes4( + keccak256("requestDeposit(uint256,address,address)") ^ keccak256("deposit(uint256,address,address)") + ^ keccak256("requestRedeem(uint256,address,address)") ^ keccak256("redeem(uint256,address,address)") + ); + } + + function calculateGroup2() public pure returns (bytes4) { + return bytes4( + keccak256("asset()") ^ keccak256("totalAssets()") ^ keccak256("assetsOf(address)") + ^ keccak256("convertToShares(uint256)") ^ keccak256("convertToAssets(uint256)") + ); + } + + function calculateGroup3() public pure returns (bytes4) { + return bytes4( + keccak256("pendingDepositRequest(uint256,address)") ^ keccak256("claimableDepositRequest(uint256,address)") + ^ keccak256("pendingRedeemRequest(uint256,address)") ^ keccak256("claimableRedeemRequest(uint256,address)") + ); + } + + function logFunctionSelectors() public pure { + console2.log("\nFunction Selectors:"); + console2.log("----------------------------------------"); + console2.log( + "requestDeposit: ", vm.toString(bytes4(keccak256("requestDeposit(uint256,address,address)"))) + ); + console2.log("deposit: ", vm.toString(bytes4(keccak256("deposit(uint256,address,address)")))); + console2.log( + "requestRedeem: ", vm.toString(bytes4(keccak256("requestRedeem(uint256,address,address)"))) + ); + console2.log("redeem: ", vm.toString(bytes4(keccak256("redeem(uint256,address,address)")))); + console2.log("asset: ", vm.toString(bytes4(keccak256("asset()")))); + console2.log("totalAssets: ", vm.toString(bytes4(keccak256("totalAssets()")))); + console2.log("assetsOf: ", vm.toString(bytes4(keccak256("assetsOf(address)")))); + console2.log("convertToShares: ", vm.toString(bytes4(keccak256("convertToShares(uint256)")))); + console2.log("convertToAssets: ", vm.toString(bytes4(keccak256("convertToAssets(uint256)")))); + console2.log( + "pendingDepositRequest: ", vm.toString(bytes4(keccak256("pendingDepositRequest(uint256,address)"))) + ); + console2.log( + "claimableDepositRequest: ", vm.toString(bytes4(keccak256("claimableDepositRequest(uint256,address)"))) + ); + console2.log( + "pendingRedeemRequest: ", vm.toString(bytes4(keccak256("pendingRedeemRequest(uint256,address)"))) + ); + console2.log( + "claimableRedeemRequest: ", vm.toString(bytes4(keccak256("claimableRedeemRequest(uint256,address)"))) + ); + } + +} diff --git a/nest/src/ComponentToken.sol b/nest/src/ComponentToken.sol index cb89485..7681775 100644 --- a/nest/src/ComponentToken.sol +++ b/nest/src/ComponentToken.sol @@ -76,7 +76,7 @@ abstract contract ComponentToken is bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE"); /// @notice Base that is used to divide all price inputs in order to represent e.g. 1.000001 as 1000001e12 uint256 internal constant _BASE = 1e18; - + // Events /** @@ -189,6 +189,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 == 0x1816b2a2 // IComponentToken interface ID - Calculated in + // CalculateComponentTokenInterfaceId.s.sol || interfaceId == 0xe3bc4e65 || ($.asyncDeposit && interfaceId == 0xce3bbe50) || ($.asyncRedeem && interfaceId == 0x620ee8e4); } From 691b704e41ce54853fd88a0c6c7cb5b78fc2a003 Mon Sep 17 00:00:00 2001 From: ungaro Date: Wed, 11 Dec 2024 00:06:43 -0500 Subject: [PATCH 2/5] add BoringVaultAdapter interface, change interfaceId calculation --- .../CalculateAggregateTokenInterfaceId.s.sol | 81 +++++++++++ ...lculateBoringVaultAdapterInterfaceId.s.sol | 37 +++++ .../CalculateComponentTokenInterfaceId.s.sol | 74 ++-------- nest/src/AggregateToken.sol | 3 +- nest/src/interfaces/IAggregateToken.sol | 126 ++++++++++++++++++ nest/src/interfaces/IBoringVaultAdapter.sol | 60 +++++++++ nest/src/token/BoringVaultAdapter.sol | 3 +- 7 files changed, 322 insertions(+), 62 deletions(-) create mode 100644 nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol create mode 100644 nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol create mode 100644 nest/src/interfaces/IBoringVaultAdapter.sol diff --git a/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol b/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol new file mode 100644 index 0000000..083d8bc --- /dev/null +++ b/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { IAggregateToken } from "../../src/interfaces/IAggregateToken.sol"; +import { Script } from "forge-std/Script.sol"; +import { console2 } from "forge-std/console2.sol"; + +contract CalculateAggregateTokenInterfaceId is Script { + + function run() public view { + bytes4 interfaceId = calculateInterfaceId(); + + // Log results + console2.log("\nIAggregateToken Interface ID Calculation Results:"); + console2.log("----------------------------------------"); + console2.log("Interface ID: ", vm.toString(interfaceId)); + + // Log individual function selectors + logFunctionSelectors(); + } + + function calculateInterfaceId() public pure returns (bytes4) { + // Split calculations into groups to avoid stack too deep + bytes4 group1 = calculateGroup1(); + bytes4 group2 = calculateGroup2(); + bytes4 group3 = calculateGroup3(); + + return group1 ^ group2 ^ group3; + } + + function calculateGroup1() public pure returns (bytes4) { + return bytes4( + keccak256("approveComponentToken(address,uint256)") ^ keccak256("addComponentToken(address)") + ^ keccak256("buyComponentToken(address,uint256)") ^ keccak256("sellComponentToken(address,uint256)") + ); + } + + function calculateGroup2() public pure returns (bytes4) { + return bytes4( + keccak256("requestBuyComponentToken(address,uint256)") + ^ keccak256("requestSellComponentToken(address,uint256)") ^ keccak256("setAskPrice(uint256)") + ^ keccak256("setBidPrice(uint256)") + ); + } + + function calculateGroup3() public pure returns (bytes4) { + return bytes4( + keccak256("pause()") ^ keccak256("unpause()") ^ keccak256("getAskPrice()") ^ keccak256("getBidPrice()") + ^ keccak256("getComponentTokenList()") ^ keccak256("isPaused()") ^ keccak256("getComponentToken(address)") + ); + } + + function logFunctionSelectors() public pure { + console2.log("\nFunction Selectors:"); + console2.log("----------------------------------------"); + console2.log( + "approveComponentToken: ", vm.toString(bytes4(keccak256("approveComponentToken(address,uint256)"))) + ); + console2.log("addComponentToken: ", vm.toString(bytes4(keccak256("addComponentToken(address)")))); + console2.log("buyComponentToken: ", vm.toString(bytes4(keccak256("buyComponentToken(address,uint256)")))); + console2.log( + "sellComponentToken: ", vm.toString(bytes4(keccak256("sellComponentToken(address,uint256)"))) + ); + console2.log( + "requestBuyComponentToken: ", vm.toString(bytes4(keccak256("requestBuyComponentToken(address,uint256)"))) + ); + console2.log( + "requestSellComponentToken:", vm.toString(bytes4(keccak256("requestSellComponentToken(address,uint256)"))) + ); + console2.log("setAskPrice: ", vm.toString(bytes4(keccak256("setAskPrice(uint256)")))); + console2.log("setBidPrice: ", vm.toString(bytes4(keccak256("setBidPrice(uint256)")))); + console2.log("pause: ", vm.toString(bytes4(keccak256("pause()")))); + console2.log("unpause: ", vm.toString(bytes4(keccak256("unpause()")))); + console2.log("getAskPrice: ", vm.toString(bytes4(keccak256("getAskPrice()")))); + console2.log("getBidPrice: ", vm.toString(bytes4(keccak256("getBidPrice()")))); + console2.log("getComponentTokenList: ", vm.toString(bytes4(keccak256("getComponentTokenList()")))); + console2.log("isPaused: ", vm.toString(bytes4(keccak256("isPaused()")))); + console2.log("getComponentToken: ", vm.toString(bytes4(keccak256("getComponentToken(address)")))); + } + +} diff --git a/nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol b/nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol new file mode 100644 index 0000000..7cc17b0 --- /dev/null +++ b/nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { IBoringVaultAdapter } from "../../src/interfaces/IBoringVaultAdapter.sol"; +import { Script } from "forge-std/Script.sol"; +import { console2 } from "forge-std/console2.sol"; + +contract CalculateBoringVaultAdapterInterfaceId is Script { + + function run() public view { + bytes4 interfaceId = type(IBoringVaultAdapter).interfaceId; + + // Log results + console2.log("\nIBoringVaultAdapter Interface ID Calculation Results:"); + console2.log("----------------------------------------"); + console2.log("Interface ID: ", vm.toString(interfaceId)); + + // Log individual function selectors for verification + console2.log("\nFunction Selectors:"); + console2.log("----------------------------------------"); + console2.log("getVault: ", vm.toString(IBoringVaultAdapter.getVault.selector)); + console2.log("getTeller: ", vm.toString(IBoringVaultAdapter.getTeller.selector)); + console2.log("getAtomicQueue: ", vm.toString(IBoringVaultAdapter.getAtomicQueue.selector)); + console2.log("version: ", vm.toString(IBoringVaultAdapter.version.selector)); + console2.log("deposit: ", vm.toString(IBoringVaultAdapter.deposit.selector)); + console2.log("requestRedeem: ", vm.toString(IBoringVaultAdapter.requestRedeem.selector)); + console2.log("notifyRedeem: ", vm.toString(IBoringVaultAdapter.notifyRedeem.selector)); + console2.log("redeem: ", vm.toString(IBoringVaultAdapter.redeem.selector)); + console2.log("previewDeposit: ", vm.toString(IBoringVaultAdapter.previewDeposit.selector)); + console2.log("previewRedeem: ", vm.toString(IBoringVaultAdapter.previewRedeem.selector)); + console2.log("convertToShares: ", vm.toString(IBoringVaultAdapter.convertToShares.selector)); + console2.log("convertToAssets: ", vm.toString(IBoringVaultAdapter.convertToAssets.selector)); + console2.log("balanceOf: ", vm.toString(IBoringVaultAdapter.balanceOf.selector)); + console2.log("assetsOf: ", vm.toString(IBoringVaultAdapter.assetsOf.selector)); + } + +} diff --git a/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol b/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol index 5885608..8958cb5 100644 --- a/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol +++ b/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol @@ -8,7 +8,7 @@ import { console2 } from "forge-std/console2.sol"; contract CalculateComponentTokenInterfaceId is Script { function run() public view { - bytes4 interfaceId = calculateInterfaceId(); + bytes4 interfaceId = type(IComponentToken).interfaceId; // Log results console2.log("\nIComponentToken Interface ID Calculation Results:"); @@ -16,67 +16,21 @@ contract CalculateComponentTokenInterfaceId is Script { console2.log("Interface ID: ", vm.toString(interfaceId)); // Log individual function selectors - logFunctionSelectors(); - } - - function calculateInterfaceId() public pure returns (bytes4) { - // Split calculations into groups to avoid stack too deep - bytes4 group1 = calculateGroup1(); - bytes4 group2 = calculateGroup2(); - bytes4 group3 = calculateGroup3(); - - return group1 ^ group2 ^ group3; - } - - function calculateGroup1() public pure returns (bytes4) { - return bytes4( - keccak256("requestDeposit(uint256,address,address)") ^ keccak256("deposit(uint256,address,address)") - ^ keccak256("requestRedeem(uint256,address,address)") ^ keccak256("redeem(uint256,address,address)") - ); - } - - function calculateGroup2() public pure returns (bytes4) { - return bytes4( - keccak256("asset()") ^ keccak256("totalAssets()") ^ keccak256("assetsOf(address)") - ^ keccak256("convertToShares(uint256)") ^ keccak256("convertToAssets(uint256)") - ); - } - - function calculateGroup3() public pure returns (bytes4) { - return bytes4( - keccak256("pendingDepositRequest(uint256,address)") ^ keccak256("claimableDepositRequest(uint256,address)") - ^ keccak256("pendingRedeemRequest(uint256,address)") ^ keccak256("claimableRedeemRequest(uint256,address)") - ); - } - - function logFunctionSelectors() public pure { console2.log("\nFunction Selectors:"); console2.log("----------------------------------------"); - console2.log( - "requestDeposit: ", vm.toString(bytes4(keccak256("requestDeposit(uint256,address,address)"))) - ); - console2.log("deposit: ", vm.toString(bytes4(keccak256("deposit(uint256,address,address)")))); - console2.log( - "requestRedeem: ", vm.toString(bytes4(keccak256("requestRedeem(uint256,address,address)"))) - ); - console2.log("redeem: ", vm.toString(bytes4(keccak256("redeem(uint256,address,address)")))); - console2.log("asset: ", vm.toString(bytes4(keccak256("asset()")))); - console2.log("totalAssets: ", vm.toString(bytes4(keccak256("totalAssets()")))); - console2.log("assetsOf: ", vm.toString(bytes4(keccak256("assetsOf(address)")))); - console2.log("convertToShares: ", vm.toString(bytes4(keccak256("convertToShares(uint256)")))); - console2.log("convertToAssets: ", vm.toString(bytes4(keccak256("convertToAssets(uint256)")))); - console2.log( - "pendingDepositRequest: ", vm.toString(bytes4(keccak256("pendingDepositRequest(uint256,address)"))) - ); - console2.log( - "claimableDepositRequest: ", vm.toString(bytes4(keccak256("claimableDepositRequest(uint256,address)"))) - ); - console2.log( - "pendingRedeemRequest: ", vm.toString(bytes4(keccak256("pendingRedeemRequest(uint256,address)"))) - ); - console2.log( - "claimableRedeemRequest: ", vm.toString(bytes4(keccak256("claimableRedeemRequest(uint256,address)"))) - ); + console2.log("requestDeposit: ", vm.toString(IComponentToken.requestDeposit.selector)); + console2.log("deposit: ", vm.toString(IComponentToken.deposit.selector)); + console2.log("requestRedeem: ", vm.toString(IComponentToken.requestRedeem.selector)); + console2.log("redeem: ", vm.toString(IComponentToken.redeem.selector)); + console2.log("asset: ", vm.toString(IComponentToken.asset.selector)); + console2.log("totalAssets: ", vm.toString(IComponentToken.totalAssets.selector)); + console2.log("assetsOf: ", vm.toString(IComponentToken.assetsOf.selector)); + console2.log("convertToShares: ", vm.toString(IComponentToken.convertToShares.selector)); + console2.log("convertToAssets: ", vm.toString(IComponentToken.convertToAssets.selector)); + console2.log("pendingDepositRequest: ", vm.toString(IComponentToken.pendingDepositRequest.selector)); + console2.log("claimableDepositRequest: ", vm.toString(IComponentToken.claimableDepositRequest.selector)); + console2.log("pendingRedeemRequest: ", vm.toString(IComponentToken.pendingRedeemRequest.selector)); + console2.log("claimableRedeemRequest: ", vm.toString(IComponentToken.claimableRedeemRequest.selector)); } } diff --git a/nest/src/AggregateToken.sol b/nest/src/AggregateToken.sol index 5d57091..2435f1c 100644 --- a/nest/src/AggregateToken.sol +++ b/nest/src/AggregateToken.sol @@ -377,7 +377,8 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder { function supportsInterface( bytes4 interfaceId ) public view virtual override(ComponentToken, ERC1155Holder) returns (bool) { - return super.supportsInterface(interfaceId); + // IAggregateToken interface ID - calculated in CalculateAggregateTokenInterfaceId.s.sol + return super.supportsInterface(interfaceId) || interfaceId == 0x5f3838d6; } } diff --git a/nest/src/interfaces/IAggregateToken.sol b/nest/src/interfaces/IAggregateToken.sol index 30353ce..85cd535 100644 --- a/nest/src/interfaces/IAggregateToken.sol +++ b/nest/src/interfaces/IAggregateToken.sol @@ -5,6 +5,132 @@ 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 Address to check + * @return bool indicating whether the address is a component token + */ + function getComponentToken( + address 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 + * @return bool indicating whether the operation was successful + */ + function addComponentToken( + address componentToken + ) external returns (bool); + + /** + * @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 + * @return bool indicating whether the operation was successful + */ + function approveComponentToken(address componentToken, uint256 amount) external returns (bool); + + /** + * @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 amount Amount of component tokens to buy + * @return uint256 Amount of assets spent + */ + function buyComponentToken(address componentToken, uint256 amount) external returns (uint256); + + /** + * @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 amount Amount of component tokens to sell + * @return uint256 Amount of assets received + */ + function sellComponentToken(address componentToken, uint256 amount) external returns (uint256); + + /** + * @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 amount Amount of component tokens to buy + * @return uint256 Request ID for tracking the buy request + */ + function requestBuyComponentToken(address componentToken, uint256 amount) external returns (uint256); + + /** + * @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 amount Amount of component tokens to sell + * @return uint256 Request ID for tracking the sell request + */ + function requestSellComponentToken(address componentToken, uint256 amount) external returns (uint256); + + /** + * @notice Set the ask price for the aggregate token + * @dev Only callable by PRICE_UPDATER_ROLE + * @param newAskPrice New ask price to set + * @return bool indicating whether the operation was successful + */ + function setAskPrice( + uint256 newAskPrice + ) external returns (bool); + + /** + * @notice Set the bid price for the aggregate token + * @dev Only callable by PRICE_UPDATER_ROLE + * @param newBidPrice New bid price to set + * @return bool indicating whether the operation was successful + */ + function setBidPrice( + uint256 newBidPrice + ) external returns (bool); + + /** + * @notice Pause all trading operations + * @dev Only callable by ADMIN_ROLE + * @return bool indicating whether the operation was successful + */ + function pause() external returns (bool); + + /** + * @notice Unpause all trading operations + * @dev Only callable by ADMIN_ROLE + * @return bool indicating whether the operation was successful + */ + function unpause() external returns (bool); + // 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 2407ad4..81e4f0d 100644 --- a/nest/src/token/BoringVaultAdapter.sol +++ b/nest/src/token/BoringVaultAdapter.sol @@ -482,7 +482,8 @@ abstract contract BoringVaultAdapter is function supportsInterface( bytes4 interfaceId ) public view virtual override(ComponentToken, AccessControlUpgradeable) returns (bool) { - return super.supportsInterface(interfaceId); + // BoringVaultAdapter interface ID - calculated in CalculateBoringVaultAdapterInterfaceId.s.sol + return super.supportsInterface(interfaceId) || interfaceId == 0xa28474c8; } } From b2eae07d0ae78e742df6ca48bdd400c85735e256 Mon Sep 17 00:00:00 2001 From: ungaro Date: Wed, 11 Dec 2024 00:25:06 -0500 Subject: [PATCH 3/5] double check interfaceIds --- .../CalculateAggregateTokenInterfaceId.s.sol | 80 +++++-------------- nest/src/interfaces/IAggregateToken.sol | 44 ++++------ nest/src/token/BoringVaultAdapter.sol | 2 +- 3 files changed, 39 insertions(+), 87 deletions(-) diff --git a/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol b/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol index 083d8bc..e888015 100644 --- a/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol +++ b/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol @@ -8,7 +8,7 @@ import { console2 } from "forge-std/console2.sol"; contract CalculateAggregateTokenInterfaceId is Script { function run() public view { - bytes4 interfaceId = calculateInterfaceId(); + bytes4 interfaceId = type(IAggregateToken).interfaceId; // Log results console2.log("\nIAggregateToken Interface ID Calculation Results:"); @@ -16,66 +16,28 @@ contract CalculateAggregateTokenInterfaceId is Script { console2.log("Interface ID: ", vm.toString(interfaceId)); // Log individual function selectors - logFunctionSelectors(); - } - - function calculateInterfaceId() public pure returns (bytes4) { - // Split calculations into groups to avoid stack too deep - bytes4 group1 = calculateGroup1(); - bytes4 group2 = calculateGroup2(); - bytes4 group3 = calculateGroup3(); - - return group1 ^ group2 ^ group3; - } - - function calculateGroup1() public pure returns (bytes4) { - return bytes4( - keccak256("approveComponentToken(address,uint256)") ^ keccak256("addComponentToken(address)") - ^ keccak256("buyComponentToken(address,uint256)") ^ keccak256("sellComponentToken(address,uint256)") - ); - } - - function calculateGroup2() public pure returns (bytes4) { - return bytes4( - keccak256("requestBuyComponentToken(address,uint256)") - ^ keccak256("requestSellComponentToken(address,uint256)") ^ keccak256("setAskPrice(uint256)") - ^ keccak256("setBidPrice(uint256)") - ); - } - - function calculateGroup3() public pure returns (bytes4) { - return bytes4( - keccak256("pause()") ^ keccak256("unpause()") ^ keccak256("getAskPrice()") ^ keccak256("getBidPrice()") - ^ keccak256("getComponentTokenList()") ^ keccak256("isPaused()") ^ keccak256("getComponentToken(address)") - ); - } - - function logFunctionSelectors() public pure { console2.log("\nFunction Selectors:"); console2.log("----------------------------------------"); - console2.log( - "approveComponentToken: ", vm.toString(bytes4(keccak256("approveComponentToken(address,uint256)"))) - ); - console2.log("addComponentToken: ", vm.toString(bytes4(keccak256("addComponentToken(address)")))); - console2.log("buyComponentToken: ", vm.toString(bytes4(keccak256("buyComponentToken(address,uint256)")))); - console2.log( - "sellComponentToken: ", vm.toString(bytes4(keccak256("sellComponentToken(address,uint256)"))) - ); - console2.log( - "requestBuyComponentToken: ", vm.toString(bytes4(keccak256("requestBuyComponentToken(address,uint256)"))) - ); - console2.log( - "requestSellComponentToken:", vm.toString(bytes4(keccak256("requestSellComponentToken(address,uint256)"))) - ); - console2.log("setAskPrice: ", vm.toString(bytes4(keccak256("setAskPrice(uint256)")))); - console2.log("setBidPrice: ", vm.toString(bytes4(keccak256("setBidPrice(uint256)")))); - console2.log("pause: ", vm.toString(bytes4(keccak256("pause()")))); - console2.log("unpause: ", vm.toString(bytes4(keccak256("unpause()")))); - console2.log("getAskPrice: ", vm.toString(bytes4(keccak256("getAskPrice()")))); - console2.log("getBidPrice: ", vm.toString(bytes4(keccak256("getBidPrice()")))); - console2.log("getComponentTokenList: ", vm.toString(bytes4(keccak256("getComponentTokenList()")))); - console2.log("isPaused: ", vm.toString(bytes4(keccak256("isPaused()")))); - console2.log("getComponentToken: ", vm.toString(bytes4(keccak256("getComponentToken(address)")))); + // Admin Functions + console2.log("addComponentToken: ", vm.toString(IAggregateToken.addComponentToken.selector)); + console2.log("approveComponentToken: ", vm.toString(IAggregateToken.approveComponentToken.selector)); + console2.log("setAskPrice: ", vm.toString(IAggregateToken.setAskPrice.selector)); + console2.log("setBidPrice: ", vm.toString(IAggregateToken.setBidPrice.selector)); + console2.log("pause: ", vm.toString(IAggregateToken.pause.selector)); + console2.log("unpause: ", vm.toString(IAggregateToken.unpause.selector)); + + // Trading Functions + console2.log("buyComponentToken: ", vm.toString(IAggregateToken.buyComponentToken.selector)); + console2.log("sellComponentToken: ", vm.toString(IAggregateToken.sellComponentToken.selector)); + console2.log("requestBuyComponentToken: ", vm.toString(IAggregateToken.requestBuyComponentToken.selector)); + console2.log("requestSellComponentToken:", vm.toString(IAggregateToken.requestSellComponentToken.selector)); + + // View Functions + console2.log("getComponentTokenList: ", vm.toString(IAggregateToken.getComponentTokenList.selector)); + console2.log("getComponentToken: ", vm.toString(IAggregateToken.getComponentToken.selector)); + console2.log("getAskPrice: ", vm.toString(IAggregateToken.getAskPrice.selector)); + console2.log("getBidPrice: ", vm.toString(IAggregateToken.getBidPrice.selector)); + console2.log("isPaused: ", vm.toString(IAggregateToken.isPaused.selector)); } } diff --git a/nest/src/interfaces/IAggregateToken.sol b/nest/src/interfaces/IAggregateToken.sol index 85cd535..ae87fc2 100644 --- a/nest/src/interfaces/IAggregateToken.sol +++ b/nest/src/interfaces/IAggregateToken.sol @@ -27,11 +27,11 @@ interface IAggregateToken is IComponentToken { /** * @notice Check if an address is a registered component token - * @param componentToken Address to check + * @param componentToken ComponentToken to check * @return bool indicating whether the address is a component token */ function getComponentToken( - address componentToken + IComponentToken componentToken ) external view returns (bool); /** @@ -46,90 +46,80 @@ interface IAggregateToken is IComponentToken { * @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 - * @return bool indicating whether the operation was successful */ function addComponentToken( - address componentToken - ) external returns (bool); + 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 - * @return bool indicating whether the operation was successful */ - function approveComponentToken(address componentToken, uint256 amount) external returns (bool); + 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 amount Amount of component tokens to buy - * @return uint256 Amount of assets spent + * @param assets Amount of assets to spend */ - function buyComponentToken(address componentToken, uint256 amount) external returns (uint256); + 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 amount Amount of component tokens to sell - * @return uint256 Amount of assets received + * @param componentTokenAmount Amount of component tokens to sell */ - function sellComponentToken(address componentToken, uint256 amount) external returns (uint256); + 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 amount Amount of component tokens to buy - * @return uint256 Request ID for tracking the buy request + * @param assets Amount of assets to spend */ - function requestBuyComponentToken(address componentToken, uint256 amount) external returns (uint256); + 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 amount Amount of component tokens to sell - * @return uint256 Request ID for tracking the sell request + * @param componentTokenAmount Amount of component tokens to sell */ - function requestSellComponentToken(address componentToken, uint256 amount) external returns (uint256); + 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 - * @return bool indicating whether the operation was successful */ function setAskPrice( uint256 newAskPrice - ) external returns (bool); + ) external; /** * @notice Set the bid price for the aggregate token * @dev Only callable by PRICE_UPDATER_ROLE * @param newBidPrice New bid price to set - * @return bool indicating whether the operation was successful */ function setBidPrice( uint256 newBidPrice - ) external returns (bool); + ) external; /** * @notice Pause all trading operations * @dev Only callable by ADMIN_ROLE - * @return bool indicating whether the operation was successful */ - function pause() external returns (bool); + function pause() external; /** * @notice Unpause all trading operations * @dev Only callable by ADMIN_ROLE - * @return bool indicating whether the operation was successful */ - function unpause() external returns (bool); + function unpause() external; // Events diff --git a/nest/src/token/BoringVaultAdapter.sol b/nest/src/token/BoringVaultAdapter.sol index 931dbc0..dde7c1a 100644 --- a/nest/src/token/BoringVaultAdapter.sol +++ b/nest/src/token/BoringVaultAdapter.sol @@ -488,7 +488,7 @@ abstract contract BoringVaultAdapter is bytes4 interfaceId ) public view virtual override(ComponentToken, AccessControlUpgradeable) returns (bool) { // BoringVaultAdapter interface ID - calculated in CalculateBoringVaultAdapterInterfaceId.s.sol - return super.supportsInterface(interfaceId) || interfaceId == 0xa28474c8; + return super.supportsInterface(interfaceId) || interfaceId == 0x265bbbe2; } } From c45ab7745a3f11556ac4783eb7dbb9dd41e46d1c Mon Sep 17 00:00:00 2001 From: ungaro Date: Wed, 11 Dec 2024 00:43:54 -0500 Subject: [PATCH 4/5] formatting and fixes boringvaultadapter --- nest/src/AggregateToken.sol | 3 +-- nest/src/ComponentToken.sol | 6 ++---- nest/src/token/BoringVaultAdapter.sol | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/nest/src/AggregateToken.sol b/nest/src/AggregateToken.sol index 881c334..74bea5a 100644 --- a/nest/src/AggregateToken.sol +++ b/nest/src/AggregateToken.sol @@ -472,8 +472,7 @@ contract AggregateToken is ComponentToken, IAggregateToken, ERC1155Holder { function supportsInterface( bytes4 interfaceId ) public view virtual override(ComponentToken, ERC1155Holder) returns (bool) { - // IAggregateToken interface ID - calculated in CalculateAggregateTokenInterfaceId.s.sol - return super.supportsInterface(interfaceId) || interfaceId == 0x5f3838d6; + return super.supportsInterface(interfaceId) || interfaceId == type(IAggregateToken).interfaceId; } } diff --git a/nest/src/ComponentToken.sol b/nest/src/ComponentToken.sol index 2080f3c..8bc6d44 100644 --- a/nest/src/ComponentToken.sol +++ b/nest/src/ComponentToken.sol @@ -230,10 +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 == 0x1816b2a2 // IComponentToken interface ID - Calculated in - // CalculateComponentTokenInterfaceId.s.sol - || 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/token/BoringVaultAdapter.sol b/nest/src/token/BoringVaultAdapter.sol index dde7c1a..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,8 +488,7 @@ abstract contract BoringVaultAdapter is function supportsInterface( bytes4 interfaceId ) public view virtual override(ComponentToken, AccessControlUpgradeable) returns (bool) { - // BoringVaultAdapter interface ID - calculated in CalculateBoringVaultAdapterInterfaceId.s.sol - return super.supportsInterface(interfaceId) || interfaceId == 0x265bbbe2; + return super.supportsInterface(interfaceId) || interfaceId == type(IBoringVaultAdapter).interfaceId; } } From 7a6ecd4b1004a718e386d37177fd9d7a863cdec7 Mon Sep 17 00:00:00 2001 From: ungaro Date: Wed, 11 Dec 2024 12:13:15 -0500 Subject: [PATCH 5/5] delete helper scripts --- .../CalculateAggregateTokenInterfaceId.s.sol | 43 ------------------- ...lculateBoringVaultAdapterInterfaceId.s.sol | 37 ---------------- .../CalculateComponentTokenInterfaceId.s.sol | 36 ---------------- 3 files changed, 116 deletions(-) delete mode 100644 nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol delete mode 100644 nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol delete mode 100644 nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol diff --git a/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol b/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol deleted file mode 100644 index e888015..0000000 --- a/nest/script/helpers/CalculateAggregateTokenInterfaceId.s.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -import { IAggregateToken } from "../../src/interfaces/IAggregateToken.sol"; -import { Script } from "forge-std/Script.sol"; -import { console2 } from "forge-std/console2.sol"; - -contract CalculateAggregateTokenInterfaceId is Script { - - function run() public view { - bytes4 interfaceId = type(IAggregateToken).interfaceId; - - // Log results - console2.log("\nIAggregateToken Interface ID Calculation Results:"); - console2.log("----------------------------------------"); - console2.log("Interface ID: ", vm.toString(interfaceId)); - - // Log individual function selectors - console2.log("\nFunction Selectors:"); - console2.log("----------------------------------------"); - // Admin Functions - console2.log("addComponentToken: ", vm.toString(IAggregateToken.addComponentToken.selector)); - console2.log("approveComponentToken: ", vm.toString(IAggregateToken.approveComponentToken.selector)); - console2.log("setAskPrice: ", vm.toString(IAggregateToken.setAskPrice.selector)); - console2.log("setBidPrice: ", vm.toString(IAggregateToken.setBidPrice.selector)); - console2.log("pause: ", vm.toString(IAggregateToken.pause.selector)); - console2.log("unpause: ", vm.toString(IAggregateToken.unpause.selector)); - - // Trading Functions - console2.log("buyComponentToken: ", vm.toString(IAggregateToken.buyComponentToken.selector)); - console2.log("sellComponentToken: ", vm.toString(IAggregateToken.sellComponentToken.selector)); - console2.log("requestBuyComponentToken: ", vm.toString(IAggregateToken.requestBuyComponentToken.selector)); - console2.log("requestSellComponentToken:", vm.toString(IAggregateToken.requestSellComponentToken.selector)); - - // View Functions - console2.log("getComponentTokenList: ", vm.toString(IAggregateToken.getComponentTokenList.selector)); - console2.log("getComponentToken: ", vm.toString(IAggregateToken.getComponentToken.selector)); - console2.log("getAskPrice: ", vm.toString(IAggregateToken.getAskPrice.selector)); - console2.log("getBidPrice: ", vm.toString(IAggregateToken.getBidPrice.selector)); - console2.log("isPaused: ", vm.toString(IAggregateToken.isPaused.selector)); - } - -} diff --git a/nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol b/nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol deleted file mode 100644 index 7cc17b0..0000000 --- a/nest/script/helpers/CalculateBoringVaultAdapterInterfaceId.s.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -import { IBoringVaultAdapter } from "../../src/interfaces/IBoringVaultAdapter.sol"; -import { Script } from "forge-std/Script.sol"; -import { console2 } from "forge-std/console2.sol"; - -contract CalculateBoringVaultAdapterInterfaceId is Script { - - function run() public view { - bytes4 interfaceId = type(IBoringVaultAdapter).interfaceId; - - // Log results - console2.log("\nIBoringVaultAdapter Interface ID Calculation Results:"); - console2.log("----------------------------------------"); - console2.log("Interface ID: ", vm.toString(interfaceId)); - - // Log individual function selectors for verification - console2.log("\nFunction Selectors:"); - console2.log("----------------------------------------"); - console2.log("getVault: ", vm.toString(IBoringVaultAdapter.getVault.selector)); - console2.log("getTeller: ", vm.toString(IBoringVaultAdapter.getTeller.selector)); - console2.log("getAtomicQueue: ", vm.toString(IBoringVaultAdapter.getAtomicQueue.selector)); - console2.log("version: ", vm.toString(IBoringVaultAdapter.version.selector)); - console2.log("deposit: ", vm.toString(IBoringVaultAdapter.deposit.selector)); - console2.log("requestRedeem: ", vm.toString(IBoringVaultAdapter.requestRedeem.selector)); - console2.log("notifyRedeem: ", vm.toString(IBoringVaultAdapter.notifyRedeem.selector)); - console2.log("redeem: ", vm.toString(IBoringVaultAdapter.redeem.selector)); - console2.log("previewDeposit: ", vm.toString(IBoringVaultAdapter.previewDeposit.selector)); - console2.log("previewRedeem: ", vm.toString(IBoringVaultAdapter.previewRedeem.selector)); - console2.log("convertToShares: ", vm.toString(IBoringVaultAdapter.convertToShares.selector)); - console2.log("convertToAssets: ", vm.toString(IBoringVaultAdapter.convertToAssets.selector)); - console2.log("balanceOf: ", vm.toString(IBoringVaultAdapter.balanceOf.selector)); - console2.log("assetsOf: ", vm.toString(IBoringVaultAdapter.assetsOf.selector)); - } - -} diff --git a/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol b/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol deleted file mode 100644 index 8958cb5..0000000 --- a/nest/script/helpers/CalculateComponentTokenInterfaceId.s.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -import { IComponentToken } from "../../src/interfaces/IComponentToken.sol"; -import { Script } from "forge-std/Script.sol"; -import { console2 } from "forge-std/console2.sol"; - -contract CalculateComponentTokenInterfaceId is Script { - - function run() public view { - bytes4 interfaceId = type(IComponentToken).interfaceId; - - // Log results - console2.log("\nIComponentToken Interface ID Calculation Results:"); - console2.log("----------------------------------------"); - console2.log("Interface ID: ", vm.toString(interfaceId)); - - // Log individual function selectors - console2.log("\nFunction Selectors:"); - console2.log("----------------------------------------"); - console2.log("requestDeposit: ", vm.toString(IComponentToken.requestDeposit.selector)); - console2.log("deposit: ", vm.toString(IComponentToken.deposit.selector)); - console2.log("requestRedeem: ", vm.toString(IComponentToken.requestRedeem.selector)); - console2.log("redeem: ", vm.toString(IComponentToken.redeem.selector)); - console2.log("asset: ", vm.toString(IComponentToken.asset.selector)); - console2.log("totalAssets: ", vm.toString(IComponentToken.totalAssets.selector)); - console2.log("assetsOf: ", vm.toString(IComponentToken.assetsOf.selector)); - console2.log("convertToShares: ", vm.toString(IComponentToken.convertToShares.selector)); - console2.log("convertToAssets: ", vm.toString(IComponentToken.convertToAssets.selector)); - console2.log("pendingDepositRequest: ", vm.toString(IComponentToken.pendingDepositRequest.selector)); - console2.log("claimableDepositRequest: ", vm.toString(IComponentToken.claimableDepositRequest.selector)); - console2.log("pendingRedeemRequest: ", vm.toString(IComponentToken.pendingRedeemRequest.selector)); - console2.log("claimableRedeemRequest: ", vm.toString(IComponentToken.claimableRedeemRequest.selector)); - } - -}