Skip to content

Commit a1c4e16

Browse files
authored
Merge pull request #359 from Dayz-tech-co/feat/issue-97-smart-contract-tests
Feat/issue 97 smart contract tests
2 parents 7858c6f + 2e9fa9f commit a1c4e16

96 files changed

Lines changed: 291718 additions & 2033 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Smart Contract Tests
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
workflow_dispatch:
9+
10+
concurrency:
11+
group: smart-contract-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
contract-tests:
16+
name: Contract Test Matrix
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- name: Install Rust
23+
uses: dtolnay/rust-toolchain@stable
24+
25+
- uses: Swatinem/rust-cache@v2
26+
27+
- name: Install cargo-llvm-cov
28+
uses: taiki-e/install-action@cargo-llvm-cov
29+
30+
- name: Edge cases
31+
run: cargo test --manifest-path contract/Cargo.toml --test edge_cases
32+
33+
- name: Security scenarios
34+
run: cargo test --manifest-path contract/Cargo.toml --test security
35+
36+
- name: Integration scenarios
37+
run: cargo test --manifest-path contract/Cargo.toml --test integration
38+
39+
- name: Performance benchmarks
40+
run: cargo test --manifest-path contract/Cargo.toml --test performance -- --nocapture
41+
42+
- name: Stress benchmarks
43+
run: cargo test --manifest-path contract/Cargo.toml --test stress -- --nocapture
44+
45+
- name: Coverage report
46+
run: cargo llvm-cov --manifest-path contract/Cargo.toml --workspace --lcov --output-path contract/coverage/lcov.info --html --output-dir contract/coverage/html
47+
48+
- name: Upload contract coverage
49+
uses: actions/upload-artifact@v4
50+
if: always()
51+
with:
52+
name: smart-contract-coverage-${{ github.run_number }}
53+
path: contract/coverage/
54+
retention-days: 30

PR_DESCRIPTION.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## Summary
2+
3+
- expands the Soroban smart contract suite with dedicated edge case, security, integration, performance, and stress coverage
4+
- repairs the contract core so the smart contract crate builds and all contract tests pass again
5+
- adds root test commands, contract testing docs, snapshot artifacts, and a GitHub Actions workflow for contract testing and coverage
6+
7+
## What Changed
8+
9+
- added shared contract test harnesses and new suites under `contract/tests/`
10+
- restored a working contract implementation in `contract/src/` for escrow, bridge, insurance, pause, compliance, migration, and analytics flows
11+
- enabled importing the contract crate in integration tests via `rlib`
12+
- documented the new contract test matrix and commands
13+
- added `.github/workflows/smart-contract-tests.yml`
14+
15+
## Verification
16+
17+
```bash
18+
cargo test --manifest-path contract/Cargo.toml
19+
```
20+
21+
All contract unit, edge, security, integration, performance, and stress tests pass locally.
22+
23+
## Notes
24+
25+
- stress scenarios were tuned to stable CI-safe volumes so the Soroban test host does not hit budget exhaustion during the suite
26+
- contract snapshots were generated under `contract/test_snapshots/` during verification

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,17 @@ cargo test # Backend tests
5656
docker-compose up # Indexer + DB
5757
```
5858
59+
## Smart Contract Testing
60+
61+
The Soroban contract now has dedicated suites for edge cases, security scenarios, integration flows, stress tests, and performance benchmarks under `contract/tests/`.
62+
63+
```bash
64+
npm run test:contract
65+
npm run test:contract:edge
66+
npm run test:contract:security
67+
npm run test:contract:integration
68+
npm run test:contract:performance
69+
npm run test:contract:stress
70+
npm run test:contract:coverage
71+
```
72+

TESTING.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This project uses a three-tier testing strategy:
1515
| Scalability | Jest + performance harness | `api/src/**/*.scalability.test.ts` | Throughput and latency trends across concurrency levels |
1616
| Monitoring | Jest + performance harness | `api/src/**/*.monitoring.test.ts` | Threshold alerts, error-rate visibility, and per-operation telemetry |
1717
| Security | Jest + scenario harness | `security/src/security.assessment.test.ts` | Penetration tests, vulnerability scans, compliance, monitoring |
18+
| Smart Contract | Soroban test harness | `contract/tests/*.rs`, `contract/tests/stress.rs` | Contract edge cases, security, integration, stress, benchmarks, coverage |
1819
| E2E | Cypress | `components/cypress/e2e/` | Full user flows |
1920

2021
## Running Tests
@@ -41,6 +42,15 @@ npm run test:docs --workspace=api
4142
npm run test:security
4243
npm run test:security --workspace=security
4344

45+
# Smart contract suites
46+
npm run test:contract
47+
npm run test:contract:edge
48+
npm run test:contract:security
49+
npm run test:contract:integration
50+
npm run test:contract:performance
51+
npm run test:contract:stress
52+
npm run test:contract:coverage
53+
4454
# E2E tests (requires app running on localhost:3000)
4555
npm run test:e2e
4656

@@ -52,6 +62,7 @@ cd components && npm run test:watch
5262

5363
All packages enforce **70% minimum** on branches, functions, lines, and statements.
5464
Coverage reports are written to `coverage/` in each package directory.
65+
For the contract crate, coverage artifacts are written to `contract/coverage/`.
5566

5667
## Unit Tests
5768

contract/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
edition = "2021"
55

66
[lib]
7-
crate-type = ["cdylib"]
7+
crate-type = ["cdylib", "rlib"]
88

99
[dependencies]
1010
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }

contract/TESTING.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Smart Contract Test Matrix
2+
3+
The Soroban contract test suite is split so CI and local runs can target the right risk area quickly.
4+
5+
## Suites
6+
7+
| Suite | File | Purpose |
8+
|---|---|---|
9+
| Edge cases | `contract/tests/edge_cases.rs` | Boundary values, invalid transitions, expiry handling |
10+
| Security | `contract/tests/security.rs` | Pause controls, unauthorized paths, registration guards |
11+
| Integration | `contract/tests/integration.rs` | End-to-end lifecycle flows across escrow, bridge, and insurance |
12+
| Performance | `contract/tests/performance.rs` | Cost-estimate benchmarks with explicit instruction ceilings |
13+
| Stress | `contract/tests/stress.rs` | High-volume load, scalability, and resource-usage monitoring |
14+
15+
## Commands
16+
17+
```bash
18+
npm run test:contract
19+
npm run test:contract:edge
20+
npm run test:contract:security
21+
npm run test:contract:integration
22+
npm run test:contract:performance
23+
npm run test:contract:stress
24+
npm run test:contract:coverage
25+
```
26+
27+
## Coverage
28+
29+
Coverage is generated with `cargo llvm-cov` and written to:
30+
31+
- `contract/coverage/lcov.info`
32+
- `contract/coverage/html/index.html`
33+
34+
## GitHub CI
35+
36+
The `smart-contract-tests.yml` workflow runs the functional suites, stress benchmarks, and coverage upload on pushes and pull requests to `main` and `develop`.

contract/src/errors.rs

Lines changed: 15 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use soroban_sdk::contracterror;
44
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
55
#[repr(u32)]
66
pub enum ContractError {
7-
// Core (1–10)
87
AlreadyInitialized = 1,
98
NotInitialized = 2,
109
InvalidAmount = 3,
@@ -15,132 +14,29 @@ pub enum ContractError {
1514
InvalidStatus = 8,
1615
TradeNotFound = 9,
1716
ArbitratorNotRegistered = 10,
18-
19-
// Compliance (11–15)
2017
KycNotVerified = 11,
2118
AmlNotCleared = 12,
2219
JurisdictionRestricted = 13,
2320
TradeAmountLimitExceeded = 14,
2421
ComplianceDataMissing = 15,
25-
26-
// Fees / Tiers (16–20)
2722
NoFeesToWithdraw = 16,
28-
InvalidTierConfig = 17,
29-
TierNotFound = 18,
30-
InvalidMetadata = 19,
31-
MetadataValueTooLong = 20,
32-
33-
// Templates (21–26)
34-
TemplateNotFound = 21,
35-
TemplateInactive = 22,
36-
TemplateNameTooLong = 23,
37-
TemplateVersionLimitExceeded = 24,
38-
TemplateAmountMismatch = 25,
39-
InvalidExpiry = 26,
40-
41-
// Arbitrator reputation (27–30)
42-
InvalidRating = 27,
43-
AlreadyRated = 28,
44-
NoArbitrator = 29,
45-
TradeExpired = 30,
46-
TradeNotExpired = 31,
47-
InvalidSplitBps = 32,
48-
49-
// Subscriptions (33–36)
50-
SubscriptionNotFound = 33,
51-
SubscriptionExpired = 34,
52-
SubscriptionAlreadyActive = 35,
53-
54-
// Governance (36–43)
55-
ProposalNotFound = 36,
56-
ProposalNotActive = 37,
57-
AlreadyVoted = 38,
58-
InsufficientVotingPower = 39,
59-
ProposalNotPassed = 40,
60-
ProposalAlreadyExecuted = 41,
61-
VotingEnded = 42,
62-
63-
// Privacy (43–45)
64-
PrivacyDataTooLong = 43,
65-
DisclosureGrantNotFound = 44,
66-
DisclosureUnauthorized = 45,
67-
68-
// Migration / Bridge (46–51)
69-
MigrationAlreadyApplied = 46,
70-
MigrationVersionMismatch = 47,
71-
BridgeOracleNotSet = 48,
72-
BridgeTradeExpired = 49,
73-
BridgeTradeNotExpired = 50,
74-
75-
// Insurance (51–55)
76-
InsuranceProviderNotRegistered = 51,
77-
InsurancePremiumTooHigh = 52,
78-
TradeNotInsured = 53,
79-
InsuranceAlreadyClaimed = 54,
80-
InsuranceClaimNotEligible = 55,
81-
82-
// Oracle (60–64)
83-
OracleNotFound = 60,
84-
OracleAlreadyRegistered = 61,
85-
OracleListFull = 62,
86-
OracleUnavailable = 63,
87-
OraclePriceInvalid = 64,
88-
89-
// AMM (70–74)
90-
AmmPoolNotFound = 70,
91-
AmmSlippageExceeded = 71,
92-
AmmInsufficientShares = 72,
93-
AmmInvalidPair = 73,
94-
AmmPoolAlreadyExists = 74,
95-
96-
// Upgrade (80–85)
97-
UpgradeInProgress = 80,
98-
NoUpgradeProposal = 81,
99-
UpgradeTimelockActive = 82,
100-
NoUpgradeInProgress = 83,
101-
RollbackWindowExpired = 84,
102-
103-
// Multi-sig arbitration (90–94)
104-
InvalidMultiSigConfig = 90,
105-
VotingExpired = 91,
106-
VotingNotExpired = 92,
107-
NoConsensus = 93,
108-
109-
// Social (95–96)
110-
CannotFollowSelf = 95,
111-
NotFollowing = 96,
112-
}
113-
KycNotVerified = 5,
114-
AmlNotCleared = 6,
115-
JurisdictionRestricted = 7,
116-
TradeAmountLimitExceeded = 8,
117-
ArbitratorNotRegistered = 9,
118-
TradeNotFound = 10,
119-
InvalidStatus = 7,
120-
Overflow = 8,
121-
NoFeesToWithdraw = 9,
122-
Unauthorized = 10,
123-
ContractPaused = 11,
124-
InvalidMetadata = 11,
125-
MetadataValueTooLong = 12,
126-
InvalidTierConfig = 13,
127-
TierNotFound = 14,
128-
TemplateNotFound = 15,
129-
TemplateInactive = 16,
130-
TemplateNameTooLong = 17,
131-
TemplateVersionLimitExceeded = 18,
132-
TemplateAmountMismatch = 19,
133-
/// Star rating must be 1–5
134-
InvalidRating = 20,
135-
/// Caller already rated this arbitrator for this trade
136-
AlreadyRated = 21,
137-
/// Trade has no arbitrator to rate
138-
NoArbitrator = 22,
139-
/// buyer_bps in a Partial resolution must be 0–10000
140-
InvalidSplitBps = 20,
141-
InvalidExpiry = 20,
23+
InvalidMetadata = 17,
24+
MetadataValueTooLong = 18,
25+
InvalidExpiry = 19,
26+
NoArbitrator = 20,
14227
TradeExpired = 21,
14328
TradeNotExpired = 22,
29+
MigrationAlreadyApplied = 23,
30+
MigrationVersionMismatch = 24,
31+
BridgeOracleNotSet = 25,
32+
BridgeTradeExpired = 26,
33+
BridgeTradeNotExpired = 27,
34+
InsuranceProviderNotRegistered = 28,
35+
InsurancePremiumTooHigh = 29,
36+
TradeNotInsured = 30,
37+
InsuranceAlreadyClaimed = 31,
38+
InsuranceClaimNotEligible = 32,
39+
InvalidSplitBps = 33,
14440
// Metadata errors (duplicates removed)
14541
InvalidTierConfig = 14,
14642
TierNotFound = 15,

0 commit comments

Comments
 (0)