| Version | Supported |
|---|---|
| mainnet (current) | Yes |
| testnet | Best-effort |
If you discover a security vulnerability in TipStream, please report it responsibly:
- Do not open a public issue.
- Email security@tipstream.app (or DM @Mosas2000 on GitHub) with:
- A description of the vulnerability.
- Steps to reproduce.
- Potential impact.
- You will receive an acknowledgment within 48 hours.
- A fix will be prioritized based on severity and deployed as soon as practical.
The following assets are in scope:
- Smart contracts deployed under
SP31PKQVQZVZCK3FM3NH67CGD6G1FMR17VQVS2W5T. - The TipStream frontend hosted at
https://tipstream.xyzand on Vercel. - Deployment scripts and configuration in this repository.
- Smart contract upgrade strategy and migration procedures.
- Frontend post-condition enforcement logic.
Out of scope:
- Third-party services (Hiro API, wallet extensions, Vercel infrastructure).
- Social engineering attacks.
- Denial-of-service attacks against public infrastructure.
- Private mnemonics or keys (report via secure channels, not as issues).
| Area | Status | Last Review | Notes |
|---|---|---|---|
| Smart Contract | Undergone review | Deployment | Timelock bypass documented |
| Post-Conditions | Audited | Current | CI enforces deny mode |
| Frontend Validation | Reviewed | Current | Client-side checks + contract validation |
| Credential Management | Secure | Current | gitleaks + .gitignore + hooks |
| Dependencies | Audited | Monthly | npm audit in CI |
| Documentation | Current | March 2026 | Audit complete, drift signals resolved |
The deployed TipStream contract has both direct and timelocked admin functions. The direct
functions (set-paused, set-fee-basis-points) can bypass the 144-block timelock. This is
documented in docs/TIMELOCK-BYPASS-AUDIT.md and mitigated
through frontend controls and operational policies.
Administrative changes use a 144-block (~24 hour) delay:
| Operation | Timelocked Function | Direct Bypass |
|---|---|---|
| Pause/Unpause | propose-pause-change / execute-pause-change |
set-paused |
| Fee Change | propose-fee-change / execute-fee-change |
set-fee-basis-points |
The frontend AdminDashboard exclusively uses the timelocked functions. Direct bypass functions are reserved for documented emergencies only.
The contract now provides cancel-pause-change to explicitly cancel pending pause proposals.
This mirrors the existing cancel-fee-change function and provides operational symmetry.
When a pause proposal is submitted in error, operators can cancel it explicitly rather than
wait for the timelock to expire or overwrite it with a new proposal.
All STX transfers enforce PostConditionMode.Deny to prevent transactions from moving
more STX than explicitly authorized. See the post-condition documentation for details.
Contract ownership uses a two-step process (propose-new-owner / accept-ownership)
to prevent accidental transfers.
The contract enforces a maximum fee of 1000 basis points (10%). The current fee is 50 basis points (0.5%).
Tips below 1000 microSTX (0.001 STX) are rejected to prevent dust spam.
- All admin functions require
tx-senderto be the contract owner. - Ownership transfer uses a two-step propose/accept pattern.
- Fee changes are bounded (maximum 10%, i.e. 1000 basis points).
- The
set-pausedfunction has a timelock: a pause/unpause must be proposed and can only execute after a delay measured in blocks. - Post conditions on every state-changing transaction restrict STX movement to the exact expected amounts.
- Self-tipping is rejected at the contract level.
- Blocked users cannot receive tips from the blocker.
- Wallet authentication is handled entirely by
@stacks/connect. TipStream never sees or stores private keys. - All contract calls use
PostConditionMode.Denyto enforce explicit post conditions. - Read-only queries go through the Hiro REST API with no write capability.
- Mainnet and testnet mnemonics must never be committed to version
control. The
.gitignoreexcludessettings/Mainnet.tomlandsettings/Testnet.toml. - Template files (
*.toml.example) are committed with placeholder values only. - The
scripts/test-contract.cjsscript reads its mnemonic from theMNEMONICenvironment variable, never from a config file. - A gitleaks configuration (
.gitleaks.toml) and a pre-commit hook (scripts/hooks/pre-commit) are provided to catch accidental secret commits before they reach the remote. - GitHub Actions runs a secret scan on every push and pull request.
The settings/Devnet.toml file contains mnemonic phrases and private keys for Clarinet
devnet test accounts. These are sandbox-only credentials with no real value. Never use
devnet mnemonics or keys on mainnet or testnet.
If you believe a mnemonic has been exposed (accidentally committed, shared in a log, or otherwise leaked):
- Stop using the compromised mnemonic immediately.
- Generate a new mnemonic using a trusted BIP-39 tool or hardware wallet.
- Transfer all remaining funds from the compromised address to a new address derived from the fresh mnemonic.
- If the compromised key is the contract deployer:
- Use
propose-new-ownerto initiate an ownership transfer to the new address. - From the new address, call
accept-ownershipto complete the transfer.
- Use
- Update
settings/Mainnet.toml(local only) and any CI/CD secrets with the new mnemonic. - Audit recent transactions on the compromised address for unauthorized activity.
- If the mnemonic was pushed to a public repository, consider using
git filter-repoor BFG Repo-Cleaner to remove the commit from history, then force-push. All collaborators must re-clone.
- Frontend dependencies are audited with
npm auditin CI - Stacks SDK versions are pinned to prevent supply-chain attacks
- Contract interactions use explicit post conditions
- Never commit mainnet private keys or seed phrases
- Use
PostConditionMode.Denyfor all contract calls - Validate all user inputs before contract interaction
- Use timelocked admin functions in the frontend
- Run
npm auditbefore submitting PRs - Test contract changes on simnet before deployment
| Role | Contact |
|---|---|
| Maintainer | @Mosas2000 |
| Security Reports | security@tipstream.app |
We appreciate responsible disclosure. Contributors who report valid vulnerabilities will be credited in the changelog unless they prefer anonymity.