I'm looking into a bit of functionality for an ERC20 smart contract token that would prevent any one wallet to hold more than X percent of the token. Couple of questions:

  1. Is it possible?
  2. Is it technically advisable?
  3. Any gotchas or considerations?
  4. What would the API look like?

Adding sample contract in addition to Richard's answer.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract CappedHolding {
    uint256 public totalSupply;
    uint holdingCapPercent = 10;
    mapping(address => uint256) public balanceOf;
    function transfer(address _to, uint256 _amount) public {
        require(balanceOf(to)+_amount <= _getMaxHolding(), "Max holding cap breached.")
        // normal transfer logic goes here
    function _getMaxHolding() public view internal (uint256) {
        return  (totalSupply * holdingCapPercent) / 100;

Is it possible?


Is it technically advisable?

That's subjective. Depends what you're trying to achieve.

Any gotchas or considerations?

Creating an account is zero-cost. A user could create multiple accounts and bypass any restrictions by spreading the balance across multiple accounts.

What would the API look like?

(I don't think you mean "API" here.) You'd have to code the smart contract to check the account balance of the recipient during any transfers. If the transfer would result in the balance exceeding the desired limit, the transaction would revert.

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .