IOTA Move Challenges
Table of Contents generated with DocToc
IOTA Move CTF Progress (Challenges 0-8)
Date updated: March 2, 2026
Network: IOTA Testnet
Wallet: 0x7ac899c7920ecde96c92785bf3e81a3965b03b7378ab02feab70905e358ec702
This document is my personal run log for the IOTA Move CTF.
For each challenge, I link the official docs page, summarize what I did, and record the on-chain proof (tx digest + flag object).
Challenge 0: Mint Leap Frog NFT
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_0
What I did:
- I called the challenge package function to mint the NFT to my address.
- I verified the created object fields (
name,description,url) in CLI.
Result:
- Tx:
D1ceDXhD6GXe6nmY1z8TN2LaAtsRtk5gyvvmWqVUg3BX - Created object:
0x137b9582f3cc4774aea57ab6a69e1867a57b0f061a49290d45ef8ac605f195d3
Explorer:
- https://testnet.iotascan.com/txblock/D1ceDXhD6GXe6nmY1z8TN2LaAtsRtk5gyvvmWqVUg3BX
- https://testnet.iotascan.com/object/0x137b9582f3cc4774aea57ab6a69e1867a57b0f061a49290d45ef8ac605f195d3
Challenge 1: Checkin
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_1
What I did:
- I called
checkin::get_flagwith no arguments. - I verified that the on-chain
Flag.userfield was my sender address.
Result:
- Tx:
HHhP5sWPQYHUWRkYWN7FxS3GSGJn35ZFtD1nRJZ8G5Ua - Flag object:
0x4fae16349410f11d77a22baf6f992c40983eb00c052a87071c57c275419f6c97
Explorer:
- https://testnet.iotascan.com/txblock/HHhP5sWPQYHUWRkYWN7FxS3GSGJn35ZFtD1nRJZ8G5Ua
- https://testnet.iotascan.com/object/0x4fae16349410f11d77a22baf6f992c40983eb00c052a87071c57c275419f6c97
Challenge 2: Lucky Number
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_2
What I did:
- I read the source and confirmed
lucky_numis effectively ignored. - I called
luckynumber::get_flagwith the shared counter and au64value. - I verified the counter increment and the created
Flagobject.
Result:
- Tx:
3R4BpYk3VJoFD3jUJJtwGfwob6EPPat4TrjHcszjYc9j - Flag object:
0x4f5c3802d7a251797adb7c1d2222414f4f31620f518c044849e3a99ae76074bb
Explorer:
- https://testnet.iotascan.com/txblock/3R4BpYk3VJoFD3jUJJtwGfwob6EPPat4TrjHcszjYc9j
- https://testnet.iotascan.com/object/0x4f5c3802d7a251797adb7c1d2222414f4f31620f518c044849e3a99ae76074bb
Challenge 3: MintCoin Mechanics
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_3
What I did:
- I read
mintcoin::get_flagand saw it requiresCoin<MINTCOIN>with exact value5. - I minted three
MINTCOINcoins (2 + 2 + 2), merged, then split to produce a5coin. - I called
get_flagwith the shared counter and that5coin.
Result:
- Final tx:
DEcF4T2RLPmpdA199nzvcofBNw8DoBsmvhtqdSdxJikQ - Flag object:
0x2a64d16cc47837b150b3bd99e62b1be6e1c3060d3e30c62a902db8a8125312cd
Explorer:
- https://testnet.iotascan.com/txblock/DEcF4T2RLPmpdA199nzvcofBNw8DoBsmvhtqdSdxJikQ
- https://testnet.iotascan.com/object/0x2a64d16cc47837b150b3bd99e62b1be6e1c3060d3e30c62a902db8a8125312cd
Challenge 4: Airdrop
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_4
What I did:
- I read the logic and confirmed each address can only call
airdroponce. - Because
get_flagneeds a coin with value2, I created a second local address, funded it, and claimed once from each address. - I transferred the second AIRDROP coin to my main address, merged
1 + 1 -> 2, then calledget_flag.
Result:
- Final tx:
GB9w6DiN8Km1VLE6hNk4xSgaUKhKMMXr5qcAmKi4e6zC - Flag object:
0xde17cdc6cb42d4655ecc805bdf38e69c61ec5b1930986b9a21d7c4cda602798d
Explorer:
- https://testnet.iotascan.com/txblock/GB9w6DiN8Km1VLE6hNk4xSgaUKhKMMXr5qcAmKi4e6zC
- https://testnet.iotascan.com/object/0xde17cdc6cb42d4655ecc805bdf38e69c61ec5b1930986b9a21d7c4cda602798d
Challenge 5: Perfect Pizza
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_5
What I did:
- I decoded the required BCS bytes in
get_flagintou16field values (little-endian):10, 3, 610, 370, 18, 200, 180, 0
- I called
cookwith exactly those values. - I called
get_flagwith the resultingPizzaBox.
Result:
- Final tx:
7Hqk5cYfRiJUL8FGh7J9pKHbJyxqgd8nWhRAcFWpmTET - Flag object:
0x65f06fe985ed0f1c002df150b1a8cbc07fc8230403b4d25d5070c01466b29edd
Explorer:
- https://testnet.iotascan.com/txblock/7Hqk5cYfRiJUL8FGh7J9pKHbJyxqgd8nWhRAcFWpmTET
- https://testnet.iotascan.com/object/0x65f06fe985ed0f1c002df150b1a8cbc07fc8230403b4d25d5070c01466b29edd
Challenge 6: Go Recycle!
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_6
What I did:
- I read
accept_boxandget_flagand confirmed I needed to recycle more than 2 boxes. - I cooked 3 new pineapple boxes, transferred each box to the recycler object (transfer-to-object), then called
accept_box3 times usingReceiving<PizzaBox>. - I called
get_flagafter my recycle points were above the threshold.
Result:
- Final tx:
J2RwxqK3ZA3VcdnoYmqCL1rb3937L2fXSKtnkiLt2LQY - Flag object:
0xbebb5a5744d8ec88bc4c60c70d9e63ae6a6ce6465f27f93e337235851523126e
Explorer:
- https://testnet.iotascan.com/txblock/J2RwxqK3ZA3VcdnoYmqCL1rb3937L2fXSKtnkiLt2LQY
- https://testnet.iotascan.com/object/0xbebb5a5744d8ec88bc4c60c70d9e63ae6a6ce6465f27f93e337235851523126e
Challenge 7: PTBs
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_7
What I did:
- I solved this in one PTB:
get_ingredientsmake_dough ingredients.0 ingredients.1 ingredients.2 ingredients.3get_flag dough
- This uses PTB result binding and nested result indexing.
Result:
- Final tx:
6ZJB2R6m5rmiz3QbDkYiKq2Gu5eoyJdJNk9XHmtoChiJ - Flag object:
0x30cb533c2f95cd6d627f0d4688d6c00e42f87cedb1898ee1e3cb4169b667e48a
Explorer:
- https://testnet.iotascan.com/txblock/6ZJB2R6m5rmiz3QbDkYiKq2Gu5eoyJdJNk9XHmtoChiJ
- https://testnet.iotascan.com/object/0x30cb533c2f95cd6d627f0d4688d6c00e42f87cedb1898ee1e3cb4169b667e48a
Challenge 8: Flash!
Official docs: https://docs.iota.org/developer/iota-move-ctf/challenge_8
What I did:
- I analyzed
vault.moveand found the flash-loan sequence lets me callget_flagmid-PTB while vault balances are temporarily drained. - I discovered the active shared vault object via RPC transaction query:
0xb20dd806796441944552112b3ab9ff1879b623482014e23b398bb0ad8496b8e7
- In one PTB, I executed:
flash(..., amount=100, a_to_b=false)get_flag(...)while vault balances satisfy the checkrepay_flash(...)so the full transaction still succeeds
Result:
- Final tx:
97cggbTZ4JUbAa26SNTfxae1im3WBfHYT3676Xb3u7Bn - Flag object:
0x85705dad66e517b60c868912799594ebe1404cc4d1b1480e3df272fac49615cc
Explorer:
- https://testnet.iotascan.com/txblock/97cggbTZ4JUbAa26SNTfxae1im3WBfHYT3676Xb3u7Bn
- https://testnet.iotascan.com/object/0x85705dad66e517b60c868912799594ebe1404cc4d1b1480e3df272fac49615cc
Index of Official Challenge Pages
- Introduction: https://docs.iota.org/developer/iota-move-ctf/introduction
- Challenge 0: https://docs.iota.org/developer/iota-move-ctf/challenge_0
- Challenge 1: https://docs.iota.org/developer/iota-move-ctf/challenge_1
- Challenge 2: https://docs.iota.org/developer/iota-move-ctf/challenge_2
- Challenge 3: https://docs.iota.org/developer/iota-move-ctf/challenge_3
- Challenge 4: https://docs.iota.org/developer/iota-move-ctf/challenge_4
- Challenge 5: https://docs.iota.org/developer/iota-move-ctf/challenge_5
- Challenge 6: https://docs.iota.org/developer/iota-move-ctf/challenge_6
- Challenge 7: https://docs.iota.org/developer/iota-move-ctf/challenge_7
- Challenge 8: https://docs.iota.org/developer/iota-move-ctf/challenge_8