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: 0xc8bc4a1780bcdfec4ca4a85522c6a2d9f2dad8ce6881fe6bb5d6df21214ffc69
Counter: 0x03730ebe89151b43e696c7c6ca6e32818ececf12459d8b67a7173dfce361ffa5

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 = 1000;
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!