Privacy-Preserving Smart Contract Rate Limiting

Ryan Sproule
co-authored with ·
No items found.


As the complexity of online autonomous agents advances, it will become progressively more difficult to restrict their access to resources. It will be essential to establish a privacy-conscious method for finely tuning the interaction rates between entities and smart contracts. This approach is crucial to prevent a limited group of advanced actors from exploiting the systems.

Rate Limiting?

Rate limiting is a crucial technique employed to control the frequency of user requests to a resource over a specified period. This technique is indispensable in most web-based systems as a safeguard against Denial of Service (DoS) attacks, where a single entity could monopolize all server resources. The cornerstone of any rate limiting system is the ability to generate a rate limit “key” – a unique identifier for the entity making the requests. In the context of Web 2.0 systems, this could be a user’s IP address or an account ID that is unique per email, phone number etc. However, these strategies are not impervious to a “Sybil” attack, where a single entity manipulates multiple rate limit keys (such as IPs or accounts), making it challenging for the web service to discern that the requests originate from the same entity.

Similarly, Ethereum and other censorship-resistant, public smart contract platforms face a comparable issue. Consider a smart contract, like a Non-Fungible Token (NFT), which might need a mechanism to prevent a single user from minting all the NFTs. Currently, this is a complex problem because there’s no reliable method to determine if transactions from multiple accounts are indeed from separate entities. In other words, there’s no clear correlation between an account (public key) and an individual human user.

Introducing a privacy-preserving flexible rate limiting library: n-per-epoch

Check out the open source implementation of this simple contract modifier here. This modifier enables contract creators to set limits on the number of times a specific user can call a function within a defined epoch. The epoch duration is highly flexible, allowing developers to set it to near infinity (1 per forever) or to a very short duration for higher throughput.


It is critical that the key we use for rate limiting on chain is privacy-preserving by default. The status quo on blockchain is that a user’s history across applications is completely transparent.

You will notice that these contracts do not care at all about msg.sender. This is by design! Under the hood, this takes advantage of zero-knowledge proof of inclusion through the usage of the semaphore library. The contract enforces auth via the provided zk proof instead of relying on the signer of the transaction. ERC4337 style account abstraction could trivially leverage this type of authentication to completely anonymize on-chain actions.


Theoretically, any semaphore group could be used as the anonymity set behind this rate limiting. This example uses a group that is already quite large and has some unique properties, such as a guarantee that each entry in the set is a human.

This example leverages an existing “anonymity set” developed by Worldcoin, comprising approximately 1.8 million verified human users. Worldcoin established this set by scanning individuals’ irises and ensuring that each iris had not been previously added to the set. To utilize a different set, simply modify the groupId within the settings. Learn more about the World ID and the Worldcoin project here.

Why is rate limiting useful?

  1. Prevent abuse: By limiting the number of requests per user, it helps to prevent abuse of services or resources by malicious actors or bots. This ensures that genuine users have fair access to the system without being crowded out by automated scripts or attacks.
  2. Encourage fair distribution: In scenarios where resources, rewards, or opportunities are limited, rate limiting human users ensures a more equitable distribution. This can help prevent a few users from monopolizing access to valuable assets or services, such as NFT drops or token faucets.
  3. Enhance user experience: When resources are constrained, rate limiting human users can help maintain a smooth and responsive experience for legitimate users. By preventing system overload or resource depletion, it ensures that users can continue to interact with the application without disruption.
  4. Manage costs: In blockchain applications, rate limiting human users can help manage costs associated with gas fees or other operational expenses. By controlling the frequency of transactions or function calls, service providers can optimize their expenses while still offering a valuable service to users.
  5. Preserve privacy: By focusing on human users and leveraging privacy-preserving techniques, rate limiting can be implemented without compromising user privacy. This is particularly important in decentralized systems, where trust in the system is often built on the foundation of user privacy and data security.

Example use-cases

Gas-sponsoring relays: These relays aim to provide gas for human users of their applications while preventing resource depletion by a single user. This library effectively enables protocols to manage resource allocation for individual users.

Faucets: Distribute assets to human users at a controlled pace, preventing abuse.

Rewarding user interactions on social networks: Rate limiting helps limit the impact of spamming while still encouraging genuine engagement.

Fair allocation of scarce resources (e.g., NFT drops): By implementing rate limiting, each human user could be allowed to mint a specific amount (e.g., one per hour), promoting equitable distribution.


As the sophistication of autonomous agents online increases, limiting access to resources will become increasingly challenging. A privacy-preserving way to have fine-grain control over the rates at which entities can interact with smart contracts will be critical if we are to prevent a small set of sophisticated actors from abusing the systems.

Disclosures: Blockchain Capital is an investor in several of the protocols mentioned above. The views expressed in each blog post may be the personal views of each author and do not necessarily reflect the views of Blockchain Capital and its affiliates. Neither Blockchain Capital nor the author guarantees the accuracy, adequacy or completeness of information provided in each blog post. No representation or warranty, express or implied, is made or given by or on behalf of Blockchain Capital, the author or any other person as to the accuracy and completeness or fairness of the information contained in any blog post and no responsibility or liability is accepted for any such information. Nothing contained in each blog post constitutes investment, regulatory, legal, compliance or tax or other advice nor is it to be relied on in making an investment decision. Blog posts should not be viewed as current or past recommendations or solicitations of an offer to buy or sell any securities or to adopt any investment strategy. The blog posts may contain projections or other forward-looking statements, which are based on beliefs, assumptions and expectations that may change as a result of many possible events or factors. If a change occurs, actual results may vary materially from those expressed in the forward-looking statements. All forward-looking statements speak only as of the date such statements are made, and neither Blockchain Capital nor each author assumes any duty to update such statements except as required by law. To the extent that any documents, presentations or other materials produced, published or otherwise distributed by Blockchain Capital are referenced in any blog post, such materials should be read with careful attention to any disclaimers provided therein.

more by
Ryan Sproule
more on
Thank you! Your submission has been received!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.