I have a basic knowledge of solidity. I am trying to create an upgradable ERC20 Token. For that, I create TokenStorage contract and Logic contract and trying to write the Proxy contract.

In the Logic contract:

pragma solidity ^0.4.24;
import "./TokenStorage.sol";
import "./SafeMath.sol";
import './Ownable.sol';

In the TokenStorage contract:

function addTotalSupply(uint256 _value) public onlyOwner {
    totalSupply = totalSupply.add(_value);

When I call balances.addTotalSupply(_amount) from Logic.mint(), I get error.

If I remove onlyOwner in addTotalSupply, it executes correctly.

Note All contracts are deployed using the same account.

Please help me to understand why this happens.

Please Share me a proper guide to creating an upgradeable ERC20 Token is much appreciable

Thank you. Sorry for my bad English

  • 1
    You should either inherit Logic from TokenStorage, or implement a new modifier called onlyLogic and use it instead of onlyOwner. Commented Aug 19, 2019 at 11:25
  • Thank you @goodvibration for your reply. But in upgradeable contract, Logic may change in future how can I inherit logic in Tokenstorage. I am following the article to write this medium.com/carbon-money/… . Commented Aug 19, 2019 at 11:35

1 Answer 1


Sammu Sundar.

It happens because your Logic contract is not an owner/creator of the Storage contract (from what I understood).

In this case, it would be better to introduce an additional access control mechanism. You may call it manager or admin. The key point is to allow certain operations to be called not only by the owner.

You could use something like this as a base contract for entities that should be managed and owned.

contract Managed is Owned {          

    mapping (address => bool) public managers;

    constructor() public Owned() {
        managers[owner] = true;

    /**@dev Allows execution by managers only */
    modifier managerOnly {

    function setManager(address manager, bool state) public ownerOnly {
        managers[manager] = state;

Then just inherit your Storage contract from Managed and add managerOnly modifier instead of onlyOwner to the addTotalSupply. After you deploy both Storage and Logic, connect them by calling.

await storage.setManager(logic.address, true).send({from:owner})
//rest of the code

Hope, that will help.

  • Thank you for your answer. I think this may help with my problem. I will try and let you know. One more help, if you know any detail document for creating upgradeable ERC20 contract please share here Commented Aug 19, 2019 at 11:40
  • The word upgradeable is quite broad. What particular behaviour do you want to implement? Commented Aug 19, 2019 at 11:50
  • I need to modify in mint(). I have maximum mintable limit. Mint is happens every day until it reach maximum circulation. For example first deploy, it mint based on one formula.but after some day i need to change the formula. Commented Aug 19, 2019 at 12:04
  • 1
    Think about moving that mint logic to another contract, say MintLogic. Token contract can store address of current MintLogic and you'll be able to change it later via some changeLogic method. Example. Token's mint() function is { bool canMint = mintLogic.canMint(); uint256 amount = mintLogic.getMintAmount; if(canMint) {totalSupply += amount;} } Commented Aug 19, 2019 at 12:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.