Search code examples
solidityhardhat

Running new() inside my contract adds 20K to contract size?


I created a function where one of my contracts instantiates another and it suddenly pushed the whole contract over the size limit. Here's the function:

function createContract(E.BKLiteMeta memory meta)         
          public 
          payable
          returns(address) 
    {
        require(meta.publisherAddress == msg.sender, "only pub");
        return(address(new BKopyLite(meta)));
    }

Hardhat size-contracts reports the size of the contract 24.02. When I change the function to:

function createContract(E.BKLiteMeta memory meta)         
          public 
          payable
          returns(address) 
    {
        require(meta.publisherAddress == msg.sender, "only pub");
        return(address(0);
    }

`size-contracts' reports a size of 4.68. So about 20K increase in size by calling new? Can someone explain, and sugggest a workaround? (The contract size of the BKopyLite contract is about 17k)


Solution

  • The new keyword results in a new contract being deployed and this requires access to its bytecode. To do this the compiler embeds BKopyLite's bytecode inside the parent contract. If the contract to be deployed is fairly big, it can add a lot to the size of the parent contract.

    There are ways to avoid that:

    • You could for example have a special factory contract, whose only job is deploying copies of BKopyLite. The parent contract would make an external call to it to trigger deployment of BKopyLite and receive an address of a new instance in return.
    • You could deploy a single instance of the contract and use OpenZeppelin's Clones to create lightweight "copies". The copies would actually be proxy contracts that have their own storage and let the single instance operate on it via DELEGATECALL.