This document outlines essential security practices for both users and developers of the Ajo decentralized savings platform built on Stellar Soroban.
The goal is to ensure safe participation in savings groups (ROSCAs) and secure development of smart contracts and supporting infrastructure.
Ajo is a decentralized financial coordination platform where users contribute funds into rotating savings groups. Because funds are managed on-chain, security is critical.
This guide covers:
- Wallet and user safety
- Smart contract security (Soroban/Rust)
- Backend/API security
- Frontend security considerations
- Operational best practices
- Always use trusted wallets such as Freighter
- Never share your private key or seed phrase
- Store recovery phrases offline (not in screenshots or cloud storage)
- Use hardware wallets where possible
- Only access the application through official URLs
- Do not click unknown links claiming rewards or urgent actions
- Always verify transaction prompts in your wallet before signing
-
Carefully review:
- Contribution amounts
- Recipient addresses
- Contract interactions
-
Do not approve transactions without understanding them
- Keep your operating system and browser updated
- Avoid using public or shared computers for transactions
- Install only trusted browser extensions
- Join savings groups with trusted participants
- Understand group rules before committing funds
- Be cautious of unusually high contribution expectations or promises
- Validate all external inputs
- Ensure contribution amounts are greater than zero
- Enforce member limits
- Check metadata length bounds
- Avoid using panic in production logic
- Return deterministic and well-defined errors instead
-
Restrict sensitive functions such as:
- Fund distribution
- Dispute resolution
- Administrative actions
-
Use explicit role-based checks (e.g., admin vs member)
- Ensure contributions are recorded before distribution
- Prevent double withdrawals
- Ensure voting results cannot be altered after finalization
- Use safe arithmetic practices
- Prevent overflow and underflow conditions
-
Emit structured events for:
- Contributions
- Payouts
- Disputes
-
This improves auditability and off-chain tracking
-
Write unit tests for all logic paths
-
Test edge cases including:
- Zero or invalid inputs
- Maximum group sizes
- Dispute edge cases
-
Include invariant tests to ensure:
- Funds are neither created nor destroyed unexpectedly
- Be aware of execution limits (budget/gas)
- Avoid expensive loops over large datasets
- Prefer predictable and bounded execution paths
- Validate all contract invocations from backend services
- Never commit .env files to version control
- Store secrets using a secure secrets manager
- Rotate keys periodically
-
Use security middleware such as:
- helmet for HTTP headers
- cors with strict origin control
-
Disable unnecessary headers
- Validate all API inputs using a schema validation library such as Zod
- Reject malformed or unexpected data
-
Implement rate limiting to prevent abuse
-
Protect endpoints such as:
- Group creation
- Dispute filing
- Voting
-
Ensure only authorized users can:
- Trigger contract interactions
- Access sensitive data
-
Do not rely solely on client-side validation
- Validate contract responses before processing
- Handle RPC failures gracefully
- Do not blindly trust on-chain data without checks
- Use only NEXT_PUBLIC variables for non-sensitive data
- Never expose private keys or secrets in frontend code
- Avoid rendering raw HTML directly
- Sanitize user-generated content
- Use HTTPS in production
- Validate API responses before rendering
-
Avoid storing sensitive data in:
- localStorage
- sessionStorage
-
Clearly display:
- Transaction amounts
- Actions (contribute, withdraw, vote)
-
Prevent duplicate submissions and accidental clicks
- Ensure votes are immutable after submission
- Prevent double voting
- Restrict administrative override capabilities
- Log all arbitration actions transparently
- Audit contracts before mainnet deployment
- Verify compiled WASM matches source code
- Use testnet extensively before production deployment
- Enforce HTTPS across all services
- Enable firewall and DDoS protection
- Monitor logs for suspicious activity
-
Run:
- Lint checks
- Type checks
- Contract tests
-
Prevent insecure code from being merged
-
Monitor:
- Failed transactions
- Unusual activity patterns
-
Set up alerting for:
- Backend errors
- Contract failures
-
Regularly update dependencies
- Hardcoding secrets
- Trusting unvalidated user input
- Skipping contract tests
- Ignoring edge cases
- Weak access control
- Poor error handling
- Stellar and Soroban documentation
- OWASP Top 10 (Web Security Risks)
- Rust secure coding guidelines
Security in Ajo follows a shared responsibility model:
- Users must protect their wallets and verify actions
- Developers must write secure contracts and APIs
- Operators must maintain secure infrastructure
Following these practices helps ensure the platform remains secure, transparent, and reliable for all participants.