What is the recommended way of locking users from sending and receiving token?

I need to write a smart contract where owner able to lock user. So that locked user can not send/receive token. Here is my code snippet,

mapping (address => bool) private _lock;
modifier onlyOwner() {
    require (Owner == _msgSender(),"you don't have access to block");
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
    require(!_lock[sender],"ERC20: sender is blocked");
    require(!_lock[recipient],"ERC20: recipient is blocked");
    _transfer(sender, recipient, amount);
    _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
    return true;
function lock (address addr) public onlyOwner returns(bool) {
    _lock[addr] = true;
    return _lock[addr];

function Unlock (address addr) public onlyOwner returns(bool) {
    _lock[addr] = false;
    return _lock[addr];

Is it proper way?


How about transfer()?

Maybe you can write this check in _transfer() which in OpenZeppelin ERC20.sol

1 Like

Hi @selv,

If you are creating a BlockList or a DenyList for ERC20 transfers then you could use the _beforeTokenTransfer hook to validate that either the to or from (depending on your use case) are allowed. See: https://docs.openzeppelin.com/contracts/3.x/extending-contracts#using-hooks

You may also want to use AccessControl rather than Ownable: https://docs.openzeppelin.com/contracts/3.x/access-control#role-based-access-control