Using proxies created with ProxyFactory

Hi
I am trying to get some clarity on how proxies we create with ProxyFactory can be used/called.

My use case :

  1. I have a implementation/logic contract called Cash.sol. This is Initializable, Ownable. The Cash contract should be able to generate cash tokens of multiple currencies when ether is paid in. So, a minimal proxy of the Cash contract we deploy for USD should be able to generate a USD token, and a minimal proxy of the Cash contract we deploy for EUR should be able to generate a EUR token, and so forth. The only things that are parametrized for the minimal proxies is therefore a ‘currency name’.
        //initiliaze proxies. here, _owner is the Factory, name is the currency name/symbol
        function initialize(bytes32 _name, address _owner) public {
            Ownable.initialize(_owner);
            factory = Factory(_owner);
            name = _name;
            symbol = _name;
        }
  1. I have a Factory.sol which is a ProxyFactory. It creates proxies of the Cash (implementation) contract and stores the proxy addresses in an array.
            function createToken(address _target, bytes32 tokenName, bytes32 tokenType) external{
                    address _owner = msg.sender;            
                    bytes memory _payload = abi.encodeWithSignature("initialize(bytes32,address)", tokenName, _owner);

                    // Deploy proxy
                    address _via = deployMinimal(_target, _payload);
                    emit TokenCreated(_via, tokenName, tokenType);
                    if(tokenType == "Cash"){
                            token[_via] = via("ViaCash", tokenName);
                            tokens.push(_via);
                    }
            }
  1. I deploy the Factory and call and parameterize createToken() in the Factory with any number and names of currencies I want to support.
        deployer.deploy(Factory).then(async () => {
                const factory = await Factory.new();
                const cash = await Cash.new(); 
                await factory.createToken(cash.address, web3.utils.utf8ToHex("USD"), 
                web3.utils.utf8ToHex("Cash"));  await factory.createToken(cash.address, 
                web3.utils.utf8ToHex("EUR"), web3.utils.utf8ToHex("Cash"));});

Now, my rather (naive) question :slight_smile: is - to use the proxies, do I obtain the cash proxy address stored in the Factory and then use that address to send ether to ? I do not see how calls are delegated to the proxies.

Thanks !

1 Like

Hi @kallolborah,

Welcome to the community :wave:

That is correct. You call functions using the ABI of the Cash contract and the address of the minimal proxy.

The minimal proxy is a simple contract that just delegates all calls to a logic contract. A delegate call is similar to a regular call, except that all code is executed in the context of the caller, not of the callee. Meaning that the state is with the minimal proxy and there can be multiple minimal proxies all pointing to the one logic contract.

I suggest reading (if you haven’t already): Deep dive into the Minimal Proxy contract

That is correct. You call functions using the ABI of the Cash contract and the address of the minimal proxy.

If I want to call functions of one token that created by the Factory and the Cash, should I use the ABI of the Cash contract and its address that created by the deployMinimal() of the Factory, instead of the address of the minimal proxy?

1 Like

Hi @xxs,

Welcome to the community :wave:

We need to call the contract using the address of the minimal proxy, this is returned by deployMinimal and in the example contract above is emitted in the TokenCreated event.

Thanks. So if I want to deploy the 6 instance contracts that created by the Factory and the Cash, using Truffle, here is my part code in my migration.js (continued the third point above):

for (let i=0; i<6; i++) {
           var factoryTokenAddress = await factory.tokens(i);
           var cashInstance = await Cash.at(factoryTokenAddress); 
           console.log(factoryTokenAddress);
           console.log(await factory.token(factoryTokenAddress));
        }

It correct and can work? Thanks.

1 Like

Hi @xxs,

I would be tempted to have it in a separate script that you run after deployment of the factory and the logic contract. Otherwise it appears to look ok. I suggest testing it out on a local blockchain.

1 Like

Hi @abcoathup

deployer.deploy(Factory).then(async () => {
                const factory = await Factory.new();
                const cash = await Cash.new(); 
                await factory.createToken(cash.address, web3.utils.utf8ToHex("USD"), 
                web3.utils.utf8ToHex("Cash"));  await factory.createToken(cash.address, 
                web3.utils.utf8ToHex("EUR"), web3.utils.utf8ToHex("Cash"));});

Here are 2 cash proxy contracts now, and they are created. But if they are deployed now?

1 Like