Thank you for your interest in contributing to Quake. This document covers everything you need to get involved — from your first issue to submitting production-ready code. Quake has a more complex architecture than most Soroban projects due to its oracle layer, so please read the oracle-specific sections carefully before contributing to contract code.
- Code of conduct
- Ways to contribute
- Getting started
- Project structure
- Development workflow
- Writing Soroban contracts
- Working with the oracle layer
- Writing the SDK
- Testing
- Pull request process
- Issue guidelines
- Security vulnerabilities
- Community
Quake follows the Contributor Covenant Code of Conduct. Report unacceptable behaviour via the security email in the repository's security policy.
Code
- Implement contract features from the roadmap
- Build oracle jobs for new data sources
- Fix bugs and improve test coverage
- Optimise Soroban compute unit usage
Research
- Propose and model trigger threshold calibration for new verticals
- Audit the oracle consensus mechanism
- Research anchor integrations for new markets
- Model reserve pool solvency under stress scenarios
Documentation
- Improve guides for policyholders, LP stakers, and oracle operators
- Write integration tutorials
Community
- Answer questions in GitHub Discussions
- Review open pull requests
- Report bugs with clear reproduction steps
| Tool | Version | Purpose |
|---|---|---|
| Rust | >=1.74 |
Soroban contract development |
soroban-cli |
latest | Contract build, deploy, invoke |
| Node.js | >=18 |
Quake.js SDK and backend |
| pnpm | >=8 |
SDK package management |
| Docker | any | Local Stellar testnet |
| Python | >=3.10 |
Oracle job scripts (optional) |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
cargo install --locked soroban-cligit clone https://github.com/your-org/quake
cd quake
cargo builddocker run --rm -it \
-p 8000:8000 \
stellar/quickstart:latest \
--testnet \
--enable-soroban-rpccargo testquake/
├── contracts/
│ └── quake/
│ ├── src/
│ │ ├── lib.rs # Contract entry point
│ │ ├── policy.rs # PolicyRecord type + storage
│ │ ├── oracle.rs # OracleAggregator logic
│ │ ├── trigger.rs # Trigger evaluation engine
│ │ ├── payout.rs # PayoutEngine
│ │ ├── reserve.rs # ReservePool + LP staking
│ │ ├── premium.rs # PremiumStream module
│ │ ├── events.rs # Event definitions
│ │ ├── errors.rs # QuakeError enum
│ │ └── types.rs # Shared types
│ ├── Cargo.toml
│ └── tests/
│ ├── create_policy.rs
│ ├── oracle_consensus.rs
│ ├── trigger_evaluation.rs
│ ├── payout_execution.rs
│ └── reserve_pool.rs
├── oracle/
│ ├── jobs/
│ │ ├── noaa_rainfall.ts # Acurast job: NOAA rainfall
│ │ ├── flightaware_delay.ts # Acurast job: flight delay
│ │ ├── noaa_hurricane.ts # Acurast job: hurricane wind speed
│ │ └── usgs_earthquake.ts # Acurast job: earthquake magnitude
│ ├── src/
│ │ ├── aggregator.ts # Off-chain aggregation helper
│ │ └── validator.ts # TEE attestation validator
│ └── README.md
├── backend/
│ ├── src/
│ │ ├── routes/
│ │ ├── services/
│ │ ├── models/
│ │ └── middleware/
│ └── package.json
├── frontend/
│ └── src/
├── sdk/
│ └── src/
├── docs/
├── CONTRIBUTING.md
├── README.md
└── LICENSE
Quake uses a standard fork-and-branch workflow.
git clone https://github.com/YOUR_USERNAME/quake
cd quake
git remote add upstream https://github.com/your-org/quakefeat/short-description # new feature
fix/short-description # bug fix
oracle/short-description # oracle job or aggregator change
docs/short-description # documentation only
test/short-description # tests only
refactor/short-description # no behaviour change
Use imperative mood, reference the component in the subject:
# Good
[contract] Add confirmation window to trigger evaluation
[oracle] Add Acurast job for NOAA hourly rainfall
[sdk] Implement createPolicy with trigger config builder
# Bad
fixed oracle stuff
git fetch upstream
git rebase upstream/mainPush and open a PR against main. Use Closes #123 in the description. Fill in the PR template completely.
snake_casefor all functions and variables,PascalCasefor types- Every public function must have a doc comment: purpose, parameters, panics, events emitted
- Use
quake_sdk::panic_with_error!with a typedQuakeError— never barepanic! - Keep public contract functions thin — delegate logic to internal modules
The oracle.rs module is the most security-critical piece of the codebase. Rules that apply specifically here:
- Never modify consensus logic without a corresponding adversarial test
- Every change to
OracleAggregatorrequires review from two maintainers regardless of size - All oracle-related constants (
MIN_SOURCES,DEFAULT_TOLERANCE_PCT,STALENESS_TTL) must be documented with the reasoning behind their default values - Do not add new oracle source types without updating the source registry and reliability scoring logic
All errors must be variants of QuakeError:
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum QuakeError {
PolicyNotFound = 1,
PolicyExpired = 2,
PolicyLapsed = 3,
PolicyAlreadyPaid = 4,
PolicyNotTriggered = 5,
InsufficientReserve = 6,
OracleNotRegistered = 7,
OracleReadingStale = 8,
OracleConsensusFailed = 9,
OracleAttestationInvalid = 10,
ConfirmationWindowActive = 11,
Unauthorised = 12,
InvalidTriggerConfig = 13,
ReserveUndercollateralised = 14,
StakeLockedUp = 15,
}All state-changing functions must emit typed events. Event schemas are public API — once deployed, they are immutable.
The oracle layer is the most unique part of Quake and the area most likely to need contributor attention.
Oracle jobs live in /oracle/jobs/. Each job is a TypeScript script that runs inside an Acurast TEE on mobile hardware. Jobs:
- Fetch data from an external API
- Process and scale the reading to the correct integer format
- Submit the reading to the
OracleAggregatorcontract via a signed Stellar transaction - Produce a TEE attestation proving the script ran unmodified
When writing a new oracle job:
- Scale all values to integers (no floats on-chain). Rainfall in mm × 100, wind speed in km/h × 10, delay in minutes × 1.
- Include the data source URL and fetch timestamp in the submitted reading
- Handle API errors gracefully — a failed fetch should not submit a zero reading
- Test locally using the Acurast simulator before deploying
To add a new data source to an existing vertical:
- Create a new job file in
/oracle/jobs/ - Register the source in the
OracleAggregatorviaregister_oracle_source() - Set an initial
reliability_scoreof 50 (neutral) - Add the source to the vertical's
OracleConfig - Add tests in
contracts/quake/tests/oracle_consensus.rscovering the new source
Reliability scores decay and recover automatically based on oracle behaviour. When evaluating a new data source before adding it:
- Run the source against at least 30 days of historical data
- Compare readings against existing accepted sources
- Document the mean absolute error in the PR description
The Quake.js SDK lives in /sdk and is written in TypeScript with strict mode.
camelCasefor functions and variables,PascalCasefor classes and types- All public methods and types must have JSDoc comments
- Explicit return types on all public API surfaces
- No
any— useunknownand narrow explicitly
cd sdk
pnpm install
pnpm build
pnpm testLive in contracts/quake/tests/. Use the Soroban test environment — no network required.
Every PR touching contract logic must include:
- Happy path test
- All relevant
QuakeErrorvariants - Edge cases (zero amounts, boundary ledgers, oracle threshold boundaries)
- At least one adversarial oracle test (e.g. single oracle submitting false data should not trigger payout)
cargo test -p quakeOracle job tests live in /oracle/jobs/__tests__/. Use mocked HTTP responses.
cd oracle
pnpm testRequire Docker running with a local Stellar testnet.
cargo test --test integrationIntegration tests are required for any change to oracle.rs, trigger.rs, or payout.rs.
Any change to the OracleAggregator must include tests for:
- Single malicious oracle submitting an out-of-band reading (should be rejected)
- All oracles submitting at the same wrong value (should trigger — this is the expected N-of-M behaviour)
- Stale reading detection (reading older than
staleness_ttlshould be rejected) - Attestation failure (TEE attestation mismatch should reject the reading)
cargo testandpnpm testmust pass locally before opening a PR- All PRs require one approving review from a maintainer
- Maintainers may request changes — address with new commits, do not force-push during review
- Maintainers squash-merge approved PRs into
main
- Code compiles without warnings
- All existing tests pass
- New tests added for new behaviour
- Adversarial oracle tests included (if touching oracle layer)
- Doc comments updated for changed public API
- PR description links the issue it resolves
Quake is part of the ecosystem. Built on Stellar and Soroban.