Skip to content

Commit 4d21cb4

Browse files
authored
Merge pull request #101 from Lay3rLabs/ecdsa-poa
ECDSA POA - transfer ownership
2 parents f444368 + ef5eb10 commit 4d21cb4

File tree

9 files changed

+119
-4
lines changed

9 files changed

+119
-4
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,27 @@ This configuration should be set in the project's **Taskfile** variables:
186186
USES_MOCK: true
187187
```
188188
189-
> Note: Only wavs-drand currently uses mock deployments. Sync services must use real deployments on the source chain, as they rely on EigenLayer core contracts for testing and cannot operate with mocks.
189+
## Transfer Ownership
190+
191+
After deploying middleware contracts, you may want to transfer ownership of the ECDSA proxy and AVS contracts to different addresses.
192+
193+
### Configuration
194+
195+
1. **Set owner addresses** in [taskfile/config.yml](taskfile/config.yml):
196+
```yaml
197+
AVS_OWNER: "0x1111111111111111111111111111111111111111"
198+
PROXY_OWNER: "0x2222222222222222222222222222222222222222"
199+
```
200+
201+
2. **Enable ownership transfer** in your project's **Taskfile**:
202+
```yaml
203+
vars:
204+
TRANSFER_OWNERSHIP: true
205+
```
206+
207+
When `TRANSFER_OWNERSHIP` is set to `true`, the bootstrap process will automatically transfer ownership after middleware deployment using the addresses configured in config.yml. The system will use the appropriate transfer method based on your deployment mode:
208+
209+
- **Regular deployments**: Uses `middleware:transfer-ownership`
210+
- **Mock deployments**: Uses `middleware:mock-transfer-ownership` with mock-specific environment variables
211+
212+
If `TRANSFER_OWNERSHIP` is `false` or not set, ownership transfer will be skipped entirely.

projects/multi-chain-operator-sync/Taskfile.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ tasks:
5959
task bootstrap:build-service
6060
task bootstrap:upload-service
6161
task bootstrap:set-service-uri
62+
task bootstrap:middleware-transfer-ownership
6263
6364
clean:
6465
desc: "Cleans up the tool"

projects/multi-chain-quorum-sync/Taskfile.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ tasks:
5858
task bootstrap:build-service
5959
task bootstrap:upload-service
6060
task bootstrap:set-service-uri
61+
task bootstrap:middleware-transfer-ownership
6162
6263
clean:
6364
desc: "Cleans up the tool"

projects/operator-updater/Taskfile.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ vars:
3333
# project name is same as dir name of current directory
3434
sh: basename "$(pwd)"
3535
BLOCK_INTERVAL: 100
36-
PAST_BLOCKS: 500
3736
WAVS_CLI_SERVICE_JSON_PATH: "/wavs-tools/projects/{{.PROJECT}}/.project-output/services/{{.COMPONENT_NAME}}.json"
3837
PROJECT_OUTPUT_DIR: '{{joinPath .ROOT_DIR ".project-output"}}'
3938
SERVICE_OUTPUT_DIR: '{{joinPath .PROJECT_OUTPUT_DIR "services"}}'
4039
SERVICE_JSON_PATH: "{{.SERVICE_OUTPUT_DIR}}/{{.COMPONENT_NAME}}.json"
4140
TEMP_SERVICE_HASH_JSON_PATH: "{{.SERVICE_OUTPUT_DIR}}/hash.json"
41+
TRANSFER_OWNERSHIP: true
4242

4343
tasks:
4444
bootstrap:
@@ -55,6 +55,7 @@ tasks:
5555
task bootstrap:register-service
5656
task bootstrap:deploy-service
5757
task bootstrap:register-operator
58+
task bootstrap:middleware-transfer-ownership
5859
5960
clean:
6061
desc: "Cleans up the tool"

projects/wavs-drand/Taskfile.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ vars:
2828
# These are all locally defined here, do not depend on config.yml being loaded first
2929
# For this reason, we sometimes need to redefined vars like .project-output here
3030
# see: https://github.com/go-task/task/issues/2303
31-
# wavs-drand uses MOCK mode
31+
# wavs-drand uses MOCK mode since it doesn't rely on any eigenlayer core contractrs
3232
USES_MOCK: true
3333
COMPONENT_NAME: "wavs_drand"
3434
PROJECT:
@@ -41,6 +41,7 @@ vars:
4141
SERVICE_JSON_PATH: "{{.SERVICE_OUTPUT_DIR}}/{{.COMPONENT_NAME}}.json"
4242
TEMP_SERVICE_HASH_JSON_PATH: "{{.SERVICE_OUTPUT_DIR}}/hash.json"
4343
SOURCE_CHAIN_NUMBER: 1
44+
TRANSFER_OWNERSHIP: true
4445

4546
tasks:
4647
bootstrap:
@@ -59,6 +60,7 @@ tasks:
5960
task bootstrap:deploy-service
6061
task bootstrap:wavs-all
6162
task bootstrap:register-operator
63+
task bootstrap:middleware-transfer-ownership
6264
6365
clean:
6466
desc: "Cleans up the tool"

taskfile/common/bootstrap.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,24 @@ tasks:
4848
cd "{{.REPO_ROOT}}" && task middleware:deploy PROJECT="{{.PROJECT}}" SERVICE_NAME="{{.PROJECT}}" {{.CHAIN_ARG}}
4949
fi
5050
51+
middleware-transfer-ownership:
52+
desc: "Transfer ownership of ECDSA proxy and AVS contracts (conditional on TRANSFER_OWNERSHIP)"
53+
vars:
54+
TRANSFER_OWNERSHIP: '{{.TRANSFER_OWNERSHIP | default "false"}}'
55+
USES_MOCK: '{{.USES_MOCK | default "false"}}'
56+
CHAIN_ARG: "{{if .SOURCE_CHAIN_NUMBER}}CHAIN_NUMBER={{.SOURCE_CHAIN_NUMBER}}{{end}}"
57+
requires:
58+
vars: [PROJECT, REPO_ROOT, PROXY_OWNER, AVS_OWNER]
59+
status:
60+
- '[ "{{.TRANSFER_OWNERSHIP}}" != "true" ]'
61+
cmds:
62+
- |
63+
if [ "{{.USES_MOCK}}" = "true" ]; then
64+
cd "{{.REPO_ROOT}}" && task middleware:mock-transfer-ownership PROJECT="{{.PROJECT}}" SERVICE_NAME="{{.PROJECT}}" PROXY_OWNER="{{.PROXY_OWNER}}" AVS_OWNER="{{.AVS_OWNER}}" {{.CHAIN_ARG}}
65+
else
66+
cd "{{.REPO_ROOT}}" && task middleware:transfer-ownership PROJECT="{{.PROJECT}}" SERVICE_NAME="{{.PROJECT}}" PROXY_OWNER="{{.PROXY_OWNER}}" AVS_OWNER="{{.AVS_OWNER}}" {{.CHAIN_ARG}}
67+
fi
68+
5169
build-mock-config:
5270
desc: "Build mock configuration JSON with all active operators"
5371
vars:

taskfile/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ vars:
4646
sh: |
4747
docker ps --format '{{"{{"}}.Names{{"}}"}}' | grep 'wavs-' | grep -v 'wavs-aggregator' | wc -l | xargs
4848
SUBMIT_DELAY: '{{ternary 1 5 (eq .DEPLOY_ENV "LOCAL")}}'
49+
# Transfer Ownership Config
50+
AVS_OWNER: "0x1111111111111111111111111111111111111111"
51+
PROXY_OWNER: "0x2222222222222222222222222222222222222222"

taskfile/docker.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: "3"
22

33
vars:
44
WAVS_DOCKER_IMAGE: "ghcr.io/lay3rlabs/wavs:94f641f"
5-
MIDDLEWARE_DOCKER_IMAGE: "ghcr.io/lay3rlabs/wavs-middleware:0548d44"
5+
MIDDLEWARE_DOCKER_IMAGE: "ghcr.io/lay3rlabs/wavs-middleware:d8c1320"
66
FOUNDRY_DOCKER_IMAGE: "ghcr.io/foundry-rs/foundry:latest"
77
JAEGER_DOCKER_IMAGE: "jaegertracing/jaeger:2.5.0"
88
PROMETHEUS_DOCKER_IMAGE: "prom/prometheus:v3.3.0"

taskfile/middleware.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,69 @@ tasks:
450450
CHAIN_ID: "{{.CHAIN_ID | default .MIDDLEWARE_CHAIN_ID}}"
451451
cmds:
452452
- sh -c 'jq -r ".addresses.strategyManager" "node_modules/@wavs/solidity/contracts/deployments/eigenlayer-core/{{.CHAIN_ID}}.json" 2>/dev/null || true'
453+
454+
transfer-ownership:
455+
desc: "Transfer ownership of ECDSA proxy and AVS contracts"
456+
vars:
457+
CHAIN_NUMBER: '{{.CHAIN_NUMBER | default "1"}}'
458+
NODES_DIR:
459+
sh: task middleware:get-output-dir CHAIN_NUMBER={{.CHAIN_NUMBER}} PROJECT={{.PROJECT}} SERVICE_NAME={{.SERVICE_NAME}}
460+
requires:
461+
vars: [PROJECT, SERVICE_NAME, PROXY_OWNER, AVS_OWNER]
462+
env:
463+
RPC_URL:
464+
sh: task backend:get-evm-rpc-url-{{.CHAIN_NUMBER}}
465+
WAVS_SERVICE_MANAGER_ADDRESS:
466+
sh: task middleware:get-service-manager-address CHAIN_NUMBER={{.CHAIN_NUMBER}} PROJECT={{.PROJECT}} SERVICE_NAME={{.SERVICE_NAME}}
467+
PROXY_OWNER: "{{.PROXY_OWNER}}"
468+
AVS_OWNER: "{{.AVS_OWNER}}"
469+
FUNDED_KEY: "{{.DEPLOYER_PRIVATE_KEY}}"
470+
preconditions:
471+
- sh: cast to-checksum {{.AVS_OWNER}}
472+
msg: AVS_OWNER is not a valid address
473+
- sh: cast to-checksum {{.PROXY_OWNER}}
474+
msg: PROXY_OWNER is not a valid address
475+
cmds:
476+
- >
477+
{{.DOCKER_SUDO}} docker run --rm --network host
478+
-e DEPLOY_ENV
479+
-e RPC_URL
480+
-e WAVS_SERVICE_MANAGER_ADDRESS
481+
-e PROXY_OWNER
482+
-e AVS_OWNER
483+
-e FUNDED_KEY
484+
-v {{.NODES_DIR}}:/root/.nodes
485+
{{.MIDDLEWARE_DOCKER_IMAGE}} transfer_ownership
486+
487+
mock-transfer-ownership:
488+
desc: "Transfer ownership of mock ECDSA proxy and AVS contracts"
489+
vars:
490+
CHAIN_NUMBER: '{{.CHAIN_NUMBER | default "1"}}'
491+
NODES_DIR:
492+
sh: task middleware:get-output-dir CHAIN_NUMBER={{.CHAIN_NUMBER}} PROJECT={{.PROJECT}} SERVICE_NAME={{.SERVICE_NAME}}
493+
requires:
494+
vars: [PROJECT, SERVICE_NAME, PROXY_OWNER, AVS_OWNER]
495+
env:
496+
MOCK_RPC_URL:
497+
sh: task backend:get-evm-rpc-url-{{.CHAIN_NUMBER}}
498+
WAVS_SERVICE_MANAGER_ADDRESS:
499+
sh: task middleware:get-service-manager-address CHAIN_NUMBER={{.CHAIN_NUMBER}} PROJECT={{.PROJECT}} SERVICE_NAME={{.SERVICE_NAME}}
500+
PROXY_OWNER: "{{.PROXY_OWNER}}"
501+
AVS_OWNER: "{{.AVS_OWNER}}"
502+
MOCK_DEPLOYER_KEY: "{{.DEPLOYER_PRIVATE_KEY}}"
503+
preconditions:
504+
- sh: cast to-checksum {{.AVS_OWNER}}
505+
msg: AVS_OWNER is not a valid address
506+
- sh: cast to-checksum {{.PROXY_OWNER}}
507+
msg: PROXY_OWNER is not a valid address
508+
cmds:
509+
- >
510+
{{.DOCKER_SUDO}} docker run --rm --network host
511+
-e DEPLOY_ENV
512+
-e MOCK_RPC_URL
513+
-e WAVS_SERVICE_MANAGER_ADDRESS
514+
-e PROXY_OWNER
515+
-e AVS_OWNER
516+
-e MOCK_DEPLOYER_KEY
517+
-v {{.NODES_DIR}}:/root/.nodes
518+
{{.MIDDLEWARE_DOCKER_IMAGE}} -m mock transfer_ownership

0 commit comments

Comments
 (0)