> ## Documentation Index
> Fetch the complete documentation index at: https://docs.optimism.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Modifying predeployed contracts

> Learn how to modify predeployed contracts for an OP Stack chain by upgrading the proxy.

<Info>
  OP Stack Hacks are explicitly things that you can do with the OP Stack that are *not* currently intended for production use.

  OP Stack Hacks are not for the faint of heart. You will not be able to receive significant developer support for OP Stack Hacks — be prepared to get your hands dirty and to work without support.
</Info>

OP Stack blockchains have a number of [predeployed contracts](https://github.com/ethereum-optimism/optimism/blob/129032f15b76b0d2a940443a39433de931a97a44/packages/contracts-bedrock/src/constants.ts) that provide important functionality.
Most of those contracts are proxies that can be upgraded using the `proxyAdminOwner` which was configured when the network was initially deployed.

## Before you begin

In this tutorial, you learn how to modify predeployed contracts for an OP Stack chain by upgrading the proxy. The predeploys are controlled from a predeploy called [`ProxyAdmin`](https://github.com/ethereum-optimism/optimism/blob/129032f15b76b0d2a940443a39433de931a97a44/packages/contracts-bedrock/contracts/universal/ProxyAdmin.sol), whose address is `0x4200000000000000000000000000000000000018`.
The function to call is [`upgrade(address,address)`](https://github.com/ethereum-optimism/optimism/blob/129032f15b76b0d2a940443a39433de931a97a44/packages/contracts-bedrock/contracts/universal/ProxyAdmin.sol#L205-L229).
The first parameter is the proxy to upgrade, and the second is the address of a new implementation.

## Modify the legacy `L1BlockNumber` contract

For example, the legacy `L1BlockNumber` contract is at `0x420...013`.
To disable this function, we'll set the implementation to `0x00...00`.
We do this using the [Foundry](https://book.getfoundry.sh/) command `cast`.

<Steps>
  <Step title="We'll need several constants.">
    * Set these addresses as variables in your terminal.

      ```sh theme={null}
      L1BLOCKNUM=0x4200000000000000000000000000000000000013
      PROXY_ADMIN=0x4200000000000000000000000000000000000018
      ZERO_ADDR=0x0000000000000000000000000000000000000000
      ```

    * Set `PRIVKEY` to the private key of your ADMIN address.

    * Set `ETH_RPC_URL`. If you're on the computer that runs the blockchain, use this command.

      ```sh theme={null}
      export ETH_RPC_URL=http://localhost:8545
      ```
  </Step>

  <Step title="Verify `L1BlockNumber` works correctly.">
    See that when you call the contract you get a block number, and twelve seconds later you get the next one (block time on L1 is twelve seconds).

    ```sh theme={null}
    cast call $L1BLOCKNUM 'number()' | cast --to-dec
    sleep 12 && cast call $L1BLOCKNUM 'number()' | cast --to-dec
    ```
  </Step>

  <Step title="Get the current implementation for the contract.">
    ```sh theme={null}
      L1BLOCKNUM_IMPLEMENTATION=`cast call $L1BLOCKNUM "implementation()" | sed 's/000000000000000000000000//'`
      echo $L1BLOCKNUM_IMPLEMENTATION 
    ```
  </Step>

  <Step title="Change the implementation to the zero address">
    ```sh theme={null}
      cast send --private-key $PRIVKEY $PROXY_ADMIN "upgrade(address,address)" $L1BLOCKNUM $ZERO_ADDR
    ```
  </Step>

  <Step title="See that the implementation is address zero, and that calling it fails.">
    ```sh theme={null}
      cast call $L1BLOCKNUM 'implementation()'
      cast call $L1BLOCKNUM 'number()'
    ```
  </Step>

  <Step title="Fix the predeploy by returning it to the previous implementation, and verify it works.">
    ```sh theme={null}
      cast send --private-key $PRIVKEY $PROXY_ADMIN "upgrade(address,address)" $L1BLOCKNUM $L1BLOCKNUM_IMPLEMENTATION
      cast call $L1BLOCKNUM 'number()' | cast --to-dec
    ```
  </Step>
</Steps>
