Recreating Kubz NFT Hack and understanding what went wrong


Another day, another white-hat takeover of an NFT project that isn’t writing their proxy contracts correctly.

Here is the transaction:

How it happened you may ask? Rather than explaining, Let’s recreate this hack for a deeper understanding of what exactly happened.

Firstly, we need to fork the Ethereum Mainnet (since the contract is deployed on Ethereum) at block number 16546861, which was 1 block before the hack was performed.

To make our live easier, just head out to and create a private testnet forked from 16546861. Screenshot below:

Click on ‘Add to MetaMask’

Visit the faucet, connect your wallet, enter the desired amount, and click on “Get BB Eth”.

If you have noticed , we can also mint popular ERC20 Tokens. Isn’t this easy then using local Hardhat Network.

Next, visit the BuildBear Explorer from teh home page and search for `0x583223027e4ae2b4466fcd51510992c6f64503de`

Yes, every Testnet has its own Explorer

In the contracts section, we will move to the ‘Write Contract’ section and click on ‘Connect to Web3’ to connect the explorer to our wallet. Make sure that you are on the custom Testnet.


Call the ‘Initialize’ function and enter your wallet address.

Finally, click on ‘Write’ and sign the transaction on our wallet.

We did it, now you are the owner of this contract and have the ability to call any owner-only functions on the implementation contract.Isn’t this easy.

Since we are NOW the owners, let’s airdrop some Nfts to ourselves.

We have successfully recreated the hack and got ourselves some NFTs🎉🎉

Let me also show how you can prevent this hack

It’s simple, there’s something called `_disableInitializers` that you should add to your implementation’s constructor. More info here

Here is more information about proxy smart contracts

Poxy contracts are used in the context of upgradeable smart contracts. Upgradeable smart contracts are composed of 3 contracts:

  • Proxy contract. The smart contract that the user interacts with. It will keep data/state which means data is stored in the context of this proxy contract account. This is an EIP1967 standard proxy contract.
  • Implementation contract. The smart contract provides functionality and logic. Please note that the data is also defined in this contract. This is the smart contract you are building.
  • ProxyAdmin contract. The contract links Proxy and Implementation.

ProxyAmdin explained in OpenZeppelin docs:

What is a proxy admin?

ProxyAdmin is a contract that acts as the owner of all your proxies. Only one per network gets deployed. When you start your project, the ProxyAdmin is owned by the deployer address, but you can transfer ownership of it by calling transferOwnership.

If you transfer ProxyAmin ownership to a multi-sig account, the authority to upgrade the Proxy contract (link proxy to new implementation) is transferred to it.

If you want to know how to modify a contract to be upgradeable, you can refer to the OpenZeppelin docs: link.

This is for education purposes only.

About BuildBear:

BuildBear is a platform for testing dApps at scale, for teams. It provides users with their own private Testnet to test their smart contracts and dApps, which can be forked from any EVM chain. It also provides a Faucet, Explorer, and RPC for testing purposes.

BuildBear aims to be building an ecosystem of tools for testing dApps at scale for the teams.

If you appreciate what we are doing, please follow us on Twitter, and LinkedIn and Join the Telegram group if you haven’t done yet.

And please give us a clap 👏 if you like our work.

Authors: Chandan

Let’s get started then, Shall we?