Skip to content

bayological/pact-contracts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pact Contracts

A minimal Solidity reference implementation of the Pact specification using Foundry.

What is Pact?

Pact is a specification for structured commitments between parties that require judgment to evaluate. Unlike purely deterministic smart contracts, Pacts handle subjective criteria like "quality of work" or "reasonable effort" through external resolvers (humans, AI, or DAOs).

Key principle: "If a resolver determines X was satisfied, then Y"

Pact sits between fully deterministic systems and completely subjective arrangements, providing:

  • Minimal structure separating resolution, enforcement, and storage
  • Resolver-agnostic evaluation (any entity can assess pacts)
  • Composable outcomes (trigger transfers, gate access, chain to other pacts)
  • Portable across on-chain, off-chain, or hybrid environments

Architecture

Contract Overview

pact-contracts/
├── src/
│   ├── interfaces/
│   │   ├── IPactRegistry.sol      # Core pact interface
│   │   └── IResolver.sol          # Resolver interface
│   ├── PactRegistry.sol           # Main registry implementation
│   └── resolvers/
│       └── SimpleResolver.sol     # Basic resolver (owner-controlled)
└── test/
    └── PactRegistry.t.sol         # Comprehensive test suite

State Machine

Proposed → Active → Resolved
             ↓
         Disputed → Resolved

States:

  • Proposed: Pact created, awaiting signatures
  • Active: Both parties signed, pact is in effect
  • Disputed: Party raised a dispute
  • Resolved: Resolver determined the outcome

Pact Structure

Each pact contains:

  • id: Unique identifier (keccak256 hash)
  • parties: Client and provider addresses
  • termsHash: IPFS hash or keccak256 of off-chain terms JSON
  • resolver: Address of resolver contract
  • stakeAmount: What's at risk (tracked, not escrowed)
  • state: Current state
  • signatures: Whether each party signed
  • resolution: Outcome once resolved

Resolution Outcomes

  • None: Not yet resolved
  • Fulfilled: Provider met the terms
  • Breached: Provider failed to meet terms
  • Partial: Mixed outcome (resolver discretion)

Example Usage

Creating a Pact

// 1. Deploy registry and resolver
PactRegistry registry = new PactRegistry();
SimpleResolver resolver = new SimpleResolver(address(registry));

// 2. Create terms off-chain (JSON)
{
  "description": "Build a website with 5 pages",
  "acceptance_criteria": [
    "All pages must be responsive",
    "Must pass accessibility audit",
    "Delivered within 30 days"
  ]
}
// Hash: 0xabc... (or IPFS: QmXyz...)

// 3. Client creates pact
bytes32 pactId = registry.createPact(
  providerAddress,
  0xabc..., // termsHash
  address(resolver),
  100 ether // stake amount (tracked, not transferred)
);

// 4. Both parties sign
registry.signPact(pactId); // client
registry.signPact(pactId); // provider → pact becomes Active

// 5. If needed, dispute
registry.disputePact(pactId); // either party

// 6. Resolver evaluates and resolves
resolver.submitResolution(
  pactId,
  IPactRegistry.Outcome.Fulfilled,
  "ipfs://QmReasoning..." // detailed reasoning
);

Design Decisions

What This Implementation Does

  • ✅ Core pact lifecycle (propose, sign, activate, dispute, resolve)
  • ✅ State machine enforcement
  • ✅ Party-only and resolver-only access control
  • ✅ Event emissions for key transitions
  • ✅ Resolution tracking with reasoning hashes
  • ✅ Simple resolver reference implementation

What This Implementation Does NOT Do

  • No actual escrow/token transfers (just tracks amounts)
  • No upgradability patterns (for simplicity)
  • No governance (resolver is owner-controlled)
  • No complex access control (just party/resolver checks)
  • No automatic enforcement (pacts are commitment records)

This is a proof-of-concept to validate the spec on-chain, not a production-ready system.

Extentions

Custom Resolvers

Can implement IResolver for custom resolution logic:

contract AIResolver is IResolver {
    function canResolve(bytes32 pactId) external view returns (bool) {
        // Check if AI model can evaluate this pact type
    }

    function submitResolution(bytes32 pactId, Outcome outcome, string calldata reasonHash) external {
        // Verify AI oracle signature
        // Submit resolution to registry
    }
}

License

MIT

Resources


About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published