worldcoin / world-id-contracts Goto Github PK
View Code? Open in Web Editor NEWInternal use. Smart contracts powering the World ID protocol and the Worldcoin app airdrops.
License: MIT License
Internal use. Smart contracts powering the World ID protocol and the Worldcoin app airdrops.
License: MIT License
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
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).
We can call the verifyProof
function via IWorldID
rather than a low level call.
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.
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.
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);
}
Research the various options for upgradability processes on chain for WorldID.
Relating to this PR on world-id-state-bridge
.
Local variables in return statements are still present and need to be removed:
WorldIDRouterImplV1
function routeFor(...)
WorldIDIdentityManagerImplV1
queryRoot(...)
latestRoot()
isInputInReducedForm(...)
reduceInputElementInSnarkScalarField(...)
getRegisterIdentitiesVerifierLookupTableAddress()
getIdentityUpdateVerifierLookupTableAddress()
getSemaphoreVerifierAddress()
getRootHistoryExpiry()
getTreeDepth()
As it says on the tin. These should be virtual.
Fixed by #134
Would make DX on worldcoin/world-id-starter-hardhat much simpler.
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.
Propagate the latest root hashes and timestamps to many different rollups, validiums, and other scaling solutions.
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.
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.
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:
initialize
to take an array of (uint256 size, ITreeVerifier verifier)
pairs for each dispatch table.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.
Provide the contract with the missing bits of member updates API and make sure it works well.
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).
world-id-contracts
which are deployed on Ethereum mainnet on different networksInteresting candidates for proving and verifying L1 state on different networks to be able to do omni-chain WorldID integrations:
WorldIdIdentityManager should support deleting identities.
This change includes:
This will be a versioned change to the id manager.
Design and implement a simple upgradeability process for these contracts. An admin-only proxy with no additional safeguards should do for now.
README.MD contains this text and a link: The protocol uses Zero-knowledge proofs so no traceable information is ever public. The link: https://id.worldcoin.org/zkp is broken - there is no such page and no such website
Rewrite the insertMember
method to use the library generated in this issue to avoid storing the entire tree in storage and enable batch inserts.
What it says on the tin.
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:
uint256
) to address
mapping in compact storage. It should not use a mapping, but instead use a uint256[]
that grows as needed.view
query that returns the address that corresponds to the provided group.--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).From discussion with Philipp, we can assume that the group identifiers are sequential small integers, and can check for this when adding groups.
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:
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
TODO
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.
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.preRoot
, startIndex
, identityCommitments
and postRoot
are all in reduced form.Note that here our r
is SNARK_SCALAR_FIELD
.
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.
verifyProof()
in world-id-contracts@op-bridge/src/Semaphore.sol
@kustoszWe 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:
world-id-contracts
This will make it easier to call for debugging and on-chain verifications.
Change requireValidRoot(...)
to virtual
in the WorldIDIdentityManagerImplV1
contract.
Currently the contract's rootHistory
stores the time at which the root became active. We instead want to store the time the root became superseded by a new one.
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.
The semaphore verification endpoint in signup sequencer is moving to semaphore V3.0.0. The WorldID Identity Manager should do the same for its embedded verifier.
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(...)
While #33 adds a new architecture for the WorldID identity management system to enable upgrades, the deploy scripts do not yet have support for deploying this new architecture.
Currently, we have a const with a gas price in the deployment script. It's necessary to deploy contracts to the Polygon mainnet.
We're most likely overpaying for these transactions. We can programmatically check and set the current gas price on each transaction.
Related resources
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.