diff --git a/README.MD b/README.MD index 86a1edce..8f10ba8a 100644 --- a/README.MD +++ b/README.MD @@ -15,6 +15,14 @@ For integrators: check exchange_received. That should improve your pathing signi 5. [`LiquidityGauge`](contracts/main/LiquidityGauge.vy): [0x64891ab20392a029c0f231656ff13c5ee64b730c](https://sepolia.etherscan.io/address/0x64891ab20392a029c0f231656ff13c5ee64b730c#code) 6. [`CurveStableSwapFactoryNG`](contracts/main/CurveStableSwapFactoryNG.vy): [0x8a00365ae28d75b92ec695d5a041b744f140438d](https://sepolia.etherscan.io/address/0x8a00365ae28d75b92ec695d5a041b744f140438d#code) +## Gnosis + +1. [`CurveStableSwapNGMath`](contracts/main/CurveStableSwapNGMath.vy): [0x87FE17697D0f14A222e8bEf386a0860eCffDD617](https://gnosisscan.io/address/0x87FE17697D0f14A222e8bEf386a0860eCffDD617#code) +2. [`CurveStableSwapNGViews`](contracts/main/CurveStableSwapNGViews.vy): [0x5eeE3091f747E60a045a2E715a4c71e600e31F6E](https://gnosisscan.io/address/0x5eeE3091f747E60a045a2E715a4c71e600e31F6E#code) +3. [`StableSwapNG`](contracts/main/CurveStableSwapNG.vy): [0xd2002373543Ce3527023C75e7518C274A51ce712](https://gnosisscan.io/address/0xd2002373543Ce3527023C75e7518C274A51ce712#code) +4. [`StableSwapMetaNG`](contracts/main/CurveStableSwapMetaNG.vy): [0x686bdb3D24Bc6F3ED89ed3d3B659765c54aC78B4](https://gnosisscan.io/address/0x686bdb3D24Bc6F3ED89ed3d3B659765c54aC78B4#code) +5. [`CurveStableSwapFactoryNG`](contracts/main/CurveStableSwapFactoryNG.vy): [0xe61Fb97Ef6eBFBa12B36Ffd7be785c1F5A2DE66b](https://gnosisscan.io/address/0xe61Fb97Ef6eBFBa12B36Ffd7be785c1F5A2DE66b#code) + ## Overview The metapool factory has several core components: diff --git a/poetry.lock b/poetry.lock index 4d684944..297ebbb3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4115,15 +4115,13 @@ version = "0.1.8" description = "A Vyper interpreter" optional = false python-versions = "*" -files = [ - {file = "titanoboa-0.1.8-py3-none-any.whl", hash = "sha256:6551663ba52793d8a2113ab1a169de32ed2c102166a5655e2988af7e9cb8997e"}, - {file = "titanoboa-0.1.8.tar.gz", hash = "sha256:5fc3a6638ade9885d1d271367d4e05d91bdce246e7064882196ccd213ab927cd"}, -] +files = [] +develop = false [package.dependencies] eth-abi = "*" eth-account = "*" -eth-stdlib = "*" +eth-stdlib = ">=0.2.7,<0.3.0" eth-typing = "*" hypothesis = "*" py-evm = ">=0.7.0a4" @@ -4135,6 +4133,12 @@ vyper = ">=0.3.10" [package.extras] forking-recommended = ["ujson"] +[package.source] +type = "git" +url = "https://github.com/vyperlang/titanoboa.git" +reference = "3201bf318d10c238071365be833ef8e3c7eaaef2" +resolved_reference = "3201bf318d10c238071365be833ef8e3c7eaaef2" + [[package]] name = "tomli" version = "2.0.1" @@ -4801,4 +4805,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "cc845fc44050fac852d04626b39b9dc33546a6d4b173f2e607dff2608105c4a0" +content-hash = "4bd0c70b9ebc5d3a0d92e626ea31898516bb129fd5f2ca0abaee77e4fd77565f" diff --git a/pyproject.toml b/pyproject.toml index e0a22a08..0898b544 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ packages = [] [tool.poetry.dependencies] python = "^3.10" poetry = "1.5.1" -titanoboa = "0.1.8" +titanoboa = {git = "https://github.com/vyperlang/titanoboa.git", rev = "3201bf318d10c238071365be833ef8e3c7eaaef2"} vyper = "0.3.10" pycryptodome = "^3.18.0" pre-commit = "^3.3.3" diff --git a/scripts/deploy_infra.py b/scripts/deploy_infra.py index 85e6b8e8..75dbbc2c 100644 --- a/scripts/deploy_infra.py +++ b/scripts/deploy_infra.py @@ -4,25 +4,66 @@ import boa import deployment_utils as deploy_utils from boa.network import NetworkEnv +from eth_abi import encode from eth_account import Account from rich.console import Console as RichConsole logger = RichConsole(file=sys.stdout) +deployments = { + "ethereum:sepolia": { + "math": "0xbc7654d2dd901aaaa3be4cb5bc0f10dea9f96443", + "views": "0x07920e98a66e462c2aa4c8fa6200bc68ca161ea0", + "plain_amm": "0x296d2b5c23833a70d07c8fcbb97d846c1ff90ddd", + "meta_amm": "0xdd7ebb1c49780519dd9755b8b1a23a6f42ce099e", + "gauge": "0x64891ab20392a029c0f231656ff13c5ee64b730c", + "factory": "0x8a00365ae28d75b92ec695d5a041b744f140438d", + }, + "gnosis:mainnet": { + "math": "0x87FE17697D0f14A222e8bEf386a0860eCffDD617", + "views": "0x5eeE3091f747E60a045a2E715a4c71e600e31F6E", + "plain_amm": "0xd2002373543Ce3527023C75e7518C274A51ce712", + "meta_amm": "0x686bdb3D24Bc6F3ED89ed3d3B659765c54aC78B4", + "factory": "0xe61Fb97Ef6eBFBa12B36Ffd7be785c1F5A2DE66b", + }, +} + def set_evm_version(contract_file, network) -> boa.vyper.contract.VyperDeployer: with open(contract_file, "r") as f: source = f.read() - if "ethereum" in network and "# pragma evm-version paris" in source: - source.replace("# pragma evm-version paris", "# pragma evm-version shanghai") - elif "ethereum" not in network and "# pragma evm-version shanghai" in source: - source.replace("# pragma evm-version shanghai", "# pragma evm-version paris") + is_shanghai_chain = any([x in network for x in ["ethereum", "gnosis"]]) + + if is_shanghai_chain and "# pragma evm-version paris" in source: + logger.log("Replacing EVM version to Shanghai ...") + source = source.replace("# pragma evm-version paris\n", "# pragma evm-version shanghai\n") + elif not is_shanghai_chain and "# pragma evm-version shanghai" in source: + logger.log("Replacing EVM version to Paris ...") + source = source.replace("# pragma evm-version shanghai\n", "# pragma evm-version paris\n") return boa.loads_partial(source_code=source) +def check_and_deploy(contract_obj, contract_designation, network, blueprint: bool = False, args=[]): + + deployed_contract = deployments[network][contract_designation] + + if not deployed_contract: + logger.log(f"Deploying {contract_designation} contract ...") + if not blueprint: + contract = contract_obj.deploy(*args) + else: + contract = contract_obj.deploy_as_blueprint() + logger.log(f"Deployed! At: {contract.address}.") + else: + logger.log(f"Deployed {contract_designation} contract exists. Using {deployed_contract} ...") + contract = contract_obj.at(deployed_contract) + + return contract + + def deploy_infra(network, url, account, fork=False): if fork: @@ -49,37 +90,61 @@ def deploy_infra(network, url, account, fork=False): views_contract_obj = set_evm_version("./contracts/main/CurveStableSwapNGViews.vy", network) plain_contract_obj = set_evm_version("./contracts/main/CurveStableSwapNG.vy", network) meta_contract_obj = set_evm_version("./contracts/main/CurveStableSwapMetaNG.vy", network) - gauge_contract_obj = set_evm_version("./contracts/main/LiquidityGauge.vy", network) # deploy non-blueprint contracts: logger.log("Deploying non-blueprint AMM components ...") - math_contract = math_contract_obj.deploy() - views_contract = views_contract_obj.deploy() + math_contract = check_and_deploy(math_contract_obj, "math", network) + views_contract = check_and_deploy(views_contract_obj, "views", network) # deploy blueprints: logger.log("Deploying blueprints ...") - plain_blueprint = plain_contract_obj.deploy_as_blueprint() - meta_blueprint = meta_contract_obj.deploy_as_blueprint() - gauge_blueprint = gauge_contract_obj.deploy_as_blueprint() + plain_blueprint = check_and_deploy(plain_contract_obj, "plain_amm", network, blueprint=True) + meta_blueprint = check_and_deploy(meta_contract_obj, "meta_amm", network, blueprint=True) # Factory: factory_contract_obj = set_evm_version("./contracts/main/CurveStableSwapFactoryNG.vy", network) logger.log("Deploying factory ...") - factory = factory_contract_obj.deploy(fee_receiver, deploy_utils.FIDDYDEPLOYER) + args = [fee_receiver, deploy_utils.FIDDYDEPLOYER] + factory = check_and_deploy(factory_contract_obj, "factory", network, False, args) - # Set it all up: + constructor_args = encode(["address", "address"], args) + logger.log(f"Constructor arguments for factory: {constructor_args.hex()}") + + # Set up AMM implementations: logger.log("Integrating AMM components into factory ...") - factory.set_gauge_implementation(gauge_blueprint.address) - factory.set_views_implementation(views_contract.address) - factory.set_math_implementation(math_contract.address) - factory.set_pool_implementations(0, plain_blueprint.address) - factory.set_metapool_implementations(0, meta_blueprint.address) + + if not factory.views_implementation() == views_contract.address: + factory.set_views_implementation(views_contract.address) + logger.log(f"Set views implementation to: {views_contract.address}") + + if not factory.math_implementation() == math_contract.address: + factory.set_math_implementation(math_contract.address) + logger.log(f"Set math implementation to: {math_contract.address}") + + if not factory.pool_implementations(0) == plain_blueprint.address: + factory.set_pool_implementations(0, plain_blueprint.address) + logger.log(f"Set plain amm implementation to: {plain_blueprint.address}") + + if not factory.metapool_implementations(0) == meta_blueprint.address: + factory.set_metapool_implementations(0, meta_blueprint.address) + logger.log(f"Set meta amm implementation to: {meta_blueprint.address}") + + if "ethereum" in network: # Gauge contract only for Ethereum. + logger.log("Deploying and setting up Gauge contracts ...") + gauge_contract_obj = set_evm_version("./contracts/main/LiquidityGauge.vy", network) + gauge_blueprint = check_and_deploy(gauge_contract_obj, "gauge", network, blueprint=True) + + if not factory.gauge_implementation() == gauge_blueprint.address: + factory.set_gauge_implementation(gauge_blueprint.address) + logger.log(f"Set liquidity gauge implementation to: {gauge_blueprint.address}") + + logger.log("Infra deployed!") def main(): deploy_infra( - "ethereum:sepolia", - "https://eth-sepolia.g.alchemy.com/v2/{alchemy_key}", + "gnosis:mainnet", + "https://gnosis.api.onfinality.io/public", "FIDDYDEPLOYER", False, # forkmode ) diff --git a/scripts/deploy_pool.py b/scripts/deploy_pool.py new file mode 100644 index 00000000..a60d290b --- /dev/null +++ b/scripts/deploy_pool.py @@ -0,0 +1,34 @@ +import os +import sys + +import boa +from boa.network import NetworkEnv +from eth_account import Account +from rich.console import Console as RichConsole + +logger = RichConsole(file=sys.stdout) + + +def deploy_plain_pool(network, url, account, factory, fork=False): + + if fork: + boa.env.fork(url) + else: + boa.set_env(NetworkEnv(url)) + boa.env.add_account(Account.from_key(os.environ[account])) + + factory = boa.load_partial("./contracts/main/CurveStableSwapFactoryNG.vy").at(factory) + + +def main(): + deploy_plain_pool( + "ethereum:sepolia", + "https://eth-sepolia.g.alchemy.com/v2/{alchemy_key}", + "FIDDYDEPLOYER", + "0x8a00365ae28d75b92ec695d5a041b744f140438d", + False, # forkmode + ) + + +if __name__ == "__main__": + main()