# Uniswap NFT USDC Airdrop - eligible address research findings
TLDR
- In 2020, Uniswap's airdrop set an example for the industry: query codes are open sourced and query methodology are explained in detail. It would be great to preserve the previous practice when conducting airdrop in the future.
- There are 33 eligible addresses excluded from the current airdrop list. The reason might be that transactions from contract wallets like Gnosis Safe were omitted. This can be resolved by creating a new claiming contract for these addresses.
# Research methodology
- For each criteria
- I explain the methodology I use, and attach all the query codes I use.
- I compare my query result to the current address list, to get false negative cases and false positive cases.
- false negative cases
- Addresses that are in my query result, but not in the current address list.
- i.e., these addresses may meet the criteria.
- false positive cases
- Addresses that are the current address list, but not in in my query result.
- i.e., these addresses may not meet the criteria
# Criteria recap
According to the [official announcement](https://uniswap.org/blog/uniswap-nft-aggregator-announcement), there are 2 criterias:
- **Criteria 1**: Wallets that completed more than one transaction before snapshot (April 15, 2022 at 00:00 UTC)
- **Criteria 2**
- **Criteria 2a**: wallets that held the Genie:Genesis NFT as of the snapshot (April 15, 2022 at 00:00 UTC).
- **Criteria 2b**: wallets that purchased a Genie:Genesis NFT or a Genie:Gem NFT between 5:59 pm and 9:15 pm UTC on June 21st.
# Criteria 1
## query methodology for Criteria 1
Criteria 1: Wallets that completed more than one transaction before snapshot (April 15, 2022 at 00:00 UTC)
Genie has 5 contracts. Among them, 4 contracts have 1 functions to trigger the NFT trading transaction, while 1 contract has 2 functions.
| contract | function_selector | function selector check|
| -------- | -------- | -------- |
| 0x0a267cf51ef038fc00e71801f5a524aec06e4f07 | 0x186b100c | https://dune.com/queries/1724912 |
| 0x2af4b707e1dce8fc345f38cfeeaa2421e54976d5 | 0x8e1d75a8 | https://dune.com/queries/1724915 |
| 0x31837aaf36961274a04b915697fdfca1af31a0c7 | 0x96582bba | https://dune.com/queries/1724918 |
| 0xf97e9727d8e7db7aa8f006d1742d107cf9411412 | 0x8840e19e | https://dune.com/queries/1724922 |
| 0xcdface5643b90ca4b3160dd2b5de80c1bf1cb088 | 0x87201b41, 0xe7acab24 | https://dune.com/queries/1724921 |
To get which addresses are eligible for this criteria, I search for which addresses successfully called these functions more than once in the given time frame. Please refer to the query link: https://dune.com/queries/1724956
## false negative cases for Criteria 1
Please refer to the query link: https://dune.com/queries/1725002
The above query returns 34 addresses.
0x0a267cf51ef038fc00e71801f5a524aec06e4f07 is Genie's router address, so that this contract will call the corresponding Genie Market contract. Therefore, this address shall be excluded for Criteria 1.
For the remaining 33 addresses
- 27 of them are Gnosis Safe wallets
- 4 of them are Argent wallets
- 1 of them is a Loopring wallet
- 1 of them is a MEV bot contract
These wallets aren't included in the current eligible list. The reason for this is most likely that the current query only consider EOA calls. i.e., query `ethereum.transactions` table instead of `ethereum.traces` table. Since these wallets are contracts other than EOAs, when a wallet user use genie in this case, an EOA address will call the wallet contract, and the wallet contract will call the genie contract internally afterwards. Therefore, these transactions cannot be found in `ethereum.transactions` table.
SAFE, Argent and Loopring are all in the [wallet list of Ethereum Foundation's website]( https://ethereum.org/en/wallets/find-wallet/). As account abstraction becomes popular in the Ethereum ecosystem, it is recommended that transactions triggered from contract wallets be handled more carefully.
I have manually checked that these wallets are all qualified, and checked that there are no more intermediate proxy contracts involved.
Please refer https://dune.com/queries/1725020 to check all corresponding trasactions for these 33 wallets.
**To sum up, a total of 33 wallet addresses completed more than one transaction before snapshot, so they all meet Criteria 1, but are not included in the current airdrop list for Criteria 1.**
| Wallet | tx count | Wallet Type |
| -------- | -------- | -------- |
0x419894cb1b4e04f4521fd79e470a379066f0149e | 18 | SAFE |
0x0ea4e5ad7e5d0626d097a3fdb6f96b8e4eaf1967 | 14 | SAFE |
0x2fc36980873ab67d9720a3cdedd96382b4a4870a | 12 | SAFE |
0x2aab909d36581cbc427b8ef0d9484b9f0c484c28 | 12 | Argent |
0x17d76b55efc331e83b48fe034420b47f6af8e6a8 | 8 | SAFE |
0x7a75e85d6d3f0b6d7363a5d7f23adc25101131e7 | 8 | SAFE |
0x5ed4e2797ebcf8b0c34271a7fdc9a12fc47c0f25 | 7 | SAFE |
0x6a693a682f8cfea669c3170814d875107cb3accb | 6 | SAFE |
0x75dd8773c3dbc4e3346838fffd526043e07f59bd | 6 | SAFE |
0x030c6c95835c5a28c6b90cd16889702619641a72 | 6 | Argent |
0x42fa35d75fac107734246e67b27b6f7c95dad350 | 5 | SAFE |
0xfa0f21b49ce8d93a5f2f0af290dc3900244e4b51 | 4 | Argent |
0x088227ee56b17e69c4e6865dc480d0a19d5156f4 | 4 | SAFE |
0xb25a1d02b029d53212e4c356b6daad419762e606 | 4 | SAFE |
0xd7c708080553068217a2fe6f44eccf9cac309915 | 3 | SAFE |
0x60aa607f0264cd85758828cc7c4d5647a3607a38 | 3 | SAFE |
0xfa4fdc9849de525e52783a7a6a11d2f5fe8a3060 | 3 | Argent |
0x3b2ea2f99277ba46c261a606e7811ee136a48af8 | 3 | SAFE |
0x7634e50225cfabcd9d760655483692c5dae81480 | 3 | SAFE |
0x5e4210e05368394e0820847c92b424bf37a0a5e8 | 3 | SAFE |
0xcb67d784bc35094ee7ded8b653803d88e3776bcd | 3 | SAFE |
0xc9d936154670cbb57be9c203286a5b8ce11bb39a | 3 | SAFE |
0x8ea84aa3a1ddcf2a9c2fb8cb730b64936d2bd627 | 2 | SAFE |
0xba84c55ecc8d5d2bcf851dea7f70958f83b811be | 2 | SAFE |
0xcdd598d1588503e1609ae1e50cdb74473ffb0090 | 2 | SAFE |
0xaab1779ab538d7c43094934c3e797e053660a981 | 2 | SAFE |
0xbf3f6477dbd514ef85b7d3ec6ac2205fd0962039 | 2 | MEV |
0x8991d9deb0cb6ad83acc5f2b733c297879b2424b | 2 | SAFE |
0x6d9c7858c11499e382991ad1447c5c122c3647aa | 2 | SAFE |
0x5e4b264f72aec9541e2e5b0a181656cb0ca64c0d | 2 | SAFE |
0x281f78188f494260edea1718bfb0eaceb0f7e79e | 2 | SAFE |
0x0d4b5370fa52f1d8f76db0f10ac0df183ce5ac0c | 2 | SAFE |
0x4a71e0267207cec67c78df8857d81c508d43b00d | 2 | Loopring |
## false positive cases for Criteria 1
Please refer to the query link: https://dune.com/queries/1725061
There are 5 addresses
* 0xb5d85cbf7cb3ee0d56b3bb207d5fc4b82f43f511
* 0x88193fc66f2cab15e03add807d11adc08b5352df
* 0x8ad92159a9faf66cd45076c12823f50ae59e60b2
* 0x84aeccde4c9f217e83d3fa28c31d34378b903f91
* 0xcd6dd8d6a5afb4aed5eead9db3551cba70fa7727
I check the eligible transactions for these addresses: https://dune.com/queries/1725179. Only one address has one eligible transaction.
By removing transaction selector filter in the above query, I find another 11 transactions: https://dune.com/queries/1725254
All these 5 addresses have more than 1 transactions. Therefore, these wallets are included in the current eligible list, most likely because the current query don't filter the function.
- 6 of these transactions are plain ETH transfer, i.e., sending ETH directly to genie contract.
- Indeed, 0xb5d85cbf7cb3ee0d56b3bb207d5fc4b82f43f511 is Coinbase's hot wallet, indicating that some users mistakenly withdrew ETH to genie contracts.
- 4 of these transactions are arbitrayCall() call to claim LOOKS trading rewards for the genie contract.
- 1 of these transactions is transferOwnership() call.
Since Genie is a NFT aggregator, I think it would be better to identify 'completing transaction on Genie' as 'completing NFT trades on Genie', rather than the above transactions.
# Criteria 2
## query methodology for Criteria 2a
Criteria 2a: wallets that held the Genie:Genesis NFT as of the snapshot.
I get all historical token transfer events, and then get the balance state at the snapshot. Please refer to the query link: https://dune.com/queries/1690925
## query methodology for Criteria 2b
Criteria 2b: wallets that purchased a Genie:Genesis NFT or a Genie:Gem NFT between 5:59 pm and 9:15 pm UTC on June 21st.
Firstly, I use [Dune's nft.trades table](https://github.com/duneanalytics/spellbook/blob/main/models/nft/nft_trades.sql) to query all purchasing transactions in the given time period: https://dune.com/queries/1690963. There are 44 transactions.
Then, I check all transactions that the corresponding NFTs are transferred during the given period, in case Dune's nft.trades table missed some purchasing transactions:
https://dune.com/queries/1690963.
Only 1 transaction(https://etherscan.io/tx/0x6a21734a36bc0d7b9a07edfe923e4934a782f3d5ea42c52e78799758b6e650f5) returned. This transaction is an EOA address transferring NFT directly to another EOA address, obviously not a purchasing transaction.
After that, I manually check all the 44 transactions. Since they are all simple single item trade through opensea/seaport contract directly without using aggregators, the buyer address in the table is the eligible address we want to get.
## query methodology for Criteria 2
Combine Criteria 2a and Criteria 2b, we can get the eligible wallet addresses for Criteria 2: https://dune.com/queries/1725433
## false negative cases for Criteria 2
There's one false negative address for Criteria 2: 0xbbc66295770da3d8349df8bb3ba760b9276a8950, query link:
https://dune.com/queries/1725576
This address is omited in the current eligible address because it held tokenid 3 of the Genie Genesis NFT. Seems that this maybe a test token for this collection. I don't filter this tokenid since I don't find information that this tokenid is not eligible for the airdrop, so I keep it in the query.
## false positive cases for Criteria 2
There's one false positive address for Criteria 2: 0x962a211f581bdd5bc3950d3048a45cc9e240f260, query link:
https://dune.com/queries/1725592
It is included in the current eligible address most likely because it is the receiver of the NFT transfer transaction mentioned above(https://etherscan.io/tx/0x6a21734a36bc0d7b9a07edfe923e4934a782f3d5ea42c52e78799758b6e650f5). Since it didn't purchase the NFT, it shall be excluded from the eligible address list.
Finally, I double check this address using etherscan: **This address didn't [hold or buy Genie Genesis NFT](https://etherscan.io/token/0xc466e2f98f95cc4cde31b134906f59e8264c1be0?a=0x962a211f581bdd5bc3950d3048a45cc9e240f260), nor did it [buy Genie GEM NFT](https://etherscan.io/token/0xbed57beec7191e59d18844124cbb0db660aef25f?a=0x962a211f581bdd5bc3950d3048a45cc9e240f260).** Therefore it didn't meet Criteria 2.
# Summary and Suggestion
In 2020, Uniswap's airdrop set an example for the industry: [query codes are open sourced and query methodology are explained in detail]((https://github.com/Uniswap/retroactive-query) ). Community can check whether the query code is correct before claiming starts.
As I understand it, the Merkle Root for the [current Merkle Claim contract](https://etherscan.io/address/0x8b799381ac40b838bba4131ffb26197c432afe78) cannot be changed. Meanwhile, the USDC deposited in the current Merkle Claim contract cannot be withdrawn until Nov.30th, 2023. Therefore, the false positive address cannot be canceled.
However, the false negative addresses can be resolved by creating a new claiming contract for these addresses.
Since the criterias are solely based on onchain actions, we suggest preserving the previous practice. In addition, it would be great to implement a bug bounty, similiar to security bug bounty but for data queries.
# Contact Author
- email: panda42jackson@gmail.com
- twitter: https://twitter.com/pandajackson42
- dune: https://dune.com/pandajackson42
*Disclaimer: Author isn't the owner of any wallets that are in the false negative addresses mentioned above.*