# Autonomous Airdrop

## Introduction

This Autonomous Airdrop example checks if a user has used Uniswap on Goerli (swapping a token for a token that is **not** ETH) on or after block 9000000, and if so, sends 100 UselessToken to the user. UselessToken is a test token and has no monetary value.

{% hint style="info" %}
**WARNING:** This code is not audited and is only provided as an example.
{% endhint %}

## Example Deployment

<https://autonomous-airdrop-example.vercel.app/>

## Github Repo

<https://github.com/axiom-crypto/autonomous-airdrop-example>

## System Diagram

<figure><img src="/files/hTIFS1QRITa4SqwHidML" alt=""><figcaption><p>Flow diagram for the full Autonomous Airdrop system</p></figcaption></figure>

## Methodology

For the airdrop parameters that we've specified, we'd like to figure out exactly how we can get this data from the blockchain. First, we'll dive a little deeper into how event logs work.

When a Solidity contract `emit`s an event, that event is saved in the transaction receipt's `logs` array. This array contains every event that was emitted during that transaction. Each `log` records up to 3 `topic`s and some amount of data. `topic`s are marked as `indexed` in the event and are easily searchable, whereas data is any field without `indexed` and is not as easily searchable. Here's an example `Swap` event at [this transaction](https://goerli.etherscan.io/tx/0x48ec8cb5f934664d26c0cf435e2f7c924ef757ab4c84b20e7320e21f468551b7#eventlog) here that we're interested in for our airdrop parameters.

<figure><img src="/files/3leLeMyRF5G4i4KHQrPE" alt=""><figcaption><p><code>Swap</code> event</p></figcaption></figure>

We're looking at one example transaction right now, but the guidelines we'll build will be universal for all transactions. In order to show that a user has performed a Swap on the `UniswapUniversalRouter` on or after block 9000000, we want to use the following four pieces of data:

* The `event schema` for the event (see note below for details), which always lives on topic index 0 of the event, matches the `Swap` event above&#x20;
* The `recipient` field of the `Swap` event matches the user's address
* The `receipt`'s `blockNumber` is >= 9000000
* The `transaction`'s `to` field matches `UniswapUniversalRouter`'s contract address

{% hint style="info" %}
Note: you can use [this online keccak256 tool](https://emn178.github.io/online-tools/keccak_256.html) to validate that the Swap event schema `0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67` is indeed equal to the keccak256 hash (with `0x` prepended) of the function signature:

```
Swap(address,address,int256,int256,uint160,uint128,int24)
```

{% endhint %}

## Finding appropriate transactions

We utilize [Alchemy's Transaction JSON-RPC](https://docs.alchemy.com/reference/alchemy-getassettransfers) to grab all transactions from the user that fit the criteria that it was sent from the user's address to the UniswapUniversalRouter's address. For each transaction, we get the receipt as well and then we parse through that data according to the 4 parameters outlined above to find an appropriate Event that matches.

## Components

This example contains 3 parts: the AxiomREPL code, contracts, scripts, and webapp. **AxiomREPL Code** is the code that's written in using AxiomREPL to generate a ZK circuit in browser that can be used in your web app. **Contracts** contains all of the Solidity contract code to implement preprocessing the transaction data. **Web App** contains the code for a Next.js 13 (app router) web app.&#x20;

{% content-ref url="/pages/SDzekrF6gBqfUWSKyHiX" %}
[AxiomREPL Code](/axiomv2-sdk/examples/autonomous-airdrop/axiomrepl-code.md)
{% endcontent-ref %}

{% content-ref url="/pages/FaZ2PNL4a9qlwRPtJKDZ" %}
[Contract](/axiomv2-sdk/examples/autonomous-airdrop/contract.md)
{% endcontent-ref %}

{% content-ref url="/pages/TqvelN5j6fksaQI6zW5Z" %}
[Web App](/axiomv2-sdk/examples/autonomous-airdrop/web-app.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://intrinsic-1.gitbook.io/axiomv2-sdk/examples/autonomous-airdrop.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
