When calling the getBlockNumber() method on the multicall3 contract on the Arbitrum chain, the value returned appears to be for the Ethereum chain.
I did test this on a few other chains (non-exhaustive) and the getBlockNumber() seems to work as expected on those with the exception of the testnet Arbitrum Goerli.
Environment tested in:
NodeJS v16.19.0
ethers version 6.2.3
Issue Replication
Run the test script below, replacing ARBITRUM_RPC_PROVIDER_URL and ETHEREUM_RPC_PROVIDER_URL with valid RPC provider URLs.
One should witness:
the block number from the Arbitrum multicall3 contract matching the Ethereum block number
the block number from the Arbitrum multicall2 contract matching the Arbitrum block number
Test script:
'use strict';
const ethers = require('ethers');
const MULTICALL3_ADDRESS = '0xcA11bde05977b3631167028862bE2a173976CA11';
const MULTICALL2_ARBITRUM_ADDRESS = '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2';
const MULTICALL_MIN_ABI = [{
"inputs":[
],
"name":"getBlockNumber",
"outputs":[
{
"internalType":"uint256",
"name":"blockNumber",
"type":"uint256"
}
],
"stateMutability":"view",
"type":"function"
}];
const ARBITRUM_RPC_PROVIDER_URL = '';
const ETHEREUM_RPC_PROVIDER_URL = '';
async function test () {
const ArbitrumProvider = new ethers.JsonRpcProvider(ARBITRUM_RPC_PROVIDER_URL);
const multicall3Contract = new ethers.Contract(MULTICALL3_ADDRESS, MULTICALL_MIN_ABI, ArbitrumProvider);
const multicall2Contract = new ethers.Contract(MULTICALL2_ARBITRUM_ADDRESS, MULTICALL_MIN_ABI, ArbitrumProvider);
const EthereumProvider = new ethers.JsonRpcProvider(ETHEREUM_RPC_PROVIDER_URL);
const [arbBlockNumberMulti3, arbBlockNumberMulti2, arbBlockNumberProvider, ethBlockNumberProvider] = await Promise.all([
multicall3Contract.getBlockNumber(),
multicall2Contract.getBlockNumber(),
ArbitrumProvider.getBlockNumber(),
EthereumProvider.getBlockNumber(),
]);
console.log(`Arbitrum block number from multicall3: ${arbBlockNumberMulti3}`);
console.log(`Arbitrum block number from multicall2: ${arbBlockNumberMulti2}`);
console.log(`Arbitrum block number from provider: ${arbBlockNumberProvider}`);
console.log(`Ethereum block number from provider: ${ethBlockNumberProvider}`);
}
test().catch(console.error);
Hey! Yes this is the expected behavior as this is an Arbitrum design decision. You can read more on EVM Diff here—check out the NUMBER opcode and the listed references. This reference will tell you how to access the arbitrum block number
Issue Description
When calling the
getBlockNumber()
method on the multicall3 contract on the Arbitrum chain, the value returned appears to be for the Ethereum chain.I did test this on a few other chains (non-exhaustive) and the
getBlockNumber()
seems to work as expected on those with the exception of the testnet Arbitrum Goerli.Environment tested in:
ethers
version 6.2.3Issue Replication
Run the test script below, replacing
ARBITRUM_RPC_PROVIDER_URL
andETHEREUM_RPC_PROVIDER_URL
with valid RPC provider URLs. One should witness:Test script: