Skip to content
Merged
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
84 changes: 84 additions & 0 deletions .github/workflows/contracts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Contracts CI

on:
push:
branches: [main, develop]
paths:
- 'contracts/**'
- '.github/workflows/contracts.yml'
pull_request:
branches: [main, develop]
paths:
- 'contracts/**'
- '.github/workflows/contracts.yml'

jobs:
test-contracts:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
components: clippy, rustfmt
override: true

- name: Cache Cargo registry
uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
contracts/target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Run cargo test
working-directory: contracts/contracts/boxmeout
run: cargo test --features testutils

- name: Run cargo clippy
working-directory: contracts/contracts/boxmeout
run: cargo clippy --all-targets --features testutils -- -D warnings

- name: Check formatting
working-directory: contracts/contracts/boxmeout
run: cargo fmt -- --check

- name: Build WASM contracts
working-directory: contracts/contracts/boxmeout
run: cargo build --release --target wasm32-unknown-unknown

- name: List WASM artifacts
run: |
ls -lh contracts/target/wasm32-unknown-unknown/release/*.wasm
find contracts/target -name "*.wasm" -type f

- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin

- name: Generate test coverage
working-directory: contracts/contracts/boxmeout
run: cargo tarpaulin --features testutils --out Xml --output-dir coverage

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: contracts/contracts/boxmeout/coverage/cobertura.xml
flags: contracts
name: contract-coverage
fail_ci_if_error: false

- name: Upload WASM artifacts
uses: actions/upload-artifact@v4
with:
name: contract-wasm
path: contracts/target/wasm32-unknown-unknown/release/boxmeout.wasm
retention-days: 7
Empty file modified check-all.sh
100644 → 100755
Empty file.
19 changes: 15 additions & 4 deletions contracts/contracts/boxmeout/src/market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ pub struct PredictionMarket;
#[contractimpl]
impl PredictionMarket {
/// Initialize a single market instance
#[allow(clippy::too_many_arguments)]
pub fn initialize(
env: Env,
market_id: BytesN<32>,
Expand Down Expand Up @@ -1123,10 +1124,20 @@ impl PredictionMarket {
.set(&Symbol::new(&env, MARKET_STATE_KEY), &STATE_CANCELLED);

let timestamp = env.ledger().timestamp();
env.events().publish(
(Symbol::new(&env, "MarketCancelled"),),
(market_id, creator, timestamp),
);

#[contractevent]
pub struct MarketCancelledEvent {
pub market_id: BytesN<32>,
pub creator: Address,
pub timestamp: u64,
}

MarketCancelledEvent {
market_id,
creator,
timestamp,
}
.publish(&env);
}

// --- TEST HELPERS (Not for production use, but exposed for integration tests) ---
Expand Down
27 changes: 17 additions & 10 deletions contracts/contracts/boxmeout/src/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,16 +948,23 @@ impl OracleManager {
.set(&Symbol::new(&env, LAST_OVERRIDE_TIME_KEY), &current_time);

// 12. Emit EmergencyOverride event with all details
env.events().publish(
(Symbol::new(&env, "EmergencyOverride"),),
(
market_id,
forced_outcome,
justification_hash,
approvers,
current_time,
),
);
#[contractevent]
pub struct EmergencyOverrideEvent {
pub market_id: BytesN<32>,
pub forced_outcome: u32,
pub justification_hash: BytesN<32>,
pub approvers: Vec<Address>,
pub timestamp: u64,
}

EmergencyOverrideEvent {
market_id,
forced_outcome,
justification_hash,
approvers,
timestamp: current_time,
}
.publish(&env);
}

/// Get emergency override record for a market (for audit purposes)
Expand Down
1 change: 1 addition & 0 deletions contracts/contracts/boxmeout/tests/factory_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ fn register_factory(env: &Env) -> Address {
}

// Helper to create a mock USDC token
#[allow(dead_code)]
fn create_mock_token(env: &Env, admin: &Address) -> Address {
let token_address = env.register_stellar_asset_contract_v2(admin.clone());
token_address.address()
Expand Down
7 changes: 3 additions & 4 deletions contracts/contracts/boxmeout/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ fn test_complete_prediction_flow() {
let admin = Address::generate(&env);
let usdc_token = Address::generate(&env);
let _creator = Address::generate(&env);
let user1 = Address::generate(&env);
let user2 = Address::generate(&env);
let _user1 = Address::generate(&env);
let _user2 = Address::generate(&env);

// Step 2: Initialize all contracts
factory_client.initialize(&admin, &usdc_token, &treasury_id);
Expand Down Expand Up @@ -120,8 +120,7 @@ fn test_complete_prediction_flow() {
// let platform_fees = treasury_client.get_platform_fees();
// assert!(platform_fees > 0);

// Verify complete flow succeeded
assert!(true); // Placeholder until functions implemented
// Verify complete flow succeeded - test passes if no panics occurred
}

/// Integration test: Market creation and AMM trading flow
Expand Down
10 changes: 5 additions & 5 deletions contracts/contracts/boxmeout/tests/market_test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg(test)]

use boxmeout::market::{MarketError, MarketState, PredictionMarketClient};
use boxmeout::market::{MarketError, PredictionMarketClient};
use soroban_sdk::{
testutils::{Address as _, Ledger, LedgerInfo},
token, Address, BytesN, Env, Symbol,
Expand Down Expand Up @@ -156,7 +156,7 @@ fn test_market_initialize() {
#[test]
fn test_commit_prediction_happy_path() {
let env = create_test_env();
let (client, _market_id, _creator, admin, usdc_address, _market_contract) =
let (client, _market_id, _creator, _admin, usdc_address, _market_contract) =
setup_test_market(&env);

// Setup user with USDC balance
Expand Down Expand Up @@ -205,7 +205,7 @@ fn test_commit_prediction_happy_path() {
#[test]
fn test_commit_prediction_duplicate_rejected() {
let env = create_test_env();
let (client, _market_id, _creator, admin, usdc_address, _market_contract) =
let (client, _market_id, _creator, _admin, usdc_address, _market_contract) =
setup_test_market(&env);

let user = Address::generate(&env);
Expand Down Expand Up @@ -271,7 +271,7 @@ fn test_commit_prediction_negative_amount_rejected() {
#[test]
fn test_multiple_users_commit() {
let env = create_test_env();
let (client, _market_id, _creator, admin, usdc_address, _market_contract) =
let (client, _market_id, _creator, _admin, usdc_address, _market_contract) =
setup_test_market(&env);

let token = token::StellarAssetClient::new(&env, &usdc_address);
Expand Down Expand Up @@ -912,5 +912,5 @@ fn test_get_market_state_serializable() {
let _winning_outcome = state.winning_outcome;

// If we got here, the struct is properly serializable
assert!(true);
// Verification complete
}
Loading