Updating _balances[account] for inherited contracts

As far as I know, it is not possible to access private variables from parents’ contract on inherited contracts, this adds some architectural issues to ERC20.sol.

Indeed, I need to perform some specific operations before a _transfer, I thought about using the _beforeTokenTransfer hook but the issue is that this hook is used in the _mint and _burn function also.

This is what I need to do:

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal override notNull(amount) {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        if (!_isExcludedFromPayingFees[sender]) {
            _beforeTokenTransfer1(sender, amount);

        uint256 senderBalance = _balances[sender];
            senderBalance >= amount,
            "ERC20: transfer amount exceeds balance"
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
function _beforeTokenTransfer1(address sender, uint256 amount) internal {
        if (_burnTax != 0) {
            uint256 burnFee = (amount * _burnTax) / (10**2);
            _balances[sender] -= burnFee;
            _balances[address(this)] += burnFee;
            _approve(address(this), sender, burnFee);
            burnFrom(address(this), burnFee);

That’s basically a simple burn tax, so could it be possible either to have specific hooks per functions, e.g., beforeTokenTransfer, beforeMint, beforeBurn and/or alternatively expose getters/setters for the _balances?

Looking forward to your answer,

1 Like

Is your overall goal to burn other tokens for other smart contracts?

If this is your goal, why not call their specific functionality for burning their own tokens?

Have on Contract Address be the Operator, the Operator calls their specific Burn Functions and the amount they should burn for their own Tokens.

No that is not it, my goal is to be able to manipulate _balances[account] this could be to for example burn tokens on behalf of my contract and then update the relevant balances, or to use x% of token to swap for ETH or add to liq… Being able to manipulate balance is very important and gives more flexibility to create more complexe contracts.

Yeah, you are right, it is not possible to access private variables from parents’ contract on inherited contracts, but you can use the internal function _mint() and _burn() to increase or decrease the balance.

Maybe you can rewrite the transfer()/transferFrom() rather than _transfer(), such as:

function transfer(address recipient, uint256 amount) public override returns (bool) {
    DO_YOUR_OWN_LOGIC;              // <<<--- here!
    _transfer(_msgSender(), recipient, amount);
    return true;

Good question, maybe you can open an issue on the repo of the OpenZeppelin to let more people know and have a discuss,

Emmm, I think they do not want developers to change underlying logic arbitrarily, so they make _balances as the private variable.

Maybe you can rewrite the code to achieve what you want to do.

1 Like

But, what i see don’t exit another option, to modify the library, right??, for manipulate the mapping of _balances, my approach is for a method for bulk of transfer (like airdrops, vesting or staking rewards), where you need to execute a lot transaction for transfer the token to the stakeholders

Hi, welcome! :wave:

I think you choose to use the library file of the OpenZeppelin, you are not recommended to modify it, if you want to modify the library file, maybe you can modify the whole file to meet all your requirements.

I posted on GitHub and I think that exposing an increase/decrease balance functions would be a super idea give more flexibility and use cases to openzepplin based contracts!

1 Like

I agree with you @aress31