cycle 1 shipped: 14 fixes across trading, points, and referrals
two days ago we published the most thorough audit in parasol's history — 10 parallel deep-dives, 67 findings, a full project management framework.
today we're shipping the first batch. 14 fixes across 3 deploys, covering the systems that matter most: trade execution, position management, gamification, and referrals.
here's exactly what changed and why.
---
trading engine
cold-start position recovery
the problem: when the server restarted, open positions lost their take-profit levels, trailing stops, and high water marks. positions would fall back to a basic 8% stop loss with no profit-taking — completely ignoring the exit strategy that was active before the restart.
the fix: we added three new columns to the trades table (trailing_stop_price, high_water_mark, take_profit_levels) and updated every insert and close path to persist this data. on cold start, positions now restore with their full exit strategy intact.
if you had a position with a trailing stop at +35% and three TP levels, and the server restarted — that position now comes back exactly as it was.
kill switch persistence
the problem: if the daily loss limit triggered the kill switch and then the server restarted, the kill switch state was lost. the agent would start trading again, violating the risk control.
the fix: kill switch state is now restored from the database on cold start. if your agent hit the daily loss limit before a restart, it stays stopped.
budget cap on cold start
the problem: the cumulative spend tracker (how much SOL the agent has spent today) was loaded from the database inside a price-fetching function. if the price was cached, the budget never loaded — meaning the agent could exceed its daily budget after a restart.
the fix: budget state now loads at the top of every live trade attempt, before any other logic runs. the cap is always enforced from the first trade.
live sell from the dashboard
the problem: clicking "Sell" on a live position only updated the client-side state. the tokens were never actually sold on-chain. the position would disappear from the UI but the tokens would remain in your wallet.
the fix: the sell button now calls the trading API first, waits for the on-chain transaction to confirm, and only then removes the position from the UI. if the sell fails, the position stays visible and you can retry. paper trading sells still work instantly — no API call needed.
jito timeout recovery
the problem: jito bundle confirmation has a 60-second polling window. if the bundle landed at second 64, the system marked the trade as failed. next cycle, the agent would try to buy the same token again — creating a duplicate position.
the fix: after a timeout, we now check the wallet's token balance before reporting failure. if tokens are present, we treat the buy as successful. this prevents duplicate positions from late-landing bundles. the same check was added to the jupiter direct path.
position sell mutex
the problem: if a take-profit level and a trailing stop triggered at the same time, two sell transactions could fire simultaneously for the same position.
the fix: a simple mutex prevents concurrent sell attempts on the same position. the first one executes; the second is blocked with a log message. the mutex releases automatically when the sell completes (or fails).
server-side buy amount validation
the problem: the baseBuySol parameter was accepted from the client without server-side validation. while there was a downstream cap at 0.5 SOL, the API boundary had no explicit check.
the fix: buy amounts are now clamped to 0.001–5.0 SOL at the API level, before reaching any trading logic. combined with the existing 0.5 SOL downstream cap, this provides two layers of protection.
---
points and gamification
first trade quest accuracy
the problem: the "Execute First Trade" quest (150 points) was triggering on paper trades. the quest description says "start a live agent and let it execute your first real trade" — paper trades shouldn't count.
the fix: the quest now only completes on the first live trade. paper trades still award their normal 10-point trade-opened bonus, but don't trigger the quest.
profitable trade daily cap
the problem: profitable trade points (25 for paper, 50 for live) had no daily limit. a user could farm points by rapidly opening and closing small profitable positions.
the fix: a daily cap of 3 profitable trade awards now applies. that's 75 points/day from paper profitable trades or 150 points/day from live. the cap resets at UTC midnight. trade-opened points already had a daily cap of 20 — now profitable trades have one too.
PnL milestones actually work
the problem: three PnL-based milestones (first profitable day: 100pts, +10% overall gain: 250pts, +50% overall gain: 1000pts) could never be earned. the milestone check was called with totalPnlPercent: 0 and hasProfitableDay: false hardcoded.
the fix: milestone checks now compute real PnL data from your actual trade history. total invested, total returned, and whether you've had a profitable trade — all calculated from your closed trades in the database.
---
referrals
schema validation tightened
the problem: the API accepted referral codes up to 20 characters, but the database column only allows 10. codes between 11-20 characters would be accepted by validation but rejected by the database — a confusing error.
the fix: API validation now matches the database limit: 3-10 characters. auto-generated codes are 9 characters (ROLEX + 4 random), so no existing codes are affected.
claim documentation fixed
the problem: the code comment said "minimum claim: 0.01 SOL" but the actual code enforced 0.05 SOL. the error message was correct, but the source code comment was misleading.
the fix: comment updated to match the code. minimum claim is 0.05 SOL.
---
infrastructure
budget reset safety
the problem: the budget reset endpoint (reset_budget) worked in both live and paper mode. in paper mode, there's no cumulative budget to reset — it was a no-op but could confuse monitoring.
the fix: budget reset now only executes in live mode. in paper mode, it returns success without doing anything — no 403 error, just a clean no-op.
---
what's next
this was the first batch from cycle 1 of our improvement sprint. two tasks remain before we move to cycle 2:
cycle 2 focuses on revenue accuracy, referral commission tiers, and database-level access policies.
we'll keep shipping updates at the end of each cycle. every change gets audited before deploy — two parallel reviews (technical + user perspective) with a full type check.
less noise. more alpha.