Fund pool is a zkApp that accepts deposits of a custom token, but only if you can prove you're a part of a whitelist. Deposits are tracked in an off-chain merkle tree, for each user/address respectively. Whitelist membership is proven via a recursive proof, and the proof is validated through it's public input via a smart contract on-chain state precondition (whitelist tree root hash matches on-chain commitment).
FundPool: B62qijxqZ9mcYF7djeyJ4Uvku8y1MxrS1c7zGfhKLaZfTdd82XKzWAP
zkApp | Compile | Without proofs | With proofs | Berkeley |
---|---|---|---|---|
Token | 18s | - | - | - |
FundPool | 3min | 70s | 7min | - |
WhitelistProgram | 27s | - | 60s | - |
Combined | 3-4min | - | 8min | 25min |
For the purpose of the zkApps e2e testing program, this project comes with a pre-funded account in keys/berkeley.json
. However, if you wish to generate a new account and request funds from a faucet, please run:
npm run init:account
The script creates a Mina account and requests a small amount of Mina from the faucet on Berkeley, and then writes the private and public key to keys/berkeley.json
.
npm run build
npm run test
npm run testw # watch mode
npm run test:berkeley
# or edit .env file and set TEST_ON_BERKELEY=true
npm run test # with edited .env
- Recursion
The FundPool contract only allows deposits as long as a valid proof of being whitelisted is submitted.
- Call stack composability
The FundPool contract transfers tokens through Token.transfer()
, from the user to the FundPool's token holder account.
- Actions
Every deposit it accompanied with a DepositAction
, which is subsequently processed during FundPool.rollup()
- Events
Rolled up deposit actions update a tree of deposits, and emit each write to the deposits tree through events, with the help of the ZKFS offchain storage library.
- Preconditions (account)
FundPool stores a whitelistRoot
as on-chain state, when the FundPool.deposit()
is proven locally, a precondition for the whitelistRoot
to match the on-chain state is applied.
Additionally, provedState
is used to prevent changing of
- Preconditions (network)
The FundPool allows deposits only during a specific time window, which is enforced based on a blockheight / chainlength range (from - to blockchainLength). A precondition is used as network.blockchainLength.assertBetween
.
- Permissions
FundPool's state is only editable with proofs, a signature authorization is not enough. This is tested by manually injecting an account update signed by the zkApp, but not generated by a provable method.
- Deploy Smart Contract
The FundPool smart contract is deployed either on LocalBlockchain or the Berkeley testnet respectively.
- Tokens
The FundPool smart contract accepts deposits of a custom token, not MINA. The token contract comes from an external repository stove-labs/mip-token-standard
.