Skip to content

Commit

Permalink
feat Allow approved modules to forbid travel (#301)
Browse files Browse the repository at this point in the history
* feat Allow approved modules to forbid travel

* fix bool + uint256 error
  • Loading branch information
aymericdelab authored Feb 28, 2023
1 parent 05aabd5 commit 5f092ef
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
55 changes: 54 additions & 1 deletion contracts/settling_game/modules/travel/Travel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
%lang starknet

from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.bool import TRUE
from starkware.cairo.common.bool import TRUE, FALSE
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.math_cmp import is_le, is_nn
from starkware.cairo.common.uint256 import Uint256
Expand Down Expand Up @@ -55,6 +55,15 @@ func TravelAction_2(
// Storage
// -----------------------------------

// @param traveller_contract_id: ContractId
// @param traveller_token_id: TokenID
// @param traveller_nested_id: NestedID
@storage_var
func cannot_travel(
traveller_contract_id: felt, traveller_token_id: Uint256, traveller_nested_id: felt
) -> (cannot_travel: felt) {
}

// @asset_id: ContractId
// @token_id: TokenID
// @nested_asset_id: NestedID
Expand Down Expand Up @@ -103,6 +112,34 @@ func upgrade{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
// External
// -----------------------------------

// @notice Allow an asset to travel (army, adventurer)
// @dev By default all assets can travel
// @param traveller_contract_id: ContractId
// @param traveller_token_id: TokenID
// @param traveller_nested_id: NestedID
@external
func allow_travel{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
traveller_contract_id: felt, traveller_token_id: Uint256, traveller_nested_id: felt
) -> () {
Module.only_approved();
cannot_travel.write(traveller_contract_id, traveller_token_id, traveller_nested_id, FALSE);
return ();
}

// @notice Forbid an asset from travelling (army, adventurer)
// @dev By default all assets can travel
// @param traveller_contract_id: ContractId
// @param traveller_token_id: TokenID
// @param traveller_nested_id: NestedID
@external
func forbid_travel{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
traveller_contract_id: felt, traveller_token_id: Uint256, traveller_nested_id: felt
) -> () {
Module.only_approved();
cannot_travel.write(traveller_contract_id, traveller_token_id, traveller_nested_id, TRUE);
return ();
}

// @traveller_contract_id: External contract ID -> keeping the same for consistency
// @traveller_token_id: Asset token ID moving (Realm, Adventurer)
// @traveller_nested_id: Nested asset ID (Armies, persons etc)
Expand All @@ -124,6 +161,8 @@ func travel{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(

// TODO: assert is correct ID (can't try move unmoveable assets)

assert_can_travel(traveller_contract_id, traveller_token_id, traveller_nested_id);

// You cannot move nested asset ID 0 - this is the actual location.
let is_not_defending_army = is_nn(traveller_nested_id);
with_attr error_message("Combat: You cannot move your Defending Army") {
Expand Down Expand Up @@ -249,6 +288,20 @@ func get_travel_distance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_c
return (distance,);
}

// @notice Assert that an item can travel (army, adventurer), by default all items can travel
func assert_can_travel{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
traveller_contract_id: felt, traveller_token_id: Uint256, traveller_nested_id: felt
) -> () {
with_attr error_message("Travel: cannot move this item") {
let (forbid_to_travel) = cannot_travel.read(
traveller_contract_id, traveller_token_id, traveller_nested_id
);
assert forbid_to_travel = FALSE;
}
return ();
}

@view
func assert_arrived{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
contract_id: felt, token_id: Uint256, nested_id: felt
Expand Down
31 changes: 31 additions & 0 deletions tests/protostar/settling_game/travel/test_travel.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.math import unsigned_div_rem, sqrt
from starkware.cairo.common.pow import pow
from starkware.starknet.common.syscalls import get_contract_address
from starkware.cairo.common.bool import TRUE, FALSE
from starkware.cairo.common.uint256 import Uint256

from contracts.settling_game.modules.travel.library import Travel, PRECISION
from contracts.settling_game.modules.travel.travel import (
allow_travel,
forbid_travel,
assert_can_travel,
travel,
)

from contracts.settling_game.utils.constants import SECONDS_PER_KM
from contracts.settling_game.utils.game_structs import Point
Expand All @@ -19,6 +28,28 @@ const TEST_X2 = (685471) + offset;

const TEST_Y2 = (419800) + offset;

const TRAVELLER_CONTRACT_ID = 1;
const TRAVELLER_TOKEN_ID = 1;
const TRAVELLER_NESTED_ID = 1;

@external
func test_travel_when_forbid_should_fail{
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr
}() -> () {
let (self_address) = get_contract_address();
%{ store(ids.self_address, "cannot_travel", [1], [ids.TRAVELLER_CONTRACT_ID, ids.TRAVELLER_TOKEN_ID, 0, ids.TRAVELLER_NESTED_ID]) %}
%{ expect_revert() %}
assert_can_travel(TRAVELLER_CONTRACT_ID, Uint256(TRAVELLER_TOKEN_ID, 0), TRAVELLER_NESTED_ID);
return ();
}

@external
func test_travel_when_allowed{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
) -> () {
assert_can_travel(TRAVELLER_CONTRACT_ID, Uint256(TRAVELLER_TOKEN_ID, 0), TRAVELLER_NESTED_ID);
return ();
}

@external
func test_calculate_distance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() {
alloc_locals;
Expand Down

0 comments on commit 5f092ef

Please sign in to comment.