Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,41 @@ jobs:
cache-on-failure: true
- name: cargo check --target wasm32v1-none (contracts)
run: cargo check ${{ env.CONTRACTS }} --target wasm32v1-none

audit:
name: Security audit
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
cache: false
- name: Cache cargo registry and target
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Install cargo-audit
run: cargo install cargo-audit --locked
- name: make audit
run: make audit

deny:
name: Dependency policy
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
cache: false
- name: Cache cargo registry and target
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Install cargo-deny
run: cargo install cargo-deny --locked
- name: make deny
run: make deny
36 changes: 36 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Contributing

Thanks for helping improve OrbitChain. This guide covers the local checks contributors should run before opening a pull request.

## Prerequisites

- Rust stable toolchain, managed by `rust-toolchain.toml`
- `wasm32v1-none` target for Soroban contract builds
- Soroban/Stellar CLI for deployment workflows
- Security scan tools:

```bash
cargo install cargo-audit --locked
cargo install cargo-deny --locked
```

## Local Workflow

```bash
make fmt
make lint
make test
make audit
make deny
```

`make audit` checks dependencies with `cargo-audit`. `make deny` checks license and dependency policy with `cargo-deny`.

If either security tool is missing, the Makefile prints the exact `cargo install ... --locked` command and exits with a non-zero status before running the scan.

## Pull Request Checklist

- [ ] Run formatting, linting, and tests for the touched crates.
- [ ] Run `make audit` and `make deny`, or explain why they were not run.
- [ ] Update README or contract docs when behavior, commands, or contributor workflow changes.
- [ ] Call out security-sensitive changes, especially auth, signatures, fund movement, or dependency policy updates.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ soroban-sdk = { version = "26.0.1" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
dotenv = "0.15"
dotenvy = "0.15"
common = { package = "orbitchain-common", path = "common" }
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,20 @@ deploy-testnet: build-wasm

# Run cargo-audit for vulnerability scanning
audit:
@if ! command -v cargo-audit >/dev/null 2>&1; then \
echo "❌ cargo-audit not installed. Run 'cargo install cargo-audit --locked' then retry." >&2; \
exit 1; \
fi
@echo "🔒 Running security audit..."
cargo audit
@echo "✅ Security audit passed"

# Run cargo-deny for license compliance
deny:
@if ! command -v cargo-deny >/dev/null 2>&1; then \
echo "❌ cargo-deny not installed. Run 'cargo install cargo-deny --locked' then retry." >&2; \
exit 1; \
fi
@echo "📋 Checking license compliance..."
cargo deny check
@echo "✅ License check passed"
Expand All @@ -112,5 +120,7 @@ help:
@echo " make sandbox-start - Start local Stellar sandbox (requires Docker)"
@echo " make deploy-sandbox - Deploy contract to local sandbox"
@echo " make deploy-testnet - Deploy contract to Stellar testnet"
@echo " make audit - Run cargo-audit vulnerability scan"
@echo " make deny - Run cargo-deny policy checks"
@echo " make optimize - Optimize WASM with wasm-opt -Oz"
@echo " make help - Show this help message"
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,13 @@ This project uses `cargo-audit` and `cargo-deny` to maintain high security stand

### Local Scans

Install the scan tools before running the Makefile targets:

```bash
cargo install cargo-audit --locked
cargo install cargo-deny --locked
```

You can run the security scans locally using the following commands:

- **Check for vulnerabilities**:
Expand Down Expand Up @@ -507,6 +514,8 @@ If a license or ban policy violation is found:

Security scans are automatically run on every push and pull request. CI will fail if any known vulnerabilities or policy violations are detected.

The CI workflow installs `cargo-audit` and `cargo-deny` before invoking `make audit` and `make deny`, so missing binaries fail with the same actionable message contributors see locally.

# 📜 License

MIT License — free to use, modify, and distribute.
Expand Down
2 changes: 2 additions & 0 deletions campaign/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
name = "orbitchain-campaign"
version = "0.1.0"
edition = "2021"
license = "MIT"
publish = false
description = "OrbitChain campaign smart contract — milestones, donations, refunds, and lifecycle"

[lib]
Expand Down
2 changes: 2 additions & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
name = "orbitchain-common"
version = "0.1.0"
edition = "2021"
license = "MIT"
publish = false
description = "OrbitChain common types — shared CampaignStatus, MilestoneStatus, AssetInfo, and ErrorCode"

[lib]
Expand Down
2 changes: 2 additions & 0 deletions crates/contracts/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name = "orbitchain-core"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license = "MIT"
publish = false
description = "Legacy OrbitChain campaign reference contract; canonical implementation lives in orbitchain-campaign"

[lib]
Expand Down
4 changes: 3 additions & 1 deletion crates/tools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name = "orbitchain-tools"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license = "MIT"
publish = false
description = "OrbitChain CLI tools — key management, signing, asset issuing, and payment processing"

[[bin]]
Expand All @@ -15,7 +17,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
tokio = { version = "1.0", features = ["rt", "macros", "time"] }
anyhow = { workspace = true }
dotenv = { workspace = true }
dotenvy = { workspace = true }
toml = "0.8"
aes-gcm = "0.10"
rand = "0.8"
Expand Down
2 changes: 1 addition & 1 deletion crates/tools/src/asset_issuing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct TrustlineConfig {

impl AssetConfig {
pub fn from_env() -> Result<Self> {
dotenv::dotenv().ok();
dotenvy::dotenv().ok();

let code = env::var("ASSET_CODE")
.unwrap_or_else(|_| "ORBIT".to_string());
Expand Down
2 changes: 1 addition & 1 deletion crates/tools/src/encrypted_vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl EncryptedVault {
/// Load vault configuration from .env file
#[must_use]
pub fn from_env() -> Result<Self> {
dotenv::dotenv().ok();
dotenvy::dotenv().ok();

// Try to get master password from environment
let master_password = env::var("VAULT_MASTER_PASSWORD")
Expand Down
2 changes: 1 addition & 1 deletion crates/tools/src/environment_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl EnvironmentConfig {
}

pub fn from_env() -> Result<Self> {
dotenv::dotenv().ok();
dotenvy::dotenv().ok();

let network = env::var("SOROBAN_NETWORK").unwrap_or_else(|_| "testnet".to_string());

Expand Down
2 changes: 1 addition & 1 deletion crates/tools/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ mod withdrawal_audit;
mod withdrawal_limits;

fn main() -> Result<()> {
dotenv::dotenv().ok();
dotenvy::dotenv().ok();

let args: Vec<String> = env::args().collect();

Expand Down
2 changes: 1 addition & 1 deletion crates/tools/src/secure_vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct SecureVault {
impl SecureVault {
#[must_use]
pub fn from_env() -> Self {
dotenv::dotenv().ok();
dotenvy::dotenv().ok();

Self {
admin_secret_key: env::var("SOROBAN_ADMIN_SECRET_KEY").ok(),
Expand Down
55 changes: 55 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# cargo-deny configuration
# Run `cargo deny check` to verify license compliance

[advisories]
# Advisories to ignore (after review)
ignore = []
# How to handle yanked crates: deny, warn (default), or allow
yanked = "warn"
# How to handle unmaintained advisories: all, workspace, transitive, none
unmaintained = "workspace"
# How to handle unsound advisories: all, workspace (default), transitive, none
unsound = "workspace"
# Warn about unused ignored advisories
unused-ignored-advisory = "warn"

[licenses]
# List of allowed licenses.
# See https://spdx.org/licenses/ for full list.
allow = [
"MIT",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-2-Clause",
"BSD-3-Clause",
"Unicode-3.0",
"Unlicense",
"Zlib",
]
# Confidence threshold for license detection (0.0 - 1.0)
confidence-threshold = 0.8
# Warn about unused allowed licenses
unused-allowed-license = "warn"

# Specific exceptions for crates that need additional licenses
# [[licenses.exceptions]]
# allow = ["License-Id"]
# crate = "crate-name"

[bans]
# Specific crates that are banned
deny = [
# Example: { name = "openssl", reason = "Using rustls instead" },
]
# Skip these specific crates from being checked
skip = []
# Skip entire trees
skip-tree = []

[sources]
# Only allow crates from crates.io by default
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
# Deny unknown registries
unknown-registry = "deny"
# Deny git sources unless explicitly allowed
unknown-git = "deny"
2 changes: 2 additions & 0 deletions token-bridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
name = "orbitchain-token-bridge"
version = "0.1.0"
edition = "2021"
license = "MIT"
publish = false
description = "OrbitChain cross-chain token bridge contract"

[lib]
Expand Down