Coder Social home page Coder Social logo

worldcoin / world-id-contracts Goto Github PK

View Code? Open in Web Editor NEW
106.0 11.0 30.0 4.09 MB

Internal use. Smart contracts powering the World ID protocol and the Worldcoin app airdrops.

License: MIT License

Makefile 0.31% Solidity 99.69%
managed-by-terraform

world-id-contracts's People

Contributors

0xkitsune avatar cichaczem avatar corydickson avatar dcbuild3r avatar dependabot[bot] avatar dzejkop avatar eltociear avatar gswirski avatar iamrecursion avatar kustosz avatar m1guelpf avatar mmqxyz avatar paolodamico avatar philsippl avatar recmo avatar sabnock01 avatar snyk-bot avatar snyk-bot-wld avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

world-id-contracts's Issues

Warn and fail deploy if deployed contracts exceed set thresholds

The current implementation of the bytecode size check gives different results to forge build --sizes. Let's work towards having it consistent with the forge implementation.

Acceptance criteria

  • When any of the deployed contracts/libraries bytecode exceeds the warning threshold of 18000 bytes, a user should see a warning informing about the bytecode size
  • When any of the deployed contracts/libraries bytecode exceeds the maximum allowed size of 24576 bytes, a user should see a failure

Generate production verifiers after trusted setup is done

Current Status:

Tests use only the correct verifier for batch Semaphore tree insertion/deletion proofs InsertionTreeVerifier16.sol / DeletionTreeVerifier16.sol (tree depth 16). There is also a test SemaphoreVerifier16.sol that verifies Semaphore tree inclusion proofs using PSE's Semaphore trusted setup files (depth 16). The insertion and deletion provers albeit real, are generated using a mock proving system file (no trusted setup performed for the creation of vk and pk).

Missing items

  • Perform trusted setup for insertion and deletion circuits of tree depth 30 and specified batch sizes
  • export the verification key from the resulting proving system files using gnark-contract-extractor and generate the corresponding verifiers to be inserted into their respective verifier lookup tables on deployment
  • Test correct working of said verifiers on staging (Goerli deployment)

Add fuzzing to the contract's tests

In order to get things out the door quickly as a proof-of-concept, the tests for the new version of the WorldID contract are not fuzzed as this would require additional setup and ensuring that valid inputs don't become part of the fuzzed inputs.

For more reliability we do want to fuzz them.

  • Introduce fuzzing for all tests where it is relevant.
  • Add a simple verifier using the parametrisation from #27. This should allow for fuzzing of correct and incorrect proofs.
  • Ensure that all tests still pass.
  • Fix any bugs that arise.

Add setters for dependent contracts

The WorldID identity manager depends on a set of contracts to execute its functionality. These should be alterable without requiring a contract upgrade.

To that end, we want to add setters for the addresses of these contracts.

Remove constants and groupId parameter

The next constants are not used anymore and they can be removed:

/// Unused code:
uint256 internal constant DEFAULT_ROUTING_TABLE_SIZE = 10;

/// How much the routing table grows when it runs out of space.
uint256 internal constant DEFAULT_ROUTING_TABLE_GROWTH = 5;

Consider removing the groupId parameter from the addGroup(...) function, which is not used:

function addGroup(uint256 groupId, IWorldID groupIdentityManager)
    public
    virtual
    onlyProxy
    onlyInitialized
    onlyOwner
{
    // Duplicate groups cannot be added.
    if (groupId < groupCount()) {
        revert DuplicateGroup(groupId);
    }

    // Groups should be added sequentially.
    if (groupId != nextGroupId()) {
        revert NonSequentialGroup(groupId);
    }

    // Insert the entry into the routing table.
    insertNewTableEntry(groupIdentityManager);
}

Remove return variables

Local variables in return statements are still present and need to be removed:

  • WorldIDRouterImplV1
    • function routeFor(...)
  • WorldIDIdentityManagerImplV1
    • function queryRoot(...)
    • function latestRoot()
    • function isInputInReducedForm(...)
    • function reduceInputElementInSnarkScalarField(...)
    • function getRegisterIdentitiesVerifierLookupTableAddress()
    • function getIdentityUpdateVerifierLookupTableAddress()
    • function getSemaphoreVerifierAddress()
    • function getRootHistoryExpiry()
    • function getTreeDepth()

Add support for contract upgrades to the deploy scripts

While #34 adds support for deploying the upgradable contract architecture from scratch, we should also script the upgrade process. This will both act as documentation for what is required, and also make it easier to deploy upgrades on disposable testnets for testing purposes.

add(support for multiple chains)

Propagate the latest root hashes and timestamps to many different rollups, validiums, and other scaling solutions.

Requirements

TODO

  • Add methods on proxy contract to abstract L1<>L2 communication with all supported chains
  • Build a public entry method from world-id-contracts that will call the methods for the other chains, passing the latest state root hashes and timestamps from the external service
  • Add monitoring to make sure data hits all the target contracts on L2s
  • Bonus: Make the service call a chain-specific contract method if L1<>L2 comms fail

Gas benchmarking for `rootHistory`

Currently the root history is stored as a mapping. Mappings have no way to know if a given key has been set to, which means that while we can check a root for expiring, we have no sensible way to remove it from the mapping.

As a result, the storage costs of that mapping will grow over time.

We should do some benchmarking and determine if we can find a more-sensible way to store the history while also minimising gas costs.

Stop emitting MemberAdded events

In order to save gas, after the contract is rewritten to ZK semaphore inserts, it should no longer emit the MemberAdded events. The clients should instead parse calldata to get the identity commitments of inserted members.

Support different batch sizes

The contract should hold on to a (possibly dynamically settable) set of verifiers for batch inserts of different sizes. This will allow the sequencer to adapt to different load levels without wasting compute on almost-empty batches.

The basic outline of how this should happen is as follows:

  • Add a set of dispatch tables. These should take the batch size and convert it to the correct verifier to use for each endpoint (identity registration, removal, and update).
  • Use this dispatch table in the identity registration, removal, and update endpoints.
  • Update the getters and setters to allow for getting and setting verifiers on a per-size basis, rather than just globally.
  • Update initialize to take an array of (uint256 size, ITreeVerifier verifier) pairs for each dispatch table.
  • Add tests to ensure that the correct verifier gets dispatched to. This can be done by adding a basic event and having the test verifiers emit different values to the log depending on the batch size.
  • Update the deploy script so that it can be used with the new architecture.
  • Update Signup Sequencer so the contract interface it stores is up to date with the changes.
  • Account for the potentially-variable batch sizes in the DRP.

Provide stub API for member removals / updates

Figure out the signatures and provide stub implementations for member removal / update operations. They should delegate to some (as yet uninitialized but settable in the future) verifier contracts, that will be able to actually verify modification correctness. This will save us some upgrade pain in the future.

Omni-chain WorldID: Support on different L1s and L2s

Description

WorldID will support Ethereum mainnet, Optimism, and Polygon PoS really soon. However, the landscape of different L2s on Ethereum is greatly expanding and other L1s should also have access to the Ethereum state for integrating WorldID in order to make our protocol credibly neutral and accessible to as many developers as possible (chain-agnostic).

Requirements for bridging to work

  • Proving the state inside of world-id-contracts which are deployed on Ethereum mainnet on different networks
  • Correct implementation of the Semaphore verifier, or any other future iteration of the verifier for WorldID proofs. The implementation will be different for different execution environments (EVM - Ethereum, Scroll, zkSync, Polygon ZKEVM, Optimism, Arbitrum, ...; Cairo - Starknet, Sway - Fuel; Sealevel - Solana; Noir - Aztec; Substrate - Polkadot; CosmWasm - CosmosSDK/IBC; RiscV - RiscZero; Leo - Aleo; SnarkyJS - Mina and more to come in the future). The development of these implementations can be supported by the Worldcoin Foundation in the form of grants in the future.
  • Relaying the proofs from Ethereum to other networks
    • EOAs sending data through calldata to the target network. EOA is controlled by an external relayer service that pushes proofs to the target network WorldID contract.
    • Oracles/Re: e.g. Chainlink, Empiric/Astraly
    • Other: Succinct, Herodotus, Axiom

Solutions

Interesting candidates for proving and verifying L1 state on different networks to be able to do omni-chain WorldID integrations:

Add `deleteIdentities` function

WorldIdIdentityManager should support deleting identities.

This change includes:

  1. Adding a lookup table for deletion batches & deletion verifiers
  2. Adding a method to delete identities

This will be a versioned change to the id manager.

Preliminary upgradeability process

Design and implement a simple upgradeability process for these contracts. An admin-only proxy with no additional safeguards should do for now.

Identity Manager Router

While we are currently unsure if we want to support groups, future-proofing the protocol is important. While signup sequencer and the on-chain identity manager can be paired, external clients will not want to hard-code a bunch of addresses for the various group setups. Instead, we should provide a router component that provides the client with the address to call based on the group number.

The component should be implemented as an upgradeable proxy, much like the identity manager itself. It should support:

  • Storing the group id (uint256) to address mapping in compact storage. It should not use a mapping, but instead use a uint256[] that grows as needed.
  • It should provide a view query that returns the address that corresponds to the provided group.
  • It should provide an owner-only function that adds an address for the provided group id. This should expand the underlying array as needed.
  • It should provide an owner-only function that replaces an address for the provided group only if the group already exists.
  • All of the necessary security and access restrictions should be provided, as they are for the identity manager.
  • Tests, of course.
  • Add support for deploying the router to the deploy script (a --with-router) option that will set up the router with the contract that gets deployed (can ask for existing router and group or set up a new one depending on whether an address is provided).
  • Ensure that the existence of the router is accounted for in the disaster recovery plan.

From discussion with Philipp, we can assume that the group identifiers are sequential small integers, and can check for this when adding groups.

Write a migration plan for the WorldID Identity Manager

No matter how comprehensive the upgradability mechanism is, we need some means to migrate after irrecoverable circumstances. We need to write a migration plan, accounting for at least the following:

  • Restoring the current root.
  • Restoring the root history.
  • Ensuring minimal downtime during a migration.

WLD Token Contract

Worldcoin contracts will be released on Polygon and other chains. We should enable token users to transfer their tokens between chains.

Create an upgradable ERC20 contract

Deploy Goerly-based staging

TODO

  • Deploy Contracts to Goerli
  • Get credentials to OZ account working with Goerli
  • Deploy Prover
  • Deploy Sequencer

Validate public inputs to the prover for being members of the field `Fr`

Currently we do no validation as to whether the public inputs to registerIdentities are in reduced form as members of the field. We should do this, allowing us to fail quickly if things aren't right.

  • Work out if we want to include the proof terms in this (they are currently checked in verifyProof, but this is later in the process). We would double-count some gas (not a lot) to check them early; we save in the failure case, which doesn't seem worth it to me.
  • Add verification checks for whether preRoot, startIndex, identityCommitments and postRoot are all in reduced form.
  • If they are not, fail with a descriptive error.
  • Add tests for this.

Note that here our r is SNARK_SCALAR_FIELD.

add(optimism-state-bridge push-based mechanism)

The current optimism-state-bridge design has a push-based mechanism that would send the latest state root along with its timestamp each time it is reconstructed due to a new batch insertion. This info would be sent to a relay contract which would call a method that triggers the L1<>L2 messenger to send that state root along with its timestamp to Optimism to use for World ID verification on the L2.

TODO:

  • figure out what branch to rebase the PR for this issue on
  • modify the world-id-contracts to send the latest state root and its timestamp to a specified contract which would forward that info to L2 (this is a forward-thinking design that would allow for a pull-based approach down the line)
  • integration test by deploying setup on Ethereum and Optimism Goerli testnets
  • testing with verifyProof() in world-id-contracts@op-bridge/src/Semaphore.sol @kustosz

StateBridge is no longer a proxy

We are changing the design of the State Bridge a little bit, the initial design will be final in terms of the actual bridge. Since after that we will migrate to a storage-proof or light-client approach.

We have to:

  • change everything from proxy to regular contract call on world-id-contracts
  • modify tests to reflect this

Discuss introducing events

Several relevant operations in the contracts do not emit events, making it difficult to monitor and review the contracts' behavior once deployed.

Operations that would benefit from emitting events include:

  • WorldIDIdentityManagerImplV1.initialize(...)
  • WorldIDIdentityManagerImplV1.registerIdentities(...)
  • WorldIDIdentityManagerImplV1.updateIdentities(...)
  • WorldIDIdentityManagerImplV1.setStateBridge(...)
  • WorldIDIdentityManagerImplV1.setSemaphoreVerifier(...)
  • WorldIDIdentityManagerImplV1.setRootHistoryExpiry(...)
  • WorldIDRouterImplV1.initialize(...)
  • WorldIDRouterImplV1.addGroup(...)
  • WorldIDRouterImplV1.updateGroup(...)
  • WorldIDBridge._setRootHistoryExpiry(...)
  • WorldIDAirdrop.claim(...)

Emitting events for the relevant operations will enable users and blockchain monitoring systems to easily detect suspicious behaviors and ensure the correct functioning of the contracts.

However, we also originally removed events from this contract (and others) in order to save on logging gas. We need to discuss what the correct course of action is here.

Add events

Several event emissions have been added to the specified functions. However, there remain some pertinent functions that do not emit events:

  • WorldIDIdentityManagerImplV1.initialize(...)
  • WorldIDRouterImplV1.initialize(...)

Deploy WorldID Identity Manager in Production

Deploy the new (batching-based) WorldID Identity Manager contract to Eth mainnet, together with the upgradeability story.

Note: The basic steps of deployment can be found in deploy.js but will need to be adapted for secure deployment to production.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.