v1.0.1 Audited by Hashlock (September 20th, 2025)
A Proof of Authority (POA) middleware system for managing operator registration, stake tracking, and signature validation using ECDSA signatures. This middleware provides a lightweight alternative to traditional EigenLayer-based AVS systems by implementing a simplified stake registry with quorum-based validation.
- Docker and Docker Compose
- Foundry (Forge and Cast) for local development and testing
- Node.js and npm for dependency management
To run the test suite, make sure you have Foundry installed. Then run:
# Run all tests
make test
# Run ECDSA tests only
make test-ecdsa
# Generate coverage report
make coverage-html-ecdsaFirst, ensure you have all dependencies:
npm installThen, build the image:
docker build -t poa-middleware .Prepare the env file:
CHAIN=holesky
cp docker/env.example.$CHAIN docker/.env
# edit the RPC_URL, DEPLOY_ENV for a paid testnet rpc endpoint.
# edit the FORK_RPC_URL for local deployment.Start anvil in one terminal:
source docker/.env
anvil --fork-url $FORK_RPC_URL --host 0.0.0.0 --port 8545Run all the following scripts in the docker/ directory.
cd docker/Deploys the POA middleware contracts.
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware deploy| Environment Variable | Required | Default | Source | Description |
|---|---|---|---|---|
DEPLOY_ENV |
for non-default value | LOCAL |
.env |
Deployment environment (LOCAL or TESTNET) |
RPC_URL |
for non-default value | http://localhost:8545 |
.env |
RPC URL |
FUNDED_KEY |
Yes | - | .env |
Private key with funds for deployment |
Registers an operator with the POA stake registry.
OPERATOR_KEY=$(cast wallet new --json | jq -r '.[0].private_key')
OPERATOR_ADDRESS=$(cast wallet addr --private-key "$OPERATOR_KEY")
echo "Operator address: $OPERATOR_ADDRESS"
SIGNING_KEY=$(cast wallet new --json | jq -r '.[0].private_key')
SIGNING_ADDRESS=$(cast wallet addr --private-key "$SIGNING_KEY")
echo "Signing address: $SIGNING_ADDRESS"
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware owner_operation registerOperator $OPERATOR_ADDRESS 10000Updates the weight of a registered operator.
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware owner_operation updateOperatorWeight $OPERATOR_ADDRESS 1000Updates the signing key for an operator.
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware update_signing_key $OPERATOR_KEY $SIGNING_ADDRESSDeregisters an operator from the POA stake registry.
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware owner_operation deregisterOperator $OPERATOR_ADDRESSUpdates the minimum stake threshold required for validation.
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware owner_operation updateStakeThreshold 100Updates the quorum configuration for signature validation.
docker run --rm --network host -v ./.nodes:/root/.nodes \
--env-file .env \
poa-middleware owner_operation updateQuorum 3 5| Environment Variable | Required | Default | Source | Description |
|---|---|---|---|---|
DEPLOY_ENV |
for non-default value | LOCAL |
.env |
Deployment environment (LOCAL or TESTNET) |
RPC_URL |
for non-default value | http://localhost:8545 |
.env |
RPC URL |
OPERATOR_KEY |
Yes | - | Command line | Private key for the operator |
SIGNING_ADDRESS |
Yes | - | Command line | Address of the signing key |
- POAStakeRegistry: Main contract managing operator registration and stake tracking
- POAStakeRegistryStorage: Storage layer for historical data using OpenZeppelin Checkpoints
- IPOAStakeRegistry: Interface defining all contract functions and events
- Operator Management: Register, deregister, and update operator weights
- Signing Key Management: Operators can update their signing keys
- Stake Tracking: Historical tracking of operator weights and total stake
- Quorum Validation: Configurable quorum requirements for signature validation
- ECDSA Signature Verification: Validates signatures against registered signing keys
- Threshold Management: Configurable minimum stake thresholds
The system validates ECDSA signatures by:
- Verifying signatures against registered signing keys
- Checking that signers are sorted in ascending order
- Ensuring sufficient stake weight has signed
- Validating against quorum requirements
- Checking threshold requirements