August 6, 2026
Superteam CTF v2: A Beginner’s Journey into Solana Security
Introduction

By Akash Jana
21 min read
Introduction
When I first registered for Superteam CTF v2, I had absolutely no idea what to expect.
This was my first ever Capture The Flag (CTF). I'd never attended one before, never solved CTF-style challenges and honestly had no clue what the format would even look like. Would it be smart contract exploits? Cryptography? Reverse engineering? Everything felt like a giant question mark.
What made it even funnier was that I travelled all the way from Mumbai to Bengaluru just for this event. A lot of people asked me,
"You came from Mumbai just for a few hours of CTF?"
My answer was always the same. Why not?
I enjoy exploring. Whether it's visiting a new city, meeting people who are passionate about the same things, or learning something completely outside my comfort zone, I think those experiences are worth far more than the traveling price. Even if I walked away without solving every challenge, I'd still come back having learned something new.
That mindset is probably the biggest reason I decided to attend.
While preparing for the event, I tried searching for previous participants' experiences. I wanted to know what the challenges were like, what I should revise, how difficult the event was, or even what I should expect on the day.
I couldn't find much!
There were no detailed write-ups, no blogs documenting the experience, and very little information beyond the event announcement itself.
So I decided to write the blog I wish I'd found before attending.
This isn't a walkthrough or a collection of flags. Instead, it's a record of what each challenge was trying to teach, the mistakes I made along the way, and the Solana concepts I learned because of them.
Hopefully, if Superteam CTF v3 happens, someone preparing for their first CTF can read this beforehand and walk in with a much better idea of what to expect than I did.
Because trust me, walking into your first CTF completely blind is… an experience.
With that, let's rewind to the morning of July 26, when I walked into my very first CTF with nothing but a laptop, a lot of curiosity, and absolutely no idea what the next six hours had in store.
About Superteam CTF v2
Superteam CTF v2 consisted of ten independent challenges, each covering a different part of the Solana ecosystem.
Rather than focusing on a single topic like smart contract auditing, the event exposed participants to a wide variety of concepts, including:
- Linux and SSH
- SPL Tokens
- Program Derived Addresses (PDAs)
- Transaction signatures
- Native SBF programs
- WebAuthn and Passkeys
- Transaction inspection
- Cryptography
- Reverse engineering
Every challenge felt like a small puzzle with very little guidance. Most of the descriptions were intentionally vague, often just a single sentence.
That meant there was only one way forward:
- Open the terminal.
- Start experimenting.
- Read every error carefully.
- Repeat until something finally clicks.
My Setup
Almost everything I did during the event revolved around the terminal.
Some of the tools I used throughout the competition were: Solana CLI, Rust, TypeScript, spl-token , curl , jq , ffprobe , llvm-objdump
One thing I quickly learned was that blindly trying random commands rarely helps.
Challenge 1: Last Stop
The first challenge immediately caught me off guard. Instead of asking me to interact with a Solana program or sign a transaction, it simply handed me SSH credentials & the session logged out every 5 mins.
At first glance, this looked like a terminal adventure game. Instead of writing code, we had to interact with a virtual subway station using commands like:
The station consisted of five locations: Lost & Found, Fare Kiosk, Signal Room, Grand Central & Red Line Gate
Our objective was to open the Red Line.
Step 1: Collect the transit cards
At Lost & Found, we could collect three transit cards: Blue card, Green card & Airport card
Step 2: Generate candidate PDAs
Next, at the Fare Kiosk, we could purchase tickets using different combinations of those cards. Each combination produced a different Program Derived Address (PDA).
At this point it became obvious that the challenge wasn't about navigating the station at all. It was about understanding that changing the PDA seeds results in an entirely different PDA.
Step 3: Replay the reader
Finally, the Signal Room allowed us to replay the gate reader.
By trying different combinations of the transit cards as PDA seeds, we could observe which PDA the Red Line gate expected. When the correct seed combination was replayed, the generated PDA matched the gate's expected PDA, allowing the Red Line to open.
Whenever the PDA didn't match, the gate responded with:
which was the biggest clue that the problem revolved around PDA derivation rather than the transit cards themselves.
What I learned
Although this challenge looked like a puzzle game, it was actually teaching one of the most fundamental concepts in Solana:
- A PDA is deterministically generated from a set of seeds, a program ID, and a bump seed.
- Changing even one seed produces a completely different PDA.
- Programs often validate that the PDA supplied by the client matches the PDA they derive internally. If they don't match, the instruction fails.
It was a clever way of introducing PDAs without making us write a single line of code. Instead of reading documentation, we learned the concept by experimenting until the correct seed combination produced the expected address.
Challenge 2: Player Two
"One cabinet is reserved for you."
Disclaimer: Since this was my first solved challenge and I completed it pretty quickly, I don't remember every detail of the solution neither have any screenshots of it. Rather than trying to reconstruct every step from memory, I'll focus on the core idea and what I learned from it.
The arcade theme made this challenge feel much lighter than the others, but the lesson behind it was surprisingly important.
At first, I assumed I needed to initialize everything from scratch. Like most blockchain applications, I expected every player to have their own isolated state.
That assumption turned out to be wrong.
The challenge revolved around the idea that a previous player's account was still present on-chain. Instead of creating a fresh account, I had to investigate transactions from earlier participants and understand how the program managed its state.
This was my first reminder that blockchain state is public.
Anyone can inspect transactions, account data, and program interactions using explorers like Solscan. The interesting question isn't whether that data is visible. It's whether the program correctly verifies who is allowed to use it.
The challenge highlighted an important security principle.
An initialized account is not automatically a valid account.
A Solana program should never trust an account simply because it already exists. It must also verify that the account belongs to the correct authority and that the current signer is actually authorized to interact with it.
Without those checks, another user may be able to reuse state left behind by someone else.
Although the challenge was presented as an arcade game with two players, it was really teaching one of the most fundamental ideas in Solana security:
Always validate ownership and authority, not just account existence.
Challenge 3: After Hours
"The night desk is open."
This was the first challenge where I had to properly interact with the Solana ecosystem. The objective looked simple: pay an invoice using SPL tokens. I assumed it would just be a matter of transferring the requested amount.
What followed was a series of failed transactions,error messages and a much deeper understanding of how SPL tokens actually work.
My debugging journey
The first few attempts failed because my wallet didn't even have the required Associated Token Account (ATA). Unlike SOL, SPL tokens require a separate token account for each mint, so creating the ATA became the first step.
Once that was fixed, I ran into balance-related issues and eventually invoice validation errors. The program kept rejecting my payment even though I believed I had transferred the correct amount.
The problem turned out to be token decimals.
The invoice wasn't checking the human-readable token amount shown in my wallet. It was validating the exact integer value stored on-chain. A tiny mismatch in decimal precision was enough for the payment to be rejected.
Throughout the challenge I encountered errors such as AccountNotInitialized, InsufficientFunds, Attempt to debit an account but found no record of a prior credit, and finally an invoice rejection due to an amount and decimal mismatch.
Each error pointed to a different problem. Instead of treating them as failures, I started treating them as hints.
What this challenge taught me
This challenge was much more than simply paying an invoice. It was an introduction to several fundamental Solana concepts:
- Associated Token Accounts (ATAs)
- SPL Token transfers
- Token decimal precision
- Base units versus displayed token amounts
- Reading transaction logs to identify the real cause of failures
Although I wasn't able to solve the challenge before the event ended, working through it taught me far more about SPL Token instructions, transaction inspection & on-chain debugging than simply reading the documentation would have. Even now, I'm not completely certain whether the approach I was exploring was the intended solution but the investigation itself was one of the most valuable learning experiences from the CTF.
Challenge 4: The Chamber
The Chamber shifted the focus to Solana's account model.
Unlike the previous challenges, this wasn't a single objective. Instead, it consisted of three sequential locks, each building on the previous one. You couldn't skip ahead, and each stage introduced a different concept, making the challenge feel like progressing through levels rather than solving a standalone puzzle.
The first lock
After opening the account, the first lock turned green and the next stage became available.
The challenge made use of a Program Derived Address (PDA) tied to my wallet, reinforcing one of the most common patterns in Solana programs. Rather than interacting with arbitrary accounts, the program relied on deterministic, program-owned state derived from known seeds.
It was nice seeing a concept that I'd already learned being applied in a practical setting rather than just as an isolated example.
The second lock
The second stage introduced an additional requirement. The interface displayed: "Co-sign with the key issued to you at the venue."
At the time, I was trying to decode the code provided by the physical card:
During registration, every participant had been given a card. One of the hints mentioned that the printed information on the card wasn't useful, so I interpreted that as a sign that the card itself wasn't important and moved on to other challenges.
It wasn't until after the event that I realized I'd misunderstood the hint. The card wasn't useless. Only the printed information on it was.
The actual clue was stored inside the card's NFC (Near Field Communication) chip.
For anyone unfamiliar, an NFC card is a contactless card containing a tiny embedded chip. When you tap it against an NFC-enabled phone, the phone reads whatever data is stored on the chip. The same technology is commonly used in metro cards, hotel room keys, office access badges & contactless payment cards.
After scanning the card, it revealed a Base64-encoded binary credential. Rather than being something human-readable, this appeared to be a cryptographic credential that was likely intended to be used in the second stage of the challenge.
Unfortunately, I only discovered this after the event had concluded, so I never got the opportunity to explore how the program verified it. Rather than speculate about the exact implementation, I'd rather leave it at that.
Looking back, it was a clever piece of challenge design. The hint never said the card was useless. It only said that what was printed on it wasn't.
Key takeaway
- Not every clue is visible at first glance.
- Sometimes the important information isn't on the screen, inside the source code, or even printed on the card you're holding.
- Sometimes it's hidden in plain sight, waiting for someone curious enough to look a little deeper.
- What is NFC card.
Challenge 5: Second Key
At first glance, this challenge looked like a simplified lending protocol.The interface showed two parties: my account on one side and the lender's vault on the other. My wallet held a single Warehouse Receipt, while the objective at the top read: "Recover Lot 22 without settling the account."
Normally, recovering collateral from a lending protocol requires repaying the loan first. Here, the challenge was asking me to do the exact opposite. That suggested there was likely a flaw in the protocol's authorization or state validation.
Investigating the interface
Unlike some of the previous challenges, this one provided very little guidance.
The available actions included:
- Opening the lender's note.
- Viewing the participant wallet.
- Pledging the receipt.
- Inspecting the on-chain evidence.
Rather than immediately interacting with the interface, I started examining the available accounts and transaction flow to understand how the protocol was structured.
The challenge seemed to revolve around a warehouse receipt, which acted as proof of ownership over a stored asset. In real-world finance, warehouse receipts are commonly used as collateral for loans. The protocol appeared to model the same concept on-chain.
The objective
The wording of the challenge made it clear that the intended solution wasn't simply transferring the receipt.
The goal was to recover the collateral without repaying the lender, which pointed towards some flaw in how the lending program validated ownership, collateral, or repayment status.
I wasn't able to solve this challenge during the event.
Rather than invent an explanation after the fact, I'd rather document the concepts it introduced and the direction I explored. They were asking me to understand how the protocol was intended to work before thinking about how it could fail. That shift in mindset is something I'll carry into future security research.
That actually changes the challenge quite a bit. It's less about finding a private key and more about blockchain forensics. I remember now that we eventually realized the important clue was that one transaction's timestamp didn't fit the sequence, and comparing the four provided transactions exposed the suspicious activity.
Challenge 6: Evidence Room
By the time I reached Evidence Room, I had started noticing a pattern.
Not every challenge expected me to write code or interact with a Solana program. Some simply expected me to investigate. This challenge was one of them.
Instead of presenting a vulnerable contract, it placed me inside an investigator's workspace. There were case files, evidence drawers, previous records, and transaction references, making it feel more like digital forensics than blockchain development. It was probably one of the most immersive interfaces in the entire CTF.
Following the evidence
The interface presented several pieces of evidence that initially looked unrelated. Among them were four transaction signatures that needed to be investigated. My first instinct was to inspect each transaction individually on Solscan and understand what had happened. All four transactions looked legitimate. The trick wasn't hidden inside any single transaction. It was hidden in the relationship between them.
The missing clue
After comparing the transactions more carefully, I realized the important detail wasn't the accounts, the instructions, or even the transferred amounts. It was the timestamps. One transaction didn't fit the expected sequence. That small inconsistency was enough to suggest that something abnormal had happened.
Instead of looking for an exploit directly, the challenge encouraged thinking like an investigator reconstructing a timeline from blockchain data. That was a refreshing change from the earlier challenges.
What I learned
Evidence Room introduced me to another important aspect of blockchain security: on-chain investigation.
Instead of thinking like a developer writing instructions, I had to think like an investigator reconstructing events from publicly available data.
The challenge reinforced the importance of:
- Reading transaction history.
- Comparing multiple transactions instead of analyzing them in isolation.
- Looking beyond instructions and account balances.
- Paying attention to metadata such as timestamps.
Sometimes the smallest piece of metadata ends up telling the biggest story.
Key takeaway
Every blockchain transaction records much more than token transfers. It also records when something happened.
In this challenge, the exploit wasn't obvious from reading a single transaction. It only became visible after comparing multiple transactions and realizing that one timestamp didn't belong.
That was a great reminder that blockchain security isn't always about exploiting programs. Sometimes it's about understanding the story the chain is already telling.
From what I remember, The Broadcast was one of the more interesting cryptography-focused challenges. We spent quite a bit of time debugging it because it looked like a normal Solana challenge, but the twist was that no on-chain transaction was required. The challenge was about generating a valid cryptographic signature over a message.
Challenge 7: The Broadcast
After several challenges involving PDAs, token accounts, and transaction analysis, The Broadcast took a completely different direction.
This time, the blockchain wasn't the main focus. Cryptographic signatures were. At first, I assumed I'd need to submit another Solana transaction. By this point in the CTF, that had become my default assumption. I was wrong.
Understanding the challenge
The challenge revolved around proving ownership of my wallet by signing a message.
Unlike a normal Solana transaction, signing a message doesn't modify on-chain state or consume any SOL. It simply proves that the holder of a private key authorized a specific piece of data.
That distinction was something I hadn't appreciated before. A wallet can sign many different things. Transactions are just one of them.
The Proof of Work (PoW)
Before signing the message, the challenge first required solving a small PoW puzzle. The server generated a challenge, and my client had to find a valid solution before it would accept any signed message. This wasn't related to Solana itself.
Instead, it acted as a lightweight anti-spam mechanism, preventing participants from brute-forcing requests against the server. Once the PoW was solved, the next step was straightforward:
- Generate the requested message.
- Sign it using my wallet.
- Submit both the message and signature for verification.
After completing the Proof of Work, the challenge led me to a YouTube video. At first, it looked completely broken. The screen was almost entirely black with only a brief "Claimed" message appearing. Naturally, I assumed the video itself contained another hidden clue.
I downloaded the video, inspected it with ffprobe, checked the metadata, and even looked through the individual frames, expecting steganography or some hidden message. After spending quite some time going down that rabbit hole, I eventually realized I was looking in the wrong place. The video wasn't the challenge. The real challenge was understanding how the signed message was being generated and verified.
The debugging
Like several earlier challenges, getting everything right took a few attempts. At one point the server accepted my claim but later rejected the verification because the signed message didn't exactly match what the challenge expected.
That was a good reminder that cryptographic signatures are extremely precise. Even the smallest difference in the message being signed produces a completely different signature.
What this challenge taught me
Before this challenge, I mostly associated wallets with sending transactions. This challenge highlighted another equally important capability: Digital signatures.
Wallets can prove ownership without sending anything on-chain. That idea appears throughout Web3.
Whether it's wallet authentication, Sign-In with Solana (SIWS), API authentication, or proving ownership of an address, message signing is everywhere.
The Broadcast was a simple but effective demonstration of that concept.
Key takeaway
- Not every interaction with a blockchain requires a blockchain transaction.
- Sometimes all you need is a valid signature.
- Understanding the difference between sending a transaction and signing an arbitrary message was probably the biggest lesson I took away from this challenge. It's a subtle distinction, but one that appears throughout modern Web3 applications.
Challenge 8: Imprint
Instead of writing transactions or inspecting accounts, the challenge revolved around passkeys.
At first glance, I wasn't even sure whether this was still a blockchain challenge. The interface guided me through a series of steps:
- Connect my wallet.
- Claim an event security key.
- Select the target vault.
- Sign a challenge using a passkey.
The interesting part was the final step.
Instead of asking my Phantom wallet to sign a transaction, it asked me to sign a 32-byte challenge using a passkey.
Understanding passkeys
Before this challenge, I'd heard about passkeys but had never actually used them in a technical context.
A passkey is based on the WebAuthn standard and uses public-key cryptography for authentication. When a passkey is created, your device generates a public-private key pair. The private key never leaves your device.
Whenever a website wants to verify your identity, it sends a random challenge. Your device signs that challenge using the private key, and the website verifies the signature using the corresponding public key.
In other words, it's authentication without passwords.
Solana meets WebAuthn
What made this challenge interesting was how it combined WebAuthn with a blockchain application.
Instead of proving ownership through a wallet signature, I was proving ownership of a registered passkey. That was a concept I hadn't seen before. Up until this point, I had mostly associated authentication in Web3 with wallets like Phantom or Metamask.
This challenge reminded me that blockchain applications can use multiple cryptographic systems together. Wallet signatures solve one problem. Passkeys solve another.
Key takeaway
One thing this CTF consistently did well was introducing concepts beyond traditional smart contracts.
Imprint wasn't testing whether I could write Rust or inspect transactions. It was introducing another piece of modern security infrastructure. As blockchain applications become more user-friendly, technologies like passkeys and WebAuthn will likely become much more common.
This challenge was a nice reminder that security isn't just about protecting blockchains. It's also about improving how people securely interact with them.
This is a much more interesting challenge than just "I deployed a malicious program." The blog should tell the story of how your understanding evolved. I also wouldn't dump all the implementation details. Save those for a technical write-up or GitHub gist. For the blog, focus on the security concept.
Challenge 9: Signet
Out of all the challenges in the CTF, Signet felt the closest to a real-world smart contract audit.
Unlike previous challenges that focused on understanding individual Solana concepts, this one required identifying a vulnerability, building an exploit around it, and executing it successfully.
The objective was simple: Move the assigned reserve tokens into the assigned escrow account and submit the transaction signature.
Starting with the source code
The challenge provided a GitHub repository containing the vault program, a starter strategy, and a client.
My initial assumption was that I simply needed to extend the provided strategy and deploy it. After spending some time reading the code, something didn't quite add up.
The repository looked secure. Eventually I realized why.
The GitHub repository had already been patched, while the deployed challenge instance was still running an older vulnerable version.
That completely changed how I approached the problem.
Finding the vulnerability
The vulnerability revolved around how the vault executed external strategy programs.
The vault used invoke_signed() to call a strategy program while forwarding its own PDA signer privileges.
Normally, this isn't a problem if the strategy program has been validated beforehand. The deployed challenge, however, didn't properly validate which strategy program was being executed.
That meant I could deploy my own strategy program and have the vault unknowingly invoke it with its signer privileges. In other words, the vault trusted code it shouldn't have trusted.
It was a classic example of why program ID validation is so important in Solana.
Building the exploit
Instead of performing the intended strategy logic, my custom strategy simply instructed the SPL Token Program to transfer the reserve tokens into my assigned escrow account.
The interesting part wasn't the token transfer itself. The interesting part was who signed it.
My strategy never possessed the vault's private key. Instead, it inherited the vault's signing authority because the vault called it using invoke_signed().
That small detail is what made the exploit possible.
The debugging rabbit hole
Getting the exploit working turned out to be far more time-consuming than understanding the vulnerability.
One of the biggest mistakes I made was creating my own Associated Token Account for the destination.
The verifier rejected it because the challenge expected tokens to be transferred into a specific assigned escrow account, not just any valid token account.
Later, I spent an embarrassing amount of time debugging what looked like a broken escrow account. The inspection script insisted the account wasn't a valid SPL Token account, while Solscan showed the exact opposite. After manually decoding the account data, everything looked perfectly valid.The issue wasn't the escrow account. The issue was my tooling. To make matters worse, I had copied the escrow address incorrectly. One incorrect Base58 character was enough to send me down several hours of unnecessary debugging.
It's amazing how much chaos a single character can create.
The final execution
Once everything was wired together correctly, the exploit worked exactly as intended.
The reserve tokens were successfully transferred into the assigned escrow account, the verifier accepted the transaction, and the challenge was finally marked as complete.
After hours of debugging, seeing the challenge accepted was an incredibly satisfying moment.
What I learned
This challenge highlighted one of the most important security principles in Solana.
Never allow arbitrary programs to inherit signer privileges.
Whenever a program performs a Cross Program Invocation using invoke_signed(), it must be extremely careful about which program it is invoking.
Forwarding signer authority to an untrusted program effectively allows that program to act with the permissions of the caller. That's exactly what happened here.
The challenge also reinforced several practical lessons that had nothing to do with the vulnerability itself:
- Always verify that you're interacting with the assigned accounts instead of creating your own.
- Don't blindly trust helper scripts. If something looks wrong, inspect the raw account data yourself.
- Reading patched source code alongside an older deployment can reveal exactly what vulnerability the challenge is trying to teach.
Key takeaway
Signet was probably the closest thing to a real audit exercise during the CTF.
Rather than solving a puzzle with hidden clues, I had to understand how the program delegated authority, identify where its trust assumptions broke down, and build an exploit around that behavior.
More than anything else, this challenge reinforced an important rule that applies far beyond Solana:
Never delegate authority to code you haven't explicitly validated.
It's a simple principle, but ignoring it is enough to turn a secure-looking protocol into a vulnerable one.
Challenge 10: Drift
I was handed a stripped native Solana SBF binary called drift_vault.so and asked to recover almost the entire reserve by submitting a valid replay trace.
No source code. No IDL. No account constraints. No documentation. Just a compiled binary.
Understanding the environment
The replay system itself was fairly minimal. It supported only two operations:invoke , set_sysvar Along with three predefined accounts:attacker , vault , position
The goal was to drain almost the entire vault balance within a limited number of replay steps. Unlike previous challenges, this wasn't about writing a Solana program. It was about understanding one that nobody had explained.
Reverse engineering the binary
Without source code, the only option was to reverse engineer the program.
Using tools like llvm-objdump, I started disassembling the SBF binary and trying to reconstruct how the program worked internally.
This was completely different from reviewing an Anchor program. Normally, Anchor provides account constraints, instruction definitions, and a clear program structure. Here, none of that existed. Every assumption had to be earned.
From the disassembly, I started piecing together possible instruction handlers, account layouts, and state transitions. One reconstruction suggested that the program might expose instructions similar to deposits, withdrawals, and state updates, but none of those assumptions could be confirmed with certainty. That uncertainty became the challenge itself.
Forming hypotheses
One interesting theory emerged while inspecting the binary. It appeared that one instruction might calculate elapsed time using something similar to: delta = current_timestamp - last_update
If that arithmetic wasn't properly checked, manipulating the Clock sysvar could potentially create an integer underflow, causing the elapsed time to become an extremely large value.
If that happened, the program might incorrectly believe a massive amount of rewards had accrued, allowing a much larger withdrawal than intended. It was an interesting hypothesis. Now it had to be tested.
What I learned
Although I never solved Drift, it ended up being one of the most educational challenges of the entire CTF. It taught me that reverse engineering isn't simply reading assembly.
It's a constant cycle of observation, hypothesis, experimentation, and revision. Every failed replay ruled out another possibility. Every error message refined my mental model of how the program worked.
Key takeaway
That challenge gave me a newfound appreciation for reverse engineers who spend days or even weeks understanding software with nothing more than assembly listings and educated guesses.
I walked away with a much better understanding of the mindset required for binary analysis. And honestly, that's a lesson I'm just as happy to take with me into future security research.
Since your entire blog is about the experience, not just the solutions, I'd end it on reflection rather than achievement.
Something like this:
Final Thoughts
Superteam CTF v2 wasn't about collecting flags. It was about collecting mental models.
Throughout the event, the leaderboard stayed live, which made things both exciting and mildly stressful. Every successful submission reshuffled the rankings, so there was always a reason to glance back at the screen.
Every challenge introduced a different corner of the Solana ecosystem. Some taught me about PDAs, others about SPL Tokens, message signing, WebAuthn, transaction forensics, reverse engineering, or simply reading logs more carefully.
I didn't solve every challenge. I also didn't expect to.
The goal was never to finish with a perfect score. It was to leave with a better understanding of how real-world Solana applications are built, how they fail, and how to reason about them.
One thing I particularly enjoyed was that the challenges weren't just random puzzles. Almost every problem represented a security concept or engineering pattern that appears in production systems. The team had crafted the challenges very well. That's what made the event memorable.
Looking back, travelling from Mumbai to Bengaluru for a one-day CTF was absolutely worth it.
I met passionate security folks, learned from people far more experienced than me and spent an entire day thinking about problems I normally wouldn't encounter while building applications.
Would I do it again? Without a second thought.
Thank You
A huge thank you to Superteam, the challenge authors, and everyone involved in organizing CTF v2. It was the most fun I've had while learning, and I genuinely hope this becomes a yearly tradition.
The event was incredibly well designed, and it's rare to find a CTF that manages to cover so many different aspects of Solana in a single day.
Hopefully this write-up helps someone preparing for the next edition.
I couldn't find a detailed participant experience before attending. Maybe this becomes the one I was looking for.