I made a small oversight and didn't account for the Berlin hard fork which increased gas costs for transferring ETH between contracts. I reused a previously tested withdrawETH function that works with wallets but obviously won't work with contracts post-Berlin fork, at least not with normal transactions.

Fortunately, to prevent contract breaking, there's EIP-2930 which introduces a new transaction type to pre-pay for accounts and storage slots, thus leaving enough gas for the ETH transfer.

I'd like a bit of help to verify if this is the correct way to execute my transaction, which would call withdrawETH with enough gas on this deployed contract, based on code from this example:

async function run() {
    wallet = new ethers.Wallet.fromMnemonic(process.env.MAINNET_MNEMONIC)
    wallet = wallet.connect(provider)
    const address = "0xb82FdA3F5752FC3b7243259e893B99DDB13D4546"; // contract address

    contract = new ethers.Contract(address, abi, wallet)

    overrides = {
        gasLimit: 500000,
        gasPrice: ethers.utils.parseUnits('150', 'gwei').toString(),
        type: 1,
        accessList: [
                address: "0xDbaD7CbcA084DFf4E93B0f365978362aD8cc0A35", // admin gnosis safe proxy address
                storageKeys: [
                address: '0xDaB5dc22350f9a6Aff03Cf3D9341aAD0ba42d2a6',  // gnosis safe master address? not sure if this is it
                storageKeys: []

    withdrawTxn = await contract.withdrawETH(overrides)
    console.log({ withdrawTxn })
    resolved = await withdrawTxn.wait()
    console.log({ resolved })

Appreciate any advice before I try it out on mainnet. Thanks in advance!

EDIT: After changing the gnosis safe master address to the correct one from the answer, it worked like a charm.


1 Answer 1


The mastercopy address of the Safe that you linked is 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552. This information can be loaded from our services, checked via Etherscan or looked up on-chain by using the masterCopy() function.

A general list of addresses for the Safe contracts can be found in the safe-deployments repository.

As an alternative to the access list you could call this method from the target Safe itself.

We have a general help article on this here: https://help.gnosis-safe.io/en/articles/5249851-why-can-t-i-transfer-eth-from-a-contract-into-a-safe

  • Thank you for the fast reply! The help article didn't mention as much information.
    – Ape Toshi
    Commented Feb 23, 2022 at 16:12
  • Yeah the help article has less technical details, as this is currently not straight forward.
    – Richard
    Commented Feb 23, 2022 at 16:22
  • My transactions are spinning endlessly and never failing. In my access list I have the gnosis safe proxy address, implementation address (same as the mastercopy address) as well as the owner (there is only one in this test address), but it seems to still be failing.
    – James
    Commented Apr 19, 2022 at 14:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.