# Picking Up Pennies from Uninitialised Implementation Contracts

By [crewmateJ](https://paragraph.com/@crewmate) · 2023-07-19

---

![crewmateJ](https://storage.googleapis.com/papyrus_images/d0029e4c445e1e18f686e748b88567554a3166ce8f1267f72f1c10fca67a7b6c.png)

crewmateJ

![CoinsBench](https://storage.googleapis.com/papyrus_images/785b74c6f17e80eacc3b7e09b39e33dec58dc50716b20697b17d194df72dcfdb.jpg)

CoinsBench

**NB: article was written in Feb 2023, albeit published in May 2023**

A [post](https://twitter.com/0xCygaar/status/1620496240445378561) by 0xCygaar a few weeks ago explained how he took control of the Qzuki implementation contract. Only a few days later I saw he took control of [another](https://twitter.com/0xCygaar/status/1621417995905167360) NFT project’s implementation contract! It got me thinking… could I do this myself?

Proxies?
--------

If you don’t know how proxy contracts work, this article may not make sense — I would suggest reading up on them quickly, specifically the `Transparent Upgradeable Proxy` pattern.

If you can’t be bothered, just use the diagram below for reference:

[https://www.certik.com/resources/blog/FnfYrOCsy3MG9s9gixfbJ-upgradeable-proxy-contract-security-best-practices](https://www.certik.com/resources/blog/FnfYrOCsy3MG9s9gixfbJ-upgradeable-proxy-contract-security-best-practices)

In essence, proxies exist so the user only ever has to interact with the `Proxy` contract, but devs can still change the `Implementation` contract. The devs can ‘upgrade’ the contract logic, without rocking the (figurative) boat of the whole system.

Most on-chain participants would have interacted with a proxy pattern before, and may even recognise the name `Transparent Upgradeable Proxy` from Etherscan’s labels:

Back to my question
-------------------

Could I find any implementation contracts to take ownership of? Over the next few days, I checked every Transparent Upgradeable Proxy contract I saw.

To my surprise, it was very common for projects to forget to initialise their implementation contract. If a contract is uninitialised, it often means \*anyone \*can call the `initialize()`function and take ownership.

While it’s not a very high-risk mistake, it could\* \*have negative effects for users. If an attacker took control over the implementation contract, they could deploy some phishing attempts under the guise of the original contract deployer. 0xCygaar’s post talks a bit about this.

Another problem is, if users accidentally send ETH to the implementation contract, someone else may be able to yoink it.

Yoinkage is exactly what I have attempted.

I searched the Ethereum mainnet for Transparent Upgradeable Proxies and their implementation contract, to see if any projects have left ETH in uninitialised implementation addresses.

The Process
-----------

*   scan the chain for the `Upgraded(address implementation)` event, the hash is:
    

> 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b

*   Etherscan’s API allows you to query events in a specified block range regardless of contract address. Below is what the Upgraded event typically looks like. The implementation address is in topics\[1\] (it’s padded with 0s).
    

*   once I had the implementation addresses I filtered by ETH balance and token balances
    
*   If a contract was uninitialised and contained ETH, I’d check for the `initialize()` and `withdraw()` functions, then try call them. Some contracts also have a `withdrawToken()` function.
    

You can often tell a contract is uninitialised if the `owner` returns 0x00..00.

In Summary
----------

Well, all that and I only got 0.06 ETH ($100) from one contract -\_-

There were a few unverified contracts with $30–40 in them but after gas I’m sure it wouldn’t be worth it.

Some things I did find:

*   The “Blur Pool contract `0x17584a148d27ac5d06d87771464dacbaf625ce45` has 0.0205 ETH stuck in it but they used the correct measures to prevent anyone from initialising the contract:
    

*   The Covan Cats implementation contract `0x443df53788d483a33a2aaeb8e6f02b78752090c2` has 0.55e stuck in it o\_o
    
*   This contract here is uninitialised with 0.05e and 50 DAI, but there doesn’t seem to be a way to initialise it… `0x939bde6c3495f8b5caa9b9ededec1bc63b35c1fe`.
    

That’s it, thanks for reading!

I hope this inspired some teams to initialise their implementation contracts, so if users accidentally send ETH to them, that ETH can be easily recovered.

Oh, and I’ve already checked most other major EVM chains for yoinkage, I found nothing ://

---

*Originally published on [crewmateJ](https://paragraph.com/@crewmate/picking-up-pennies-from-uninitialised-implementation-contracts)*
