Skip to content

Commit

Permalink
precompile
Browse files Browse the repository at this point in the history
  • Loading branch information
JSHan94 committed Mar 18, 2024
1 parent 3ec6203 commit 2e5e42b
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 53 deletions.
Binary file modified precompile/binaries/minlib/vip_score.mv
Binary file not shown.
4 changes: 2 additions & 2 deletions precompile/modules/initia_stdlib/sources/vip/vault.move
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module initia_std::vip_vault {
use initia_std::vip_reward;

friend initia_std::vip;

//
// Errors
//
Expand Down Expand Up @@ -125,7 +125,7 @@ module initia_std::vip_vault {
let vault_store_addr = get_vault_store_address();
primary_fungible_store::balance(vault_store_addr, vip_reward::reward_metadata())
}

//
// Tests
//
Expand Down
244 changes: 193 additions & 51 deletions precompile/modules/minitia_stdlib/sources/vip/score.move
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// vip_score is the contract to provide a score for each contracts.
module minitia_std::vip_score {
use std::vector;
use std::event;

use minitia_std::bcs;
use minitia_std::signer;
use minitia_std::table;
use minitia_std::error;
Expand Down Expand Up @@ -37,15 +37,37 @@ module minitia_std::vip_score {
/// The deployer is not found.
const EDEPLOYER_NOT_FOUND: u64 = 5;


/// The length of addrs and scores is not matched.
const ENOT_MATCH_LENGTH: u64 = 6;

/// The score is invalid.
const EINVALID_SCORE: u64 = 7;

//
// Constants
// Events
//
const BOARD_PREFIX: u8 = 0xf7;

#[event]
struct DeployerAddedEvent has drop, store {
deployer: address
}

#[event]
struct DeployerRemovedEvent has drop, store {
deployer: address
}

#[event]
struct UpdateScoreEvent has drop, store {
addr: address,
stage: u64,
score: u64,
total_score: u64
}


//
// Helper functions.
// Implementation
//

fun init_module(chain: &signer) {
Expand All @@ -66,14 +88,8 @@ module minitia_std::vip_score {
assert!(found, error::invalid_argument(EUNAUTHORIZED));
}

fun generate_board_seed(account: address): vector<u8> {
let seed = vector[BOARD_PREFIX];
vector::append(&mut seed, bcs::to_bytes(&account));
return seed
}

//
// View functions.
// View functions
//

#[view]
Expand All @@ -97,27 +113,22 @@ module minitia_std::vip_score {
}

//
// Public functions.
// Public functions
//

public entry fun add_deployer(
chain: &signer,
deployer: address,
public fun prepare_stage (
deployer: &signer,
stage: u64
) acquires ModuleStore {
check_chain_permission(chain);
check_deployer_permission(deployer);
let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(!simple_map::contains_key(&module_store.deployers, &deployer), error::invalid_argument(EDEPLOYER_ALREADY_ADDED));
simple_map::add(&mut module_store.deployers, deployer, true);
}

public entry fun remove_deployer(
chain: &signer,
deployer: address,
) acquires ModuleStore {
check_chain_permission(chain);
let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(simple_map::contains_key(&module_store.deployers, &deployer), error::invalid_argument(EDEPLOYER_NOT_FOUND));
simple_map::remove(&mut module_store.deployers, &deployer);
if (!table::contains(&module_store.scores, stage)) {
table::add(&mut module_store.scores, stage, Scores {
total_score: 0,
score: table::new<address, u64>()
});
};
}

/// Increase a score of an account.
Expand All @@ -130,17 +141,21 @@ module minitia_std::vip_score {
check_deployer_permission(deployer);

let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(table::contains(&module_store.scores, stage), error::invalid_argument(EINVALID_STAGE));

if (!table::contains(&module_store.scores, stage)) {
table::add(&mut module_store.scores, stage, Scores {
total_score: 0,
score: table::new<address, u64>()
});
};
let scores = table::borrow_mut(&mut module_store.scores, stage);
let score = table::borrow_mut_with_default(&mut scores.score, addr, 0);
*score = *score + amount;
scores.total_score = scores.total_score + amount;

event::emit(
UpdateScoreEvent {
addr: addr,
stage: stage,
score: *score,
total_score: scores.total_score
}
)
}

/// Decrease a score of an account.
Expand All @@ -154,11 +169,109 @@ module minitia_std::vip_score {

let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(table::contains(&module_store.scores, stage), error::invalid_argument(EINVALID_STAGE));

let scores = table::borrow_mut(&mut module_store.scores, stage);
let score = table::borrow_mut(&mut scores.score, addr);
assert!(*score >= amount, error::invalid_argument(EINSUFFICIENT_SCORE));
*score = *score - amount;
scores.total_score = scores.total_score - amount;

event::emit(
UpdateScoreEvent {
addr: addr,
stage: stage,
score: *score,
total_score: scores.total_score
}
)
}

public fun update_score (
deployer: &signer,
addr: address,
stage: u64,
amount: u64
) acquires ModuleStore {
check_deployer_permission(deployer);
assert!(amount > 0, error::invalid_argument(EINVALID_SCORE));

let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(table::contains(&module_store.scores, stage), error::invalid_argument(EINVALID_STAGE));

let scores = table::borrow_mut(&mut module_store.scores, stage);
let score = table::borrow_mut_with_default(&mut scores.score, addr, 0);

if (*score > amount) {
scores.total_score = scores.total_score - (*score - amount);
} else {
scores.total_score = scores.total_score + (amount - *score);
};

*score = amount;

event::emit(
UpdateScoreEvent {
addr: addr,
stage: stage,
score: *score,
total_score: scores.total_score
}
)
}

//
// Entry functions
//

public entry fun update_score_script(
deployer: &signer,
stage: u64,
addrs: vector<address>,
scores: vector<u64>
) acquires ModuleStore {
assert!(vector::length(&addrs) == vector::length(&scores), error::invalid_argument(ENOT_MATCH_LENGTH));
prepare_stage(deployer, stage);

vector::enumerate_ref(&addrs, |i, addr| {
update_score(
deployer,
*addr,
stage,
*vector::borrow(&scores, i),
);
});
}

public entry fun add_deployer_script(
chain: &signer,
deployer: address,
) acquires ModuleStore {
check_chain_permission(chain);
let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(!simple_map::contains_key(&module_store.deployers, &deployer), error::invalid_argument(EDEPLOYER_ALREADY_ADDED));
simple_map::add(&mut module_store.deployers, deployer, true);

event::emit(
DeployerAddedEvent {
deployer: deployer
}
)
}

public entry fun remove_deployer_script(
chain: &signer,
deployer: address,
) acquires ModuleStore {
check_chain_permission(chain);
let module_store = borrow_global_mut<ModuleStore>(@minitia_std);
assert!(simple_map::contains_key(&module_store.deployers, &deployer), error::invalid_argument(EDEPLOYER_NOT_FOUND));
simple_map::remove(&mut module_store.deployers, &deployer);

event::emit(
DeployerRemovedEvent {
deployer: deployer
}
)
}

//
Expand All @@ -174,56 +287,67 @@ module minitia_std::vip_score {

#[test(chain = @0x1, deployer = @0x2, user = @0x123)]
#[expected_failure(abort_code = 0x10001, location = Self)]
fun test_remove_deployer(chain: &signer, deployer: &signer, user: address) acquires ModuleStore {
fun failed_remove_deployer_script(chain: &signer, deployer: &signer, user: address) acquires ModuleStore {
init_module_for_test(chain);
add_deployer(chain, signer::address_of(deployer));

add_deployer_script(chain, signer::address_of(deployer));
prepare_stage(deployer, 1);

increase_score(deployer, user, 1, 100);
assert!(get_score(user, 1) == 100, 1);
remove_deployer(chain, signer::address_of(deployer));
remove_deployer_script(chain, signer::address_of(deployer));
increase_score(deployer, user, 1, 100);
}

#[test(chain = @0x1, deployer = @0x2, user = @0x123)]
#[expected_failure(abort_code = 0x10002, location = Self)]
fun test_decrease_score_isufficient(chain: &signer, deployer: &signer, user: address) acquires ModuleStore {
fun failed_decrease_score_isufficient(chain: &signer, deployer: &signer, user: address) acquires ModuleStore {
init_module_for_test(chain);
add_deployer(chain, signer::address_of(deployer));
add_deployer_script(chain, signer::address_of(deployer));
prepare_stage(deployer, 1);

increase_score(deployer, user, 1, 100);
assert!(get_score(user, 1) == 100, 1);
decrease_score(deployer, user, 1, 10000);
}

#[test(chain = @0x1, deployer = @0x2, user = @0x123)]
#[expected_failure(abort_code = 0x10003, location = Self)]
fun test_decrease_score_invalid_stage(chain: &signer, deployer: &signer, user: address) acquires ModuleStore {
fun failed_decrease_score_invalid_stage(chain: &signer, deployer: &signer, user: address) acquires ModuleStore {
init_module_for_test(chain);
add_deployer(chain, signer::address_of(deployer));
add_deployer_script(chain, signer::address_of(deployer));
prepare_stage(deployer, 1);

increase_score(deployer, user, 1, 100);
assert!(get_score(user, 1) == 100, 1);
decrease_score(deployer, user, 2, 100);

// stage 2 not prepared
increase_score(deployer, user, 2, 100);
}

#[test(chain = @0x1, deployer = @0x2)]
#[expected_failure(abort_code = 0x10004, location = Self)]
fun test_add_deployer_already_exist(chain: &signer, deployer: &signer) acquires ModuleStore {
fun failed_add_deployer_script_already_exist(chain: &signer, deployer: &signer) acquires ModuleStore {
init_module_for_test(chain);
add_deployer(chain, signer::address_of(deployer));
add_deployer(chain, signer::address_of(deployer));
add_deployer_script(chain, signer::address_of(deployer));
add_deployer_script(chain, signer::address_of(deployer));
}

#[test(chain = @0x1, deployer = @0x2)]
#[expected_failure(abort_code = 0x10005, location = Self)]
fun test_remove_deployer_not_found(chain: &signer, deployer: &signer) acquires ModuleStore {
fun failed_remove_deployer_script_not_found(chain: &signer, deployer: &signer) acquires ModuleStore {
init_module_for_test(chain);
remove_deployer(chain, signer::address_of(deployer));
remove_deployer_script(chain, signer::address_of(deployer));
}

#[test(chain = @0x1, deployer_a = @0x2, deployer_b = @0x3, user_a = @0x123, user_b = @0x456)]
fun test_e2e(chain: &signer, deployer_a: &signer, deployer_b: &signer, user_a: address, user_b: address) acquires ModuleStore {
init_module_for_test(chain);

add_deployer(chain, signer::address_of(deployer_a));
add_deployer(chain, signer::address_of(deployer_b));
add_deployer_script(chain, signer::address_of(deployer_a));
add_deployer_script(chain, signer::address_of(deployer_b));

prepare_stage(deployer_a, 1);

// increase score by deployer_a
increase_score(deployer_a, user_a, 1, 100);
Expand All @@ -239,10 +363,28 @@ module minitia_std::vip_score {
assert!(get_total_score(1) == 300, 5);

// decrease score of user_a
decrease_score( deployer_a, user_a, 1, 50);
decrease_score( deployer_b, user_b, 1, 50);
decrease_score(deployer_a, user_a, 1, 50);
decrease_score(deployer_b, user_b, 1, 50);
assert!(get_score(user_a, 1) == 150, 6);
assert!(get_score(user_b, 1) == 50, 7);
assert!(get_total_score(1) == 200, 8);

update_score(deployer_a, user_a, 1, 300);
update_score(deployer_b, user_b, 1, 300);
assert!(get_score(user_a, 1) == 300, 9);
assert!(get_score(user_b, 1) == 300, 10);
assert!(get_total_score(1) == 600, 11);

// automatically prepare stage
update_score_script(
deployer_a,
2,
vector[user_a, user_b],
vector[100, 200]
);

assert!(get_score(user_a, 2) == 100, 12);
assert!(get_score(user_b, 2) == 200, 13);
assert!(get_total_score(2) == 300, 14);
}
}

0 comments on commit 2e5e42b

Please sign in to comment.