web3.js icon indicating copy to clipboard operation
web3.js copied to clipboard

An issue when calling a method on diamonds proxy contract

Open Muhammad-Altabba opened this issue 1 year ago • 1 comments

description

There is an issue specifically with diamonds proxy contract. Probably some or all other proxy contracts work. When calling the proxy contract address an error is throw:

   ContractExecutionError: Error happened while trying to execute a function inside a smart contract

  455 |             // However, more processing will happen at a higher level to decode the error data,
  456 |             //      according to the Error ABI, if it was available as of EIP-838.
> 457 |             if (error?.message.includes('revert')) throw new ContractExecutionError(error);
      |                                                          ^
  458 |
  459 |             return false;
  460 |     }

  at Function._isReverted (../../../web3v4.x/packages/web3-core/src/web3_request_manager.ts:457:48)
  at Web3RequestManager._processJsonRpcResponse (../../../web3v4.x/packages/web3-core/src/web3_request_manager.ts:396:35)
  at Web3RequestManager.<anonymous> (../../../web3v4.x/packages/web3-core/src/web3_request_manager.ts:226:16)
  at fulfilled (../../../web3v4.x/packages/web3-core/lib/commonjs/web3_request_manager.js:21:58)

Cause:

Note: As shown above the Cause: is empty and no text after it.

The diamonds proxy standard is defined in the EIP 2535: https://eips.ethereum.org/EIPS/eip-2535

Fixing this is needed for the zkSync plugin. Kindly check: https://github.com/ChainSafe/web3-plugin-zksync/commit/37b161514ce78b8b7f4f230a82ee2d09f409626c

Steps to reproduce the behavior

import { Contract, Web3 } from 'web3';

describe('diamonds proxy tests', () => {
	const ABI = [
		{
			inputs: [],
			name: 'getName',
			outputs: [
				{
					internalType: 'string',
					name: '',
					type: 'string',
				},
			],
			stateMutability: 'view',
			type: 'function',
		},
	] as const;
	it('using direct contract', async () => {
		const web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/VCOFgnRGJF_vdAY2ZjgSksL6-6pYvRkz');
		const contract = new Contract(ABI, '0x550cf73F4b50aA0DF0257f2D07630D48fA00f73a', web3);
		const contractName = await contract.methods.getName().call();

		expect(contractName).toBe('MailboxFacet');
	});

        // This currently throws! ContractExecutionError: Error happened while trying to execute a function inside a smart contract
	it('using diamonds proxy contract', async () => {
		const web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/VCOFgnRGJF_vdAY2ZjgSksL6-6pYvRkz');
		const contract = new Contract(ABI, '0x9A6DE0f62Aa270A8bCB1e2610078650D539B1Ef9', web3);
		const contractName = await contract.methods.getName().call();

		expect(contractName).toBe('MailboxFacet');
	});
});

Muhammad-Altabba avatar Jul 08 '24 23:07 Muhammad-Altabba

It turns out only registered facets functions of a diamonds proxy would be callable. And getName is not available in the proxy contract. So, no issues with web3.js. Calling methods in a diamonds proxy contract works well and here is an example:

	it('using diamonds proxy contract', async () => {
		const web3 = new Web3('https://eth-sepolia.g.alchemy.com/v2/VCOFgnRGJF_vdAY2ZjgSksL6-6pYvRkz');
		const contract = new Contract(ABI, '0x9A6DE0f62Aa270A8bCB1e2610078650D539B1Ef9', web3);

		const l2TransactionBaseCost = await contract.methods
			.l2TransactionBaseCost(BigInt(18556727650), BigInt(14414298), 800)
			.call();
		expect(l2TransactionBaseCost).toBeGreaterThan(BigInt(0));
	});

However, the error parsing in web3.js would better to be able to handle Error(string) and Panic(uint256). So, an MR will be opened for this.

Muhammad-Altabba avatar Jul 16 '24 11:07 Muhammad-Altabba