From 8f83a78145b0ac8983857b9b7a730401899f4316 Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Sat, 9 Mar 2024 14:51:16 -0800 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=A7=B1=20arbitrum=20nitro=20node=20do?= =?UTF-8?q?cker=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ctf_launchers/nitro_pwn_launcher.py | 47 +++++++++++++++++++ .../ctf_server/backends/docker_backend.py | 34 ++++++++++---- paradigmctf.py/ctf_server/types/__init__.py | 23 ++++++++- 3 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py diff --git a/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py b/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py new file mode 100644 index 0000000..203ed3a --- /dev/null +++ b/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py @@ -0,0 +1,47 @@ +import os + +from eth_abi import abi +import requests +from ctf_launchers.launcher import Action, Launcher, ORCHESTRATOR_HOST, CHALLENGE +from ctf_launchers.team_provider import TeamProvider, get_team_provider +from ctf_server.types import UserData, get_privileged_web3 +from web3 import Web3 + +FLAG = os.getenv("FLAG", "PCTF{flag}") + + +class NitroPwnChallengeLauncher(Launcher): + def __init__( + self, + project_location: str = "challenge/project", + provider: TeamProvider = get_team_provider(), + ): + super().__init__( + 'nitro', + project_location, + provider, + [ + Action(name="get flag", handler=self.get_flag), + ], + ) + + def get_flag(self) -> int: + instance_body = requests.get(f"{ORCHESTRATOR_HOST}/instances/{self.get_instance_id()}").json() + if not instance_body['ok']: + print(instance_body['message']) + return 1 + + user_data = instance_body['data'] + + if not self.is_solved( + user_data, user_data['metadata']["challenge_address"] + ): + print("are you sure you solved it?") + return 1 + + print(FLAG) + return 0 + + def is_solved(self, user_data: UserData, addr: str) -> bool: + # TODO + return False diff --git a/paradigmctf.py/ctf_server/backends/docker_backend.py b/paradigmctf.py/ctf_server/backends/docker_backend.py index b9e82e1..9ef7bb6 100644 --- a/paradigmctf.py/ctf_server/backends/docker_backend.py +++ b/paradigmctf.py/ctf_server/backends/docker_backend.py @@ -13,7 +13,8 @@ InstanceInfo, UserData, format_anvil_args, - format_starknet_args + format_starknet_args, + format_nitro_args ) from docker.errors import APIError, NotFound from docker.models.containers import Container @@ -41,12 +42,26 @@ def _launch_instance_impl(self, request: CreateInstanceRequest) -> UserData: if request["type"] == "starknet": anvil_containers[anvil_id] = self.__client.containers.run( name=f"{instance_id}-{anvil_id}", - image=anvil_args.get("image", "shardlabs/starknet-devnet-rs"), + image=anvil_args.get( + "image", "shardlabs/starknet-devnet-rs"), network="paradigmctf", entrypoint=["tini", "--", "starknet-devnet"] + [ - shlex.quote(str(v)) - for v in format_starknet_args(anvil_args, anvil_id) - ], + shlex.quote(str(v)) + for v in format_starknet_args(anvil_args, anvil_id) + ], + restart_policy={"Name": "always"}, + detach=True, + mounts=[ + Mount(target="/data", source=volume.id), + ], + ) + elif request["type"] == "nitro": + anvil_containers[anvil_id] = self.__client.containers.run( + name=f"{instance_id}-{anvil_id}", + image=anvil_args.get( + "image", "offchainlabs/stylus-node:v0.1.0-f47fec1-dev"), + network="paradigmctf", + command=format_nitro_args(anvil_args, anvil_id), restart_policy={"Name": "always"}, detach=True, mounts=[ @@ -91,7 +106,8 @@ def _launch_instance_impl(self, request: CreateInstanceRequest) -> UserData: anvil_instances: Dict[str, InstanceInfo] = {} for anvil_id, anvil_container in anvil_containers.items(): - container: Container = self.__client.containers.get(anvil_container.id) + container: Container = self.__client.containers.get( + anvil_container.id) anvil_instances[anvil_id] = { "id": anvil_id, @@ -171,11 +187,13 @@ def __try_delete( def __try_delete_container(self, container_name: str): try: try: - container: Container = self.__client.containers.get(container_name) + container: Container = self.__client.containers.get( + container_name) except NotFound: return - logging.info("deleting container %s (%s)", container.id, container.name) + logging.info("deleting container %s (%s)", + container.id, container.name) try: container.kill() diff --git a/paradigmctf.py/ctf_server/types/__init__.py b/paradigmctf.py/ctf_server/types/__init__.py index afe50bb..9662118 100644 --- a/paradigmctf.py/ctf_server/types/__init__.py +++ b/paradigmctf.py/ctf_server/types/__init__.py @@ -64,6 +64,7 @@ def format_anvil_args(args: LaunchAnvilInstanceArgs, anvil_id: str, port: int = return cmd_args + def format_starknet_args(args: LaunchAnvilInstanceArgs, anvil_id: str, port: int = 8545) -> List[str]: cmd_args = [] cmd_args += ["--host", "0.0.0.0"] @@ -73,6 +74,25 @@ def format_starknet_args(args: LaunchAnvilInstanceArgs, anvil_id: str, port: int return cmd_args +def format_nitro_args(args: LaunchAnvilInstanceArgs, anvil_id: str, port: int = 8545) -> List[str]: + cmd_args = [] + cmd_args += ["--node.dangerous.no-l1-listener"] + cmd_args += ["--node.sequencer.dangerous.no-coordinator"] + cmd_args += ["--node.sequencer.enable"] + cmd_args += ["--node.staker.enable=false"] + cmd_args += ["--init.dev-init"] + cmd_args += ["--init.empty=false"] + cmd_args += ["--chain.id=473474"] + cmd_args += ["--chain.dev-wallet.private-key=b6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659"] + cmd_args += ["--http.addr=0.0.0.0"] + cmd_args += ["--http.port", str(port)] + cmd_args += ["--http.vhosts='*'"] + cmd_args += ["--http.corsdomain='*'"] + cmd_args += ["--chain.info-json", '[{"chain-name": "ctf","chain-config": {"chainId": 473474,"homesteadBlock": 0,"daoForkBlock": null,"daoForkSupport": true,"eip150Block": 0,"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block": 0,"eip158Block": 0,"byzantiumBlock": 0,"constantinopleBlock": 0,"petersburgBlock": 0,"istanbulBlock": 0,"muirGlacierBlock": 0,"berlinBlock": 0,"londonBlock": 0,"clique": {"period": 0,"epoch": 0},"arbitrum": {"EnableArbOS": true,"AllowDebugPrecompiles": true,"DataAvailabilityCommittee": false,"InitialArbOSVersion": 11,"InitialChainOwner": "0x0000000000000000000000000000000000000000","GenesisBlockNum": 0}}}]'] + + return cmd_args + + class DaemonInstanceArgs(TypedDict): image: str @@ -133,7 +153,8 @@ def get_additional_account(mnemonic: str, offset: int) -> LocalAccount: def get_privileged_web3(user_data: UserData, anvil_id: str) -> Web3: anvil_instance = user_data["anvil_instances"][anvil_id] return Web3( - Web3.HTTPProvider(f"http://{anvil_instance['ip']}:{anvil_instance['port']}") + Web3.HTTPProvider( + f"http://{anvil_instance['ip']}:{anvil_instance['port']}") ) From 2ad553f344af8cca77a42f074a5f7f7404b11e95 Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Sat, 9 Mar 2024 15:03:56 -0800 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20prepare=20node=20fu?= =?UTF-8?q?nc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paradigmctf.py/ctf_server/backends/backend.py | 7 ++++++- paradigmctf.py/ctf_server/backends/docker_backend.py | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/paradigmctf.py/ctf_server/backends/backend.py b/paradigmctf.py/ctf_server/backends/backend.py index f5a0de8..deb6762 100644 --- a/paradigmctf.py/ctf_server/backends/backend.py +++ b/paradigmctf.py/ctf_server/backends/backend.py @@ -107,4 +107,9 @@ def _prepare_node_starknet(self, args: LaunchAnvilInstanceArgs, web3: Web3): starknet_getVersion(web3) break except: - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) + + def _prepare_node_nitro(self, args: LaunchAnvilInstanceArgs, web3: Web3): + while not web3.is_connected(): + time.sleep(0.1) + continue diff --git a/paradigmctf.py/ctf_server/backends/docker_backend.py b/paradigmctf.py/ctf_server/backends/docker_backend.py index 9ef7bb6..2860cd8 100644 --- a/paradigmctf.py/ctf_server/backends/docker_backend.py +++ b/paradigmctf.py/ctf_server/backends/docker_backend.py @@ -126,6 +126,13 @@ def _launch_instance_impl(self, request: CreateInstanceRequest) -> UserData: Web3.HTTPProvider(url) ), ) + elif request["type"] == "nitro": + self._prepare_node_nitro( + request["anvil_instances"][anvil_id], + Web3( + Web3.HTTPProvider(url) + ), + ) else: self._prepare_node( request["anvil_instances"][anvil_id], From 5af40e3dcff97d6f15a3cce45d2672ba5f775b4d Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Sat, 9 Mar 2024 18:49:43 -0800 Subject: [PATCH 3/8] =?UTF-8?q?=F0=9F=92=B8=20nitro=20fund=20accounts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paradigmctf.py/ctf_launchers/launcher.py | 21 +++++++++++++----- paradigmctf.py/ctf_launchers/utils.py | 10 ++++++--- paradigmctf.py/ctf_server/backends/backend.py | 22 +++++++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/paradigmctf.py/ctf_launchers/launcher.py b/paradigmctf.py/ctf_launchers/launcher.py index 2684ead..b849676 100644 --- a/paradigmctf.py/ctf_launchers/launcher.py +++ b/paradigmctf.py/ctf_launchers/launcher.py @@ -8,7 +8,7 @@ import requests from ctf_launchers.team_provider import TeamProvider -from ctf_launchers.utils import deploy, deploy_cairo, http_url_to_ws +from ctf_launchers.utils import deploy, deploy_cairo, deploy_nitro, http_url_to_ws from ctf_server.types import ( CreateInstanceRequest, DaemonInstanceArgs, @@ -124,11 +124,14 @@ def launch_instance(self) -> int: if self.type == "starknet": web3 = get_privileged_web3(user_data, "main") - + credentials = self.get_credentials(web3.provider.endpoint_uri) challenge_addr = self.deploy_cairo(user_data, credentials) priv_key = credentials[1][1] + elif self.type == "nitro": + challenge_addr = self.deploy_nitro(user_data, self.mnemonic) + priv_key = get_player_account(self.mnemonic).key.hex() else: challenge_addr = self.deploy(user_data, self.mnemonic) priv_key = get_player_account(self.mnemonic).key.hex() @@ -141,7 +144,8 @@ def launch_instance(self) -> int: print() print(f"your private blockchain has been set up") - print(f"it will automatically terminate in {round(TIMEOUT/60)} minutes") + print( + f"it will automatically terminate in {round(TIMEOUT/60)} minutes") print(f"---") print(f"rpc endpoints:") for id in user_data["anvil_instances"]: @@ -171,12 +175,19 @@ def deploy(self, user_data: UserData, mnemonic: str) -> str: web3, self.project_location, mnemonic, env=self.get_deployment_args( user_data) ) - + def deploy_cairo(self, user_data: UserData, credentials: list) -> str: web3 = get_privileged_web3(user_data, "main") return deploy_cairo(web3, self.project_location, credentials, env=self.get_deployment_args(user_data)) - + + def deploy_nitro(self, user_data: UserData, mnemonic: str) -> str: + web3 = get_privileged_web3(user_data, "main") + + return deploy_nitro( + web3, self.project_location, mnemonic, env=self.get_deployment_args( + user_data) + ) def get_deployment_args(self, user_data: UserData) -> Dict[str, str]: return {} diff --git a/paradigmctf.py/ctf_launchers/utils.py b/paradigmctf.py/ctf_launchers/utils.py index c01d7c8..662b54c 100644 --- a/paradigmctf.py/ctf_launchers/utils.py +++ b/paradigmctf.py/ctf_launchers/utils.py @@ -10,7 +10,6 @@ from foundry.anvil import anvil_autoImpersonateAccount, anvil_setCode - def deploy( web3: Web3, project_location: str, @@ -109,6 +108,10 @@ def deploy_cairo( return output[:65] +def deploy_stylus(): + pass + + def anvil_setCodeFromFile( web3: Web3, addr: str, @@ -123,10 +126,11 @@ def anvil_setCodeFromFile( anvil_setCode(web3, addr, bytecode) + def http_url_to_ws(url: str) -> str: if url.startswith("http://"): - return "ws://" + url[len("http://") :] + return "ws://" + url[len("http://"):] elif url.startswith("https://"): - return "wss://" + url[len("https://") :] + return "wss://" + url[len("https://"):] return url diff --git a/paradigmctf.py/ctf_server/backends/backend.py b/paradigmctf.py/ctf_server/backends/backend.py index deb6762..8ee7892 100644 --- a/paradigmctf.py/ctf_server/backends/backend.py +++ b/paradigmctf.py/ctf_server/backends/backend.py @@ -113,3 +113,25 @@ def _prepare_node_nitro(self, args: LaunchAnvilInstanceArgs, web3: Web3): while not web3.is_connected(): time.sleep(0.1) continue + + pk = "0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" + acc = web3.eth.account.from_key(pk) + + for i in range(args.get("accounts", DEFAULT_ACCOUNTS)): + transaction = { + 'from': acc.address, + 'to': self.__derive_account( + args.get("derivation_path", DEFAULT_DERIVATION_PATH), + args.get("mnemonic", DEFAULT_MNEMONIC), + i, + ).address, + 'value': 250 * 10 ** 18, + 'nonce': web3.eth.get_transaction_count(acc.address), + 'gas': 1000000, + 'chainId': web3.eth.chain_id, + 'gasPrice': web3.eth.gas_price + } + + signed = web3.eth.account.sign_transaction(transaction, pk) + + web3.eth.send_raw_transaction(signed.rawTransaction) From b81c7dfce44a3bf82905b9b47936a584d8153e35 Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Sat, 9 Mar 2024 22:01:50 -0800 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20stylus=20contract=20de?= =?UTF-8?q?ployment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paradigmctf.py/Dockerfile | 14 ++++++++ paradigmctf.py/ctf_launchers/utils.py | 46 ++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/paradigmctf.py/Dockerfile b/paradigmctf.py/Dockerfile index fd4cb77..ffc1f69 100644 --- a/paradigmctf.py/Dockerfile +++ b/paradigmctf.py/Dockerfile @@ -30,6 +30,20 @@ RUN true && \ huffup && \ true +# Install Stylus + +env RUSTUP_HOME=/opt/rust/rustup CARGO_HOME=/opt/rust/cargo +env PATH=${PATH}:/opt/rust/cargo/bin + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +RUN rustup toolchain install nightly +RUN rustup component add rust-src --toolchain nightly +RUN rustup target add wasm32-unknown-unknown +RUN RUSTFLAGS="-C link-args=-rdynamic" cargo install --force cargo-stylus +RUN cargo install wasm-opt --locked + +RUN chmod -R 777 /opt/rust + # (Optimization) Install requirements COPY requirements.txt /tmp/requirements.txt diff --git a/paradigmctf.py/ctf_launchers/utils.py b/paradigmctf.py/ctf_launchers/utils.py index 662b54c..7b8da66 100644 --- a/paradigmctf.py/ctf_launchers/utils.py +++ b/paradigmctf.py/ctf_launchers/utils.py @@ -1,10 +1,9 @@ import json import os -import shutil +import re import subprocess from typing import Dict -from eth_account.account import LocalAccount from web3 import Web3 from foundry.anvil import anvil_autoImpersonateAccount, anvil_setCode @@ -108,8 +107,47 @@ def deploy_cairo( return output[:65] -def deploy_stylus(): - pass +def deploy_nitro( + web3: Web3, + project_location: str, + credentials: list, + deploy_script: str = "deploy.py", + env: Dict = {}, +) -> str: + rfd, wfd = os.pipe2(os.O_NONBLOCK) + + proc = subprocess.Popen( + args=[ + "/opt/rust/cargo/bin/cargo", + "stylus", + "deploy", + "-e", + web3.provider.endpoint_uri, + "--private-key", + "0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" + ], + pass_fds=[wfd], + cwd=project_location, + text=True, + encoding="utf8", + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = proc.communicate() + + if proc.returncode != 0: + print(stdout) + print(stderr) + raise Exception("script failed to run") + + address = stdout.split('Activating program at address ')[1].replace("\\n", "") + + ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') + + output = ansi_escape.sub('', address)[:42] + + return output def anvil_setCodeFromFile( From 1d2b254a75d4e61bd6ef487c77144f0cdc19c80e Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Mon, 11 Mar 2024 10:54:35 -0700 Subject: [PATCH 5/8] =?UTF-8?q?=E2=9C=A8=20deploy=20solidity=20and=20stylu?= =?UTF-8?q?s=20contracts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paradigmctf.py/ctf_launchers/utils.py | 76 +++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/paradigmctf.py/ctf_launchers/utils.py b/paradigmctf.py/ctf_launchers/utils.py index 7b8da66..17508fe 100644 --- a/paradigmctf.py/ctf_launchers/utils.py +++ b/paradigmctf.py/ctf_launchers/utils.py @@ -107,11 +107,64 @@ def deploy_cairo( return output[:65] +def deploy_no_impersonate( + web3: Web3, + project_location: str, + mnemonic: str, + deploy_script: str = "script/Deploy.s.sol:Deploy", + env: Dict = {}, +) -> str: + rfd, wfd = os.pipe2(os.O_NONBLOCK) + + proc = subprocess.Popen( + args=[ + "/opt/foundry/bin/forge", + "script", + "--rpc-url", + web3.provider.endpoint_uri, + "--out", + "/artifacts/out", + "--cache-path", + "/artifacts/cache", + "--broadcast", + "--unlocked", + "--sender", + "0x0000000000000000000000000000000000000000", + deploy_script, + ], + env={ + "PATH": "/opt/huff/bin:/opt/foundry/bin:/usr/bin:" + os.getenv("PATH", "/fake"), + "MNEMONIC": mnemonic, + "OUTPUT_FILE": f"/proc/self/fd/{wfd}", + } + | env, + pass_fds=[wfd], + cwd=project_location, + text=True, + encoding="utf8", + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = proc.communicate() + + if proc.returncode != 0: + print(stdout) + print(stderr) + raise Exception("forge failed to run") + + result = os.read(rfd, 256).decode("utf8") + + os.close(rfd) + os.close(wfd) + + return result + + def deploy_nitro( web3: Web3, project_location: str, - credentials: list, - deploy_script: str = "deploy.py", + mnemonic: list, env: Dict = {}, ) -> str: rfd, wfd = os.pipe2(os.O_NONBLOCK) @@ -141,11 +194,26 @@ def deploy_nitro( print(stderr) raise Exception("script failed to run") - address = stdout.split('Activating program at address ')[1].replace("\\n", "") + address = stdout.split('Activating program at address ')[ + 1].replace("\\n", "") ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') - output = ansi_escape.sub('', address)[:42] + token = ansi_escape.sub('', address)[:42] + + env = { + "PATH": "/opt/huff/bin:/opt/foundry/bin:/usr/bin:" + os.getenv("PATH", "/fake"), + "MNEMONIC": mnemonic, + "OUTPUT_FILE": f"/proc/self/fd/{wfd}", + "TOKEN": token + } + + output = deploy_no_impersonate( + web3, + project_location, + "", + env=env, + ) return output From 480b8b6f1b6b08f0414711aee16c3c2aee961bec Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:52:37 -0700 Subject: [PATCH 6/8] =?UTF-8?q?=E2=9C=A8=20nitro=20initialize=20contract?= =?UTF-8?q?=20with=20cast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ctf_launchers/nitro_pwn_launcher.py | 14 ++++- paradigmctf.py/ctf_launchers/utils.py | 52 ++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py b/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py index 203ed3a..2fe9be6 100644 --- a/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py +++ b/paradigmctf.py/ctf_launchers/nitro_pwn_launcher.py @@ -43,5 +43,15 @@ def get_flag(self) -> int: return 0 def is_solved(self, user_data: UserData, addr: str) -> bool: - # TODO - return False + web3 = get_privileged_web3(user_data, "main") + + (result,) = abi.decode( + ["bool"], + web3.eth.call( + { + "to": addr, + "data": web3.keccak(text="isSolved()")[:4], + } + ), + ) + return result diff --git a/paradigmctf.py/ctf_launchers/utils.py b/paradigmctf.py/ctf_launchers/utils.py index 17508fe..48f671c 100644 --- a/paradigmctf.py/ctf_launchers/utils.py +++ b/paradigmctf.py/ctf_launchers/utils.py @@ -111,8 +111,9 @@ def deploy_no_impersonate( web3: Web3, project_location: str, mnemonic: str, + token: str, deploy_script: str = "script/Deploy.s.sol:Deploy", - env: Dict = {}, + env: Dict = {} ) -> str: rfd, wfd = os.pipe2(os.O_NONBLOCK) @@ -158,9 +159,57 @@ def deploy_no_impersonate( os.close(rfd) os.close(wfd) + # cast_initialize(web3, project_location, token, result) + return result +def cast_initialize( + web3: Web3, + project_location: str, + token: str, + entrypoint: str +) -> str: + rfd, wfd = os.pipe2(os.O_NONBLOCK) + + proc = subprocess.Popen( + args=[ + "/opt/foundry/bin/cast", + "send", + token, + '"initialize(address)"', + entrypoint, + "--rpc-url", + web3.provider.endpoint_uri, + "--private-key", + "0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" + ], + pass_fds=[wfd], + cwd=project_location, + text=True, + encoding="utf8", + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = proc.communicate() + + if proc.returncode != 0: + print(stdout) + print(stderr) + raise Exception("cast failed to run") + + result = os.read(rfd, 256).decode("utf8") + + os.close(rfd) + os.close(wfd) + + return result + + + + + def deploy_nitro( web3: Web3, project_location: str, @@ -212,6 +261,7 @@ def deploy_nitro( web3, project_location, "", + token, env=env, ) From d4c09a5da913afaeede78b380dfe37984273d66e Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Mon, 11 Mar 2024 13:39:34 -0700 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=90=9B=20fix=20stylus=20deploy=20and?= =?UTF-8?q?=20cast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- paradigmctf.py/ctf_launchers/utils.py | 48 +++++++-------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/paradigmctf.py/ctf_launchers/utils.py b/paradigmctf.py/ctf_launchers/utils.py index 48f671c..9b05279 100644 --- a/paradigmctf.py/ctf_launchers/utils.py +++ b/paradigmctf.py/ctf_launchers/utils.py @@ -115,31 +115,22 @@ def deploy_no_impersonate( deploy_script: str = "script/Deploy.s.sol:Deploy", env: Dict = {} ) -> str: - rfd, wfd = os.pipe2(os.O_NONBLOCK) - proc = subprocess.Popen( args=[ "/opt/foundry/bin/forge", - "script", + "create", + "src/Challenge.sol:Challenge", + "--constructor-args", + token, "--rpc-url", web3.provider.endpoint_uri, - "--out", - "/artifacts/out", - "--cache-path", - "/artifacts/cache", - "--broadcast", - "--unlocked", - "--sender", - "0x0000000000000000000000000000000000000000", - deploy_script, + "--private-key", + "0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" ], env={ "PATH": "/opt/huff/bin:/opt/foundry/bin:/usr/bin:" + os.getenv("PATH", "/fake"), - "MNEMONIC": mnemonic, - "OUTPUT_FILE": f"/proc/self/fd/{wfd}", } | env, - pass_fds=[wfd], cwd=project_location, text=True, encoding="utf8", @@ -154,14 +145,12 @@ def deploy_no_impersonate( print(stderr) raise Exception("forge failed to run") - result = os.read(rfd, 256).decode("utf8") + address = stdout.split('Deployed to: ')[ + 1].replace("\\n", "")[:42] - os.close(rfd) - os.close(wfd) + cast_initialize(web3, project_location, token, address) - # cast_initialize(web3, project_location, token, result) - - return result + return address def cast_initialize( @@ -170,21 +159,17 @@ def cast_initialize( token: str, entrypoint: str ) -> str: - rfd, wfd = os.pipe2(os.O_NONBLOCK) - proc = subprocess.Popen( args=[ "/opt/foundry/bin/cast", "send", token, - '"initialize(address)"', - entrypoint, + "0xc4d66de8000000000000000000000000" + entrypoint[2:], "--rpc-url", web3.provider.endpoint_uri, "--private-key", "0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" ], - pass_fds=[wfd], cwd=project_location, text=True, encoding="utf8", @@ -192,6 +177,7 @@ def cast_initialize( stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) + stdout, stderr = proc.communicate() if proc.returncode != 0: @@ -199,16 +185,6 @@ def cast_initialize( print(stderr) raise Exception("cast failed to run") - result = os.read(rfd, 256).decode("utf8") - - os.close(rfd) - os.close(wfd) - - return result - - - - def deploy_nitro( web3: Web3, From 0bc79686dce9b74d65c240b7aad59b7d97c2e811 Mon Sep 17 00:00:00 2001 From: cairo <101215230+cairoeth@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:50:08 -0700 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=94=A7=20update=20images=20and=20requ?= =?UTF-8?q?irements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kubernetes/ctf-server.yaml | 4 ++-- paradigmctf.py/docker-compose.yml | 4 ++-- paradigmctf.py/requirements.txt | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/kubernetes/ctf-server.yaml b/kubernetes/ctf-server.yaml index 09d3627..c627909 100644 --- a/kubernetes/ctf-server.yaml +++ b/kubernetes/ctf-server.yaml @@ -91,7 +91,7 @@ spec: runAsNonRoot: true containers: - name: orchestrator - image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2023-server:latest + image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2024-server:latest command: ["uvicorn", "--host", "0.0.0.0", "--port", "7283", "ctf_server:orchestrator"] env: - name: BACKEND @@ -142,7 +142,7 @@ spec: runAsNonRoot: true containers: - name: anvil-proxy - image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2023-server:latest + image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2024-server:latest command: ["uvicorn", "--host", "0.0.0.0", "--port", "8545", "--workers", "16", "ctf_server:anvil_proxy"] env: - name: DATABASE diff --git a/paradigmctf.py/docker-compose.yml b/paradigmctf.py/docker-compose.yml index faf04e0..1befd2a 100644 --- a/paradigmctf.py/docker-compose.yml +++ b/paradigmctf.py/docker-compose.yml @@ -14,7 +14,7 @@ services: - database:/data ctf-server-orchestrator: container_name: orchestrator - image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2023-server:latest + image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2024-server:latest build: . user: root command: uvicorn ctf_server:orchestrator --host 0.0.0.0 --port 7283 @@ -32,7 +32,7 @@ services: - database ctf-server-anvil-proxy: container_name: anvil-proxy - image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2023-server:latest + image: us-docker.pkg.dev/idyllic-adviser-409615/openzeppelin/ctf-2024-server:latest build: . command: uvicorn ctf_server:anvil_proxy --host 0.0.0.0 --port 8545 ports: diff --git a/paradigmctf.py/requirements.txt b/paradigmctf.py/requirements.txt index 877dbac..3314056 100644 --- a/paradigmctf.py/requirements.txt +++ b/paradigmctf.py/requirements.txt @@ -97,3 +97,5 @@ web3==6.11.3 websocket-client==1.6.4 websockets==12.0 yarl==1.9.2 +vyper==0.4.0b4 +snekmate @ git+https://github.com/pcaversaccio/snekmate.git@modules \ No newline at end of file