Skip to content

Commit

Permalink
(fix): airdrop formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mauromedda committed May 3, 2024
1 parent 33253e2 commit 5bcf795
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .trunk/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml
tmp
35 changes: 21 additions & 14 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
version: 0.1
cli:
version: 1.5.1
version: 1.22.0
plugins:
sources:
- id: trunk
ref: v0.0.11
ref: v1.2.1
uri: https://github.com/trunk-io/plugins

lint:
enabled:
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- eslint@8.35.0
- buildifier@6.0.1
- eslint@8.57.0
- buildifier@7.1.1
- git-diff-check
- markdownlint@0.33.0
- prettier@2.8.4
- shfmt@3.5.0
- svgo@3.0.2
- gitleaks@8.16.0
- flake8@6.0.0
- isort@5.12.0
- black@23.1.0
- rustfmt@1.61.0
- markdownlint@0.40.0
- prettier@3.2.5
- shfmt@3.6.0
- svgo@3.2.0
- gitleaks@8.18.2
- flake8@7.0.0
- isort@5.13.2
- black@24.4.2
- rustfmt@1.65.0
# - [email protected] - removed for being over-prissy and wanting tab indents - rrw 2023-04-25
ignore:
- linters: [gitleaks]
Expand All @@ -46,6 +52,7 @@ lint:
- products/bridge/bridge-web
- linters: [ALL]
paths:
- products/airdrop/**
- products/developer-portal/Dockerfile # Annoying, but trunk is now very opinionated on how you write dockerfiles.
- products/developer-portal/zq2/docs/js/** # trunk does not know this is looking for metamask in the user's browser.
- products/developer-portal/zq2/docs/index.md # contains legitimate empty links
Expand Down
42 changes: 23 additions & 19 deletions products/airdrop/README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
# Airdrop Utility

The ```Disperse``` contract and script in this repo provide a handy utility to automate batched transfers to a large number of accounts. It's useful for airdrops and other events where hundreds or tousands of accounts have to be sent an individual amount of a token. The contract supports the native token as well as ```ERC20``` tokens, but the script can currently handle only ```ERC20``` tokens.
The `Disperse` contract and script in this repo provide a handy utility to automate batched transfers to a large number of accounts. It's useful for airdrops and other events where hundreds or tousands of accounts have to be sent an individual amount of a token. The contract supports the native token as well as `ERC20` tokens, but the script can currently handle only `ERC20` tokens.

The contract in ```contracts/Disperse.sol``` is an updated version of the original contract implemented by the [Disperse Protocol](https://disperse.app/disperse.pdf) ported to Solidity 0.8.20. The original contract is deployed and actively used on the Ethereum mainnet: https://etherscan.io/address/0xD152f549545093347A162Dce210e7293f1452150.
The contract in `contracts/Disperse.sol` is an updated version of the original contract implemented by the [Disperse Protocol](https://disperse.app/disperse.pdf) ported to Solidity 0.8.20. The original contract is deployed and actively used on the Ethereum mainnet: https://etherscan.io/address/0xD152f549545093347A162Dce210e7293f1452150.

## Installation

Install [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started#installation) and configure your network(s) and account(s) in ```hardhat.config.js```.
Install [Hardhat](https://hardhat.org/hardhat-runner/docs/getting-started#installation) and configure your network(s) and account(s) in `hardhat.config.js`.

There are already existing deployments on the following networks:

| Network | ```Disperse``` contract address
| -- | --
| Zilliqa 1 mainnet | ```0x8Cc17F9eA46cD1A98EbB1Dd5495067e3095956aA```
| Zilliqa 1 testnet | ```0x38048F4B71a87a31d21C86FF373a91d1E401bea5```
| Network | `Disperse` contract address |
| ----------------- | -------------------------------------------- |
| Zilliqa 1 mainnet | `0x8Cc17F9eA46cD1A98EbB1Dd5495067e3095956aA` |
| Zilliqa 1 testnet | `0x38048F4B71a87a31d21C86FF373a91d1E401bea5` |

Deploy a new `Disperse` contract only if it does not yet exist on the respective network:

Deploy a new ```Disperse``` contract only if it does not yet exist on the respective network:
```
npx hardhat run scripts/deploy.js --network <one_of_the_networks_in_hardhat.config.js>
```

The script will output the address of the ```Disperse``` contract you can add to the table above and use in the ```disperse.js``` script below.
The script will output the address of the `Disperse` contract you can add to the table above and use in the `disperse.js` script below.

## Usage

Adjust the ```disperse.js``` script as follows:
* change the address in line 9 to the address at which the ```Disperse``` contract is deployed on the respective network,
* change the address in line 10 to the address at which your ```ERC20``` token is deployed on the respective network,
* change how many accounts to send tokens to per ```batch``` in line 11
Adjust the `disperse.js` script as follows:

- change the address in line 9 to the address at which the `Disperse` contract is deployed on the respective network,
- change the address in line 10 to the address at which your `ERC20` token is deployed on the respective network,
- change how many accounts to send tokens to per `batch` in line 11

Prepare the `input.csv` file. Each line consists of two values separated by a comma:

Prepare the ```input.csv``` file. Each line consists of two values separated by a comma:
* the value before the comma is a hex or bech32 formatted address
* the value after the comma is an integer amount
- the value before the comma is a hex or bech32 formatted address
- the value after the comma is an integer amount

Note that the script does not support decimal numbers as amount.
Note that the script does not support decimal numbers as amount.

Transfer the total amount of tokens to be distributed to the account that will be used to execute the script as configured in ```hardhat.config.js```.
Transfer the total amount of tokens to be distributed to the account that will be used to execute the script as configured in `hardhat.config.js`.

Run the script:

```
npx hardhat run scripts/disperse.js --network <one_of_the_networks_in_hardhat.config.js>
```
```
2 changes: 0 additions & 2 deletions products/airdrop/scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
const hre = require("hardhat");

async function main() {

const Disperse = await ethers.getContractFactory("Disperse");
const disperse = await Disperse.deploy();
await disperse.waitForDeployment();
console.log(disperse.target);

}

main()
Expand Down
35 changes: 23 additions & 12 deletions products/airdrop/scripts/disperse.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ const { validation } = require("@zilliqa-js/util");
const { open } = require("node:fs/promises");

async function main() {

const disperse = await ethers.getContractAt("Disperse", "0x38048F4B71a87a31d21C86FF373a91d1E401bea5");
const token = await ethers.getContractAt("ERC20", "0xf01f7FF8E38759707eE4167f0db48694677D15ad");
const disperse = await ethers.getContractAt(
"Disperse",
"0x38048F4B71a87a31d21C86FF373a91d1E401bea5",
);
const token = await ethers.getContractAt(
"ERC20",
"0xf01f7FF8E38759707eE4167f0db48694677D15ad",
);
const batch = 100;

const decimals = await token.decimals();
Expand All @@ -18,25 +23,31 @@ async function main() {
var total = BigInt(0);
const file = await open("./scripts/input.csv");
for await (const line of file.readLines()) {
const [address, amountStr] = line.split(",");
const recipient = address && validation.isBech32(address) ? fromBech32Address(address) : address;
recipients.push(recipient.toLowerCase());
const [address, amountStr] = line.split(",");
const recipient =
address && validation.isBech32(address)
? fromBech32Address(address)
: address;
recipients.push(recipient.toLowerCase());
const amount = BigInt(amountStr);
amounts.push(amount * multiplier);
amounts.push(amount * multiplier);
total += amount * multiplier;
//console.log(recipient, amount);
}

txn = await token.approve(disperse, total);
rcpt = await txn.wait();

for (start = 0; start < recipients.length; start += batch) {
end = start + batch < recipients.length ? start + batch : recipients.length;
txn = await disperse.disperseToken(token, recipients.slice(start, end), amounts.slice(start, end));
end = start + batch < recipients.length ? start + batch : recipients.length;
txn = await disperse.disperseToken(
token,
recipients.slice(start, end),
amounts.slice(start, end),
);
rcpt = await txn.wait();
console.log(txn.hash, start, end);
console.log(txn.hash, start, end);
}

}

main()
Expand Down

0 comments on commit 5bcf795

Please sign in to comment.