ApeWorX / ape

The smart contract development tool for Pythonistas, Data Scientists, and Security Professionals
https://apeworx.io
Apache License 2.0
884 stars 132 forks source link

Equivalent of Hardhat/OpenZeppelin "deployProxy" and "upgradeProxy" in Ape? [APE-683] #1328

Closed PoCk3T-SPAI closed 1 year ago

PoCk3T-SPAI commented 1 year ago

Ape community,

My apologies, this issue doesn't belong in the "bug" category, I'm sure it can be re-labeled or discarded entirely.

Context = I'm deploying an upgradable ERC1155-based smart contract implementing OpenZepelin's "OwnableUpgradeable" + "UUPSUpgradeable" interfaces.

Problem = as far as I understand, deploying such smart contract with Ape deploys the implementation smart contract without the proxy in front of it. I can't call the mint function of such smart contract because the owner is set to 0x0. I would need to call the mint function of the proxy instead.

Question = is there any equivalent to Hardhat's "deployProxy" and "upgradeProxy" in Ape? I couldn't find any relevant information on ApeX/ape-hardhat repo

Thank you in advance for any insights the community members here could share :)

fubuloubu commented 1 year ago

A couple of questions first:

  1. Are you correctly deploying the proxy contract, referencing the implementation contract?
  2. Is the problem that you do not see the deployProxy and upgradeProxy methods within the deployed UUPS?
  3. Or, is the problem that you are looking for some easier method to deploy such a proxy?

There's a small bug with using proxies where more complex proxies end up missing their additional proxy methods, and you only see the implementation methods: https://github.com/ApeWorX/ape/issues/1249

note: this does not affect your deployment, it is still a valid proxy, but it is somewhat annoying to use the proxy due to this bug

As far as further support for these proxy types through specialized methods within the framework, we don't have that planned currently. Hopefully we can work with the fine people over at OpenZeppelin to add better support. Once we fix the above linked issue, it should be practical to manage them through contract calls.

PoCk3T-SPAI commented 1 year ago

Thank you @fubuloubu for the prompt feedbacks as always

Pardon my naiveness, this is fair to assume I'm going to keep learning a lot before making complete sense, but here's an attempt to answer your question:

Point 3 - I was following this OpenZeppelin tutorial which seems like to deploy the implementation contract & the proxy contract in one shot with "deployProxy", and was looking for an equivalent/simple way to do the same thing with Ape

I hope whatever insights gathered here would help the fellow Web2-turning-Web3 DevOps engineers like myself

fubuloubu commented 1 year ago

Ah okay, yes you are indeed correct that there isn't a "simple" way to do that today. Although, simple is a bit relative here because it shouldn't be more than a few extra lines of code to replicate the same thing

I had a similar issue with working on a different type of proxy, and this is how I solved it: https://github.com/fubuloubu/ape-safe/blob/8b3e3b5aa2c606e47660e2fd42237eb647a9b249/tests/conftest.py#L33-L36

Once you've merged the two ABIs together (a workaround for #1249) you can call methods from either, including the upgrade method from the UUPS. Deploying is just a matter of doing both deployments in sequence. Hope that code helps.

PoCk3T-SPAI commented 1 year ago

Thank you again @fubuloubu , it took me few days to figure out the concrete exact steps, but I was finally successful. Here's an extract for whoever is interested:

_implementation_contract_deployed = account.deploy(...)
_proxy_contract_deployed = account.deploy(<proxy contract of your choice like @openzeppelin/proxy/ERC1967/ERC1967Proxy.sol>, _implementation_contract_deployed, ...)
_proxy_contract_deployed.contract_type.abi += [*_implementation_contract_deployed.contract_type.abi]                
_proxy_contract_deployed.initialize(...)
_proxy_contract_deployed.call_implementation_contract_functions_here()
fubuloubu commented 1 year ago
_proxy_contract_deployed.contract_type.abi += [*_implementation_contract_deployed.contract_type.abi]                

And with #1249 implemented, we should be able to remove this line!

fopina commented 10 months ago

just bumped through this issue while looking for exactly the same information: how do I deploy a contract with a proxy?

All tutorials online seem to use openzeppelin hardhat, but I cannot find any information for ape...

@PoCk3T-SPAI did you do any quick write-up on your use case? I'd really like to go through it

Thanks