diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index da7453f5204e..8a0e34c946b9 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1609,7 +1609,10 @@ impl SimpleCast { /// Generates an interface in solidity from either a local file ABI or a verified contract on /// Etherscan. It returns a vector of [`InterfaceSource`] structs that contain the source of the /// interface and their name. - /// ```ignore + /// + /// Note: This removes the constructor from the ABI before generating the interface. + /// + /// ```no_run /// use cast::{AbiPath, SimpleCast as Cast}; /// # async fn foo() -> eyre::Result<()> { /// let path = @@ -1620,7 +1623,7 @@ impl SimpleCast { /// # } /// ``` pub async fn generate_interface(address_or_path: AbiPath) -> Result> { - let (contract_abis, contract_names) = match address_or_path { + let (mut contract_abis, contract_names) = match address_or_path { AbiPath::Local { path, name } => { let file = std::fs::read_to_string(&path).wrap_err("unable to read abi file")?; let obj: ContractObject = serde_json::from_str(&file)?; @@ -1643,9 +1646,12 @@ impl SimpleCast { } }; contract_abis - .iter() + .iter_mut() .zip(contract_names) .map(|(contract_abi, name)| { + // need to filter out the constructor + contract_abi.constructor.take(); + let source = foundry_cli::utils::abi_to_solidity(contract_abi, &name)?; Ok(InterfaceSource { name, diff --git a/crates/cast/tests/cli/main.rs b/crates/cast/tests/cli/main.rs index 41cef5e61675..7df9d4b91f6a 100644 --- a/crates/cast/tests/cli/main.rs +++ b/crates/cast/tests/cli/main.rs @@ -757,3 +757,37 @@ casttest!(balance, |_prj, cmd| { assert_ne!(usdt_result, "0x0000000000000000000000000000000000000000000000000000000000000000"); assert_eq!(alias_result, usdt_result); }); + +// tests that `cast interface` excludes the constructor +// +casttest!(interface_no_constructor, |prj, cmd| { + let interface = include_str!("../fixtures/interface.json"); + + let path = prj.root().join("interface.json"); + fs::write(&path, interface).unwrap(); + // Call `cast find-block` + cmd.args(["interface"]).arg(&path); + let output = cmd.stdout_lossy(); + + let s = r#"// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.4; + +interface Interface { + type SpendAssetsHandleType is uint8; + + function getIntegrationManager() external view returns (address integrationManager_); + function lend(address _vaultProxy, bytes memory, bytes memory _assetData) external; + function parseAssetsForAction(address, bytes4 _selector, bytes memory _actionData) + external + view + returns ( + SpendAssetsHandleType spendAssetsHandleType_, + address[] memory spendAssets_, + uint256[] memory spendAssetAmounts_, + address[] memory incomingAssets_, + uint256[] memory minIncomingAssetAmounts_ + ); + function redeem(address _vaultProxy, bytes memory, bytes memory _assetData) external; +}"#; + assert_eq!(output.trim(), s); +}); diff --git a/crates/cast/tests/fixtures/interface.json b/crates/cast/tests/fixtures/interface.json new file mode 100644 index 000000000000..73e561886a96 --- /dev/null +++ b/crates/cast/tests/fixtures/interface.json @@ -0,0 +1,141 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_integrationManager", + "type": "address", + "internalType": "address" + }, + { + "name": "_addressListRegistry", + "type": "address", + "internalType": "address" + }, + { + "name": "_aTokenListId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_pool", + "type": "address", + "internalType": "address" + }, + { + "name": "_referralCode", + "type": "uint16", + "internalType": "uint16" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getIntegrationManager", + "inputs": [], + "outputs": [ + { + "name": "integrationManager_", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "lend", + "inputs": [ + { + "name": "_vaultProxy", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "_assetData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "parseAssetsForAction", + "inputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + }, + { + "name": "_selector", + "type": "bytes4", + "internalType": "bytes4" + }, + { + "name": "_actionData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "spendAssetsHandleType_", + "type": "uint8", + "internalType": "enum IIntegrationManager.SpendAssetsHandleType" + }, + { + "name": "spendAssets_", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "spendAssetAmounts_", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "incomingAssets_", + "type": "address[]", + "internalType": "address[]" + }, + { + "name": "minIncomingAssetAmounts_", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "redeem", + "inputs": [ + { + "name": "_vaultProxy", + "type": "address", + "internalType": "address" + }, + { + "name": "", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "_assetData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + } +] \ No newline at end of file