A decentralized policy-based authorization system built on EigenLayer that enables intent-based transaction validation using Rego policies and zero-knowledge proofs.
- Overview
- Architecture
- Contract Documentation
- Policy System
- Deployment Guide
- Usage Examples
- Development Setup
- Security Considerations
- Related Projects
The Newton Policy Protocol AVS is a decentralized system that enables policy-based authorization for blockchain transactions. It allows users to submit transaction intents that are evaluated against predefined policies using the Rego language (Open Policy Agent), with cryptographic proofs ensuring the correctness of policy evaluations.
- Intent-Based Authorization: Users submit transaction intents that are evaluated against policies
- Rego Policy Engine: Flexible policy definition using Open Policy Agent's Rego language
- Zero-Knowledge Proofs: Supports SP1 and RISC0 proof systems for verification
- Decentralized Validation: Multiple operators validate policy evaluations
- Challenge Mechanism: Economic incentives ensure correctness through slashing
- EigenLayer Integration: Leverages restaked ETH for security
- Upgradeable Contracts: Uses OpenZeppelin's transparent proxy pattern for upgradeability
- Multi-Chain Support: Designed to work across different blockchain networks
- Policy Creation: Clients deploy policy contracts with Rego rules and configuration
- Policy Data Setup: Deploy policy data contracts with attestation mechanisms
- Intent Submission: Users submit transaction intents for policy evaluation
- Operator Validation: Multiple operators independently evaluate intents against policies
- Response Aggregation: BLS signatures from operators are aggregated and submitted
- Challenge Resolution: Challengers can dispute incorrect evaluations with ZK proofs
- Authorization: Validated intents are authorized for execution
The Newton Policy Protocol consists of several interconnected components working together to provide secure, decentralized policy-based authorization.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Policy Factory │────│ Policy Data │────│ Policy Client │
│ │ │ Factory │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Policy │ │ Policy Data │ │ Example Policy │
│ Contracts │ │ Contracts │ │ Client │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
▼
┌─────────────────┐
│ Newton Prover │
│ Task Manager │
│ (EigenLayer) │
└─────────────────┘
- Factory Layer: Deploys and manages policy and policy data contracts
- Policy Layer: Stores Rego policies, schemas, and configurations
- Data Layer: Handles policy data validation and attestation
- Client Layer: Interfaces for applications to interact with the policy system
- Validation Layer: EigenLayer-based task management and validation
Purpose: Factory contract for deploying new policy instances using CREATE2 for deterministic addresses.
Key Features:
- Deploys policy contracts using transparent upgradeable proxies
- Manages policy verification status
- Supports verifier role management
- Deterministic address computation
Key Functions:
function deployPolicy(
string memory _entrypoint,
string memory _policyUri,
string memory _schemaUri,
address[] memory _policyData,
string memory _metadataUri,
address _owner
) external returns (address policyAddr)
function computePolicyAddress(...) public view returns (address predicted)
function setPolicyVerification(address policyAddr, bool verified) externalPurpose: Core policy contract that stores Rego policies and client configurations.
Key Features:
- Stores policy URIs, schemas, and entrypoints
- Manages per-client policy configurations
- Supports policy verification status
- ERC165 interface compliance
Key Functions:
function setPolicy(PolicyConfig calldata policyConfig) public returns (bytes32)
function getPolicyConfig(bytes32 policyId) public view returns (PolicyConfig memory)
function isPolicyVerified() public view returns (bool)Policy Configuration Structure:
struct PolicyConfig {
bytes policyParams; // Encoded policy parameters
uint32 expireAfter; // Expiration time in blocks
}Purpose: Manages policy data with cryptographic attestation mechanisms.
Key Features:
- Multiple attestation types (ECDSA, BLS12-381, BN254, GROTH16)
- Policy data validation and expiration
- Flexible attestation configuration
- IPFS integration for data storage
Attestation Types:
enum AttestationType {
ECDSA, // ECDSA signature attestation
BN254, // BN254 curve signatures
BLS12_381, // BLS signatures on BLS12-381
GROTH16 // Zero-knowledge proofs using Groth16
}Purpose: Factory for deploying policy data contracts with proper attestation setup.
Purpose: Defines core message types and data structures used throughout the system.
Key Structures:
struct Intent {
address from;
address to;
uint256 value;
bytes data;
uint256 chainId;
bytes functionSignature;
}
struct Attestation {
bytes32 taskId;
bytes32 policyId;
address policyClient;
Intent intent;
uint32 expiration;
}Defines the standard interface for policy contracts including policy configuration, metadata management, and verification status.
Interface for client contracts that interact with the policy system, enabling policy-based transaction authorization.
Interface for policy data contracts with attestation capabilities and data validation.
Interface for the EigenLayer-based task management system that handles policy evaluation tasks.
Purpose: Comprehensive validation library for policies and policy data.
Key Functions:
function checkVerifiedPolicy(address policyClient, PolicyTaskData calldata policyTaskData)
function validatePolicyData(address policyAddress, PolicyTaskData calldata policyTaskData, uint32 currentBlock)Validation Features:
- Policy ID and address verification
- Policy data attestation validation
- Expiration checking
- Mainnet verification requirements
Utility library for chain-specific operations and network detection.
Library for task creation, hashing, and processing logic.
Purpose: Abstract base contract providing policy client functionality.
Key Features:
- ERC-7201 storage pattern for upgradeable contracts
- Policy configuration management
- Attestation validation
- Owner access control
Storage Structure:
struct NewtonPolicyClientStorage {
INewtonProverTaskManager policyTaskManager;
address policy;
bytes32 policyId;
address policyClientOwner;
}The Newton Protocol uses the Rego language (Open Policy Agent) for flexible and powerful policy definition. Policies are stored on-chain and evaluated by operators to determine whether user intents should be authorized.
package example
# Main authorization rule
allow if {
# Check if sender is authorized
input.sender in data.authorized_senders
# Verify transaction value limits
input.value <= data.max_transaction_value
# Validate target contract
input.target in data.allowed_contracts
# Additional custom logic
custom_validation
}
# Denial rules (explicit deny)
deny if {
input.target in data.blacklisted_contracts
}
# Helper rules
custom_validation if {
# Complex business logic
input.timestamp >= data.start_time
input.timestamp <= data.end_time
}- Policy URI: IPFS location of the Rego policy file
- Schema URI: JSON schema defining the policy input structure
- Entrypoint: The Rego rule to evaluate (e.g.,
example.allow) - Policy Parameters: Client-specific configuration data
- Policy Data: External data sources with attestation
- Policy Creation: Deploy policy contract with Rego rules and schema
- Policy Registration: Client calls
setPolicy()with configuration - Policy ID Generation: Unique ID created from policy data hash
- Task Association: Tasks reference policy ID for evaluation
- Evaluation: Operators evaluate user intents against policies
- Authorization: Validated intents are authorized for execution
Policy data provides external information that policies can use during evaluation. This data must be attested to ensure integrity.
- ECDSA Signatures: Traditional cryptographic signatures
- BLS Signatures: Aggregate signatures for efficiency
- Zero-Knowledge Proofs: GROTH16 proofs for privacy-preserving attestation
- Data Creation: Generate policy data off-chain
- Attestation: Sign or prove data integrity
- Upload: Store data and attestation on IPFS
- Registration: Deploy policy data contract
- Validation: Operators verify attestations during evaluation
- Foundry - Solidity development framework
- Docker - For local testing environment
- jq - JSON processing tool
- Node.js and npm - For additional tooling
- Clone the repository:
git clone <repository-url>
cd newton-contracts- Install dependencies:
git submodule update --init --recursive- Set up environment variables:
cp .env.example .env
# Edit .env with your configuration- Build contracts:
forge build- Start local Anvil node:
make start_docker
# or
anvil- Run tests:
forge test
# or
make testsThe project supports multiple networks configured in foundry.toml:
- Mainnet: Production Ethereum network
- Sepolia: Ethereum testnet
- Holesky: Ethereum testnet
- Local: Anvil local development
# Upload policy files to IPFS
make upload-policy-to-ipfs json=path/to/config.json chain_id=1
# Deploy policy contracts
make deploy-policy json=path/to/config.json chain_id=1
# Deploy policy client
make deploy-policy-client policy_params_file=path/to/params.json policy_address=0x...pragma solidity ^0.8.27;
import {NewtonPolicyClient} from "../mixins/NewtonPolicyClient.sol";
import {NewtonMessage} from "../core/NewtonMessage.sol";
import {INewtonPolicy} from "../interfaces/INewtonPolicy.sol";
contract MyPolicyClient is NewtonPolicyClient {
function initialize(
address policyTaskManager,
address policy,
address owner
) public initializer {
_initNewtonPolicyClient(policyTaskManager, policy, owner);
}
function executeWithPolicy(
NewtonMessage.Attestation calldata attestation
) external returns (bytes memory) {
require(_validateAttestation(attestation), "Invalid attestation");
NewtonMessage.Intent memory intent = attestation.intent;
(bool success, bytes memory result) = intent.to.call{value: intent.value}(intent.data);
require(success, "Intent execution failed");
return result;
}
}// Set up policy with parameters
INewtonPolicy.PolicyConfig memory config = INewtonPolicy.PolicyConfig({
policyParams: abi.encode(
maxTransactionValue,
allowedContracts,
authorizedSenders
),
expireAfter: 3600 // 1 hour in blocks
});
bytes32 policyId = policyClient.setPolicy(config);// Create an intent (off-chain)
const intent = {
from: userAddress,
to: targetContract,
value: ethers.utils.parseEther("1.0"),
data: encodedFunctionCall,
chainId: 1,
functionSignature: encodedABI,
};
// Submit to operators for evaluation
// Operators return attestation if policy allows
// Execute with attestation
await policyClient.executeIntent(attestation);newton-contracts/
├── src/
│ ├── core/ # Core protocol contracts
│ ├── interfaces/ # Contract interfaces
│ ├── libraries/ # Utility libraries
│ ├── middlewares/ # EigenLayer integration middleware
│ └── mixins/ # Reusable contract components
├── deployments/ # Chain-specific deployment artifacts
├── data/ # Configuration files
└── anvil/ # Local deployment scripts
Main Foundry configuration with:
- Solidity compiler settings (0.8.27)
- Optimizer configuration
- Network RPC endpoints
- Testing parameters
Automation for:
- Docker container management
- IPFS uploads
- Contract deployment
- Testing workflows
# Run all tests
forge test
# Run with verbosity
forge test -vvv
# Run specific test
forge test --match-test testPolicyDeployment
# Run with gas reporting
forge test --gas-reportThe project uses several tools for code quality:
- Solhint: Solidity linting
- Forge fmt: Code formatting
- Slither: Security analysis (configured in
slither.config.json)
# Format code
forge fmt
# Run linter
solhint src/**/*.sol
# Security analysis
slither .- Owner Controls: Critical functions protected by ownership checks
- Verifier System: Multi-party verification for policy validation
- Interface Validation: ERC165 checks for contract compatibility
- Policy Verification: Mainnet policies must be verified
- Data Attestation: All policy data must be cryptographically attested
- Expiration Handling: Time-based expiration for policies and data
- Transparent Proxies: OpenZeppelin's battle-tested proxy pattern
- Storage Layouts: ERC-7201 storage slots prevent collisions
- Initialization Guards: Prevent multiple initialization
- Policy ID Matching: Ensures correct policy evaluation
- Chain ID Validation: Prevents cross-chain replay attacks
- Signature Verification: Multiple signature schemes supported
- Expiration Checks: Prevents use of stale data
- Minimal Trust: Verify all external data and signatures
- Fail-Safe Defaults: Deny by default, allow explicitly
- Comprehensive Logging: Detailed events for monitoring
- Error Handling: Clear error messages and proper reverts
All EigenLayer code listed below is subject to the following license https://github.com/Layr-Labs/eigenlayer-middleware?tab=License-1-ov-file#readme
- eigensdk-rs - Official EigenLayer Rust SDK
- rust-bls-bn254 - EIP 2335 Compatible Keystore using BN254
- eigenlayer-contracts - EigenLayer core smart contracts
- eigenlayer-middleware - Middleware contracts for AVS development
- Open Policy Agent (OPA) - Policy engine used for Rego language
- Rego Language - Policy language for authorization decisions
- Regorus - Rust implementation of Rego
- SP1 - Succinct's zkVM for general-purpose computation
- RISC0 - RISC Zero's zkVM for verifiable computation
- Foundry - Fast, portable and modular toolkit for Ethereum development
- OpenZeppelin - Secure smart contract library
- IPFS - Distributed storage for policy files and data
For detailed schema reference and data structures, see SCHEMA_REFERENCE.md.
For contribution guidelines and development workflows, see the project's contribution documentation.