0

https://github.com/optionality/clone-factory/blob/master/contracts/CloneFactory.sol#L32 contains a code to deploy a basic proxy.

This code misses a way to pass data to the proxied contract to init it.

Initialization could be accomplished an init method but that's legible to attack of running a wrong init() call before the user by passing high gas price. This makes the hacker able to make a legit user either not to be able to deploy at all or to pay high gas because he would need to deploy multiple times to reach the right init() arguments.

I see no reason for anyone playing this game with my users, but allowing to circumvent legit users for anyone who wants to play with his extra gas is nevertheless a bad thing.

Could you give me a code for deploying an efficient proxy that does not suffer from this vulnerability?

1

I think a case could be made that this concern is a non-issue.

Remember, the initialized state is in your proxy.

Someone else can DELEGATECALL to your contract and it will, at first, seem uninitialized in the context of their proxy (because their state is uninitialized) but that does not interfere with your system. Someone else out there would be using your contract and that might not sit right with you, but that would be a separate concern and not a threat to your system.

Even the initializer modifier in the open zeppelin Initializer.sol contract doesn't prevent others from initializing their proxy with your contract's function. It only prevents you from doing it twice. Each such proxy would be, effectively, a separate instance of your contract.

Consider:

On deployment, initialize it. Perhaps you are setting up ownership or other parameters in the initialization. Confirm everything is as it should be before you enable the contract, e.g. the Pausable pattern. Since you are deploying the debut release of the system there is probably no value in it, yet. If someone front-runs your transaction, you will catch it because you are not the owner. It seems like a pointless attack because you'll just redeploy.

On upgrade, you don't initialize it this time. It's already initialized because it picks up the existing state. If there is further, new work to do for the new version, that's another function that you can safely protect with access control, e.g. onlyOwner. The new contract would recall the owner value (and everything else) from the existing state, and you wouldn't want to initialize twice.

I don't see a front-running concern. Just make sure you own it before you use it.

As a PSA for anyone else who happens along, one has to be very careful about not upsetting the state variable layout at the bytecode level or there will be bigger problems.

Hope it helps.

2
  • My concern is exactly if someone "uses my contract' that is call init() on my contract. So your answer is unrelated to my question. – porton Dec 22 '20 at 8:16
  • And I told that the problem is that the attacked my increase my costs of redeploy. Yes, it's pointless, but hackers are pointless. – porton Dec 22 '20 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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