Skip to main content

Challenge 2: Lucky Number

In this challenge you are supposed to get the flag Event by passing in the right parameters to the get_flag function in the luckynumber module. If you do this correctly you should get a Flag event in return.

Deployed Contract Addresses:

Package: 0x2d902cb948748fd2b92ff98e5d0fd46a9ceb4b7501050ef8513b9bc60f515ef8
Counter: 0xbd21a9287e9f6ea1b69c810cf31e554fa260ff4547b2b94dac3e73239b1c3173

Contracts

luckynumber.move

module ctf::luckynumber {
use ctf::counter::{Self, Counter};

fun init(ctx: &mut TxContext) {
counter::create_counter(ctx);
}

public struct Flag has key, store {
id: UID,
user: address
}

public entry fun get_flag(user_counter: &mut Counter, lucky_num: u64, ctx: &mut TxContext) {
counter::increment(user_counter);
counter::is_within_limit(user_counter);

let _ = lucky_num;
transfer::public_transfer(Flag {
id: object::new(ctx),
user: tx_context::sender(ctx)
}, tx_context::sender(ctx));
}
}

counter.move

module ctf::counter {

const MaxCounter: u64 = 10;
const ENoAttemptLeft: u64 = 0;

/// A shared counter.
public struct Counter has key {
id: UID,
owner: address,
value: u64
}

/// Create and share a Counter object.
public(package) fun create_counter(ctx: &mut TxContext) {
transfer::share_object(Counter {
id: object::new(ctx),
owner: tx_context::sender(ctx),
value: 0
})
}

public fun owner(counter: &Counter): address {
counter.owner
}

public fun value(counter: &Counter): u64 {
counter.value
}

/// Increment a counter by 1.
public fun increment(counter: &mut Counter) {
counter.value = counter.value + 1;
}

/// Set value (only runnable by the Counter owner)
public entry fun set_value(counter: &mut Counter, value: u64, ctx: &TxContext) {
assert!(counter.owner == tx_context::sender(ctx), 0);
counter.value = value;
}

/// Check whether the counter has reached the limit.
public fun is_within_limit(counter: &mut Counter) {
assert!(counter.value <= MaxCounter, ENoAttemptLeft);
}
}

In this stage of the CTF, you should be familiar with how to use the CLI to call a Move function and pass in the right parameters, as well as a general understanding of the Object Model:

tip

You should check how to use the CLI to call a function in a module and pass in the right parameters. iota client call --help might help.

Good luck in capturing your second flag!