Utilities enabling the mass distribution of assets, with a single funding transaction.
A funder, such as a yield farming distribution, wishes to distribute 1,000,000 XYZ tokens to 50,000 addresses.
Off-chain, the funder builds a merkle tree of (address,amount) pairs for XYZ payouts.
The funder sends 1,000,000 XYZ tokens, and the Merkle root hash, to this MerkleBox contract for secure storage.
Then, at any time, users may claim their XYZ tokens by providing a Merkle proof of their (address,amount).
The end result is aggregating all the payouts into a single blockchain transaction from the funder. (Users must still individually issue claim transactions)
Validate a supplied merkle receipt is associated with a valid, unspent claim.
Present a valid merkle receipt with account associated with it and transfer the associated tokens to given account.
Provided account address must be the address in the claim, and the claim must be unspent.
Store a merkle root, and associated ERC20 funds, on chain. Must provide withdraw unlock time and its value must be atleast 30 days higher than claim group create time.
Can also provide a memo string for adding arbitrary notes to the group.
WARNING: There is no on-chain validation that funds supplied equal the funds required to fully satisfy all claims. The funder may under-fund.
Funder can not claim tokens via
claim()
Supply additional quantity of asset to the claims group.
Usually the funder calls this operation, but that is not a requirement. Once a claims group is created, anyone may supply additional funds.
The funder (owner) may withdraw funds from the claims group, if-and-only-if the Withdraw Unlock time is reached.
A separate MultiTransfer contract is provided, which provides the simple utility of
- Receive N amount of an ERC20 token
- Send tokens to a list of (address,amount) pairs.
This contract and function is not tied in any way to the above merkle-related operations, and is provided as an alternate mass-pay operation for ERC20 tokens.
It appears prohibitively expensive to validate that a holding is fully funded. (Solutions welcome)
As a consequence, it is possible to under-fund a claims group.
The withdraw lock feature permits disabling of withdrawals until a specified time.
There will be atleast 30 days withdraw locking. To permanently lock the funds, set the lock time to a maximum, or an arbitrary time millions of years in the future.
Install packages
$ npm i
$ npm run compile
$ npm run test
$ npm run coverage
Setup the env vars properly (See .env.template
file) and run:
# deploy
$ npm run deploy -- --gasprice <gas price in wei> --network <network>
# create release
$ npx hardhat create-release --release <semver> --network <network>