Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

metaregistry second gen #18

Open
3 tasks
bout3fiddy opened this issue Mar 6, 2024 · 0 comments
Open
3 tasks

metaregistry second gen #18

bout3fiddy opened this issue Mar 6, 2024 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@bout3fiddy
Copy link
Collaborator

bout3fiddy commented Mar 6, 2024

Background

The Metaregistry deployed at 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC is an on-chain API that integrators can use to get more information about the latest pools from Curve. It is currently used by analysts and notable integrators in the dex aggregator as well as yield aggregator space.

Requirements

Users have needs that evolve with the times. The immutable nature of the Metaregistry does not accommodate this evolution. Since the metaregistry does not hold user funds, it is a good candidate to adopt an upgradeable proxy architecture.

Limitations

Vyper does not currently support upgradeable proxies in a way that is useful to the metaregistry. To date, the best implementation of this is by Banteg, which has several limitations:

Limitation 1: cannot cleanly comply with EIP1967 for storage slots

_gap_0: uint256[24440054405305269366569402256811496959409073762505157381672968839269610695612]
implementation: public(address)# @ 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
_gap_1: uint256[57515418674210777583064340759886350581885744927316125368323712657003024561478]
admin: public(address)# @ 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103

_gap_0 and _gap_1 are hacky ways to ensure that implementation and admin methods have deterministic storage slots. This can be achieved by specifying storage slots during compile time but this falls short since integrators will not go the length to add yet another .json file in the pipeline to verify these contracts.

Vyper needs the ability to specify storage slots at compile time but within the smart contract itself. This would be the bare minimum devex necessary for the second gen of the metaregistry.

Limitation 2: cannot specify universal return type in fallback method

In the example, banted mentions:

@external
def __default__() -> uint256:
    """
    FIXME vyper needs a way to pass verbatim buffer for this to work universally
    """
    result: uint256 = convert(raw_call(self.implementation, msg.data, max_outsize=32, is_delegate_call=True), uint256)
    return result

The __default__ method cannot return values other than uint256 here. For this, Vyper devs have theorised a raw_return, which could potentially looks similar to:

@external
def __default__():
    raw_return(raw_call(self.implementation, msg.data, max_outsize=32, is_delegate_call=True))

Second-generation metaregistry is blocked from being developed without overcoming these two limitations. It also makes limited sense to build it without it being upgradeable since that would not be a future-proof way.

Task List

  • Coordinate with vyper devs and get enabling features on vyper release 0.4.1
  • create2deploy upgradeable proxy with deterministic addresses across all chains
  • test and deploy metaregistry contracts on these chains

Challenges

Because the metaregistry is going to be on several chains, this is quite the cumbersome task since there can be quite a few edge-cases.

@bout3fiddy bout3fiddy self-assigned this Mar 6, 2024
@bout3fiddy bout3fiddy added the enhancement New feature or request label Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant