Skip to content

Commit

Permalink
[merkle-distributor] fixed the compiler error of test
Browse files Browse the repository at this point in the history
  • Loading branch information
welbon committed Jan 15, 2025
1 parent f6be02f commit 7743d0e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 27 deletions.
83 changes: 57 additions & 26 deletions contrib-contracts/modules/MerkleDistributor.move
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
address StarcoinAssociation {
module MerkleDistributorScripts {
module StarcoinAssociation::MerkleDistributorScripts {
use StarcoinAssociation::MerkleDistributor;
use starcoin_framework::coin;
use starcoin_std::signer;
public entry fun create<T: store>(signer: signer, merkle_root: vector<u8>, coin_amounts: u64, leaves: u64) {

public entry fun create<T>(signer: signer, merkle_root: vector<u8>, coin_amounts: u64, leaves: u64) {
let coins = coin::withdraw<T>(&signer, coin_amounts);
MerkleDistributor::create<T>(&signer, merkle_root, coins, leaves);
}

public entry fun claim_for_address<T: store>(signer: signer, distribution_address: address, index: u64, account: address, amount: u64, merkle_proof: vector<vector<u8>>) {
public entry fun claim_for_address<T>(
signer: signer,
distribution_address: address,
index: u64,
account: address,
amount: u64,
merkle_proof: vector<vector<u8>>
) {
MerkleDistributor::claim_for_address<T>(&signer, distribution_address, index, account, amount, merkle_proof);
}
public entry fun claim<T: store>(signer: signer, distribution_address: address, index: u64, amount: u64, merkle_proof: vector<vector<u8>>) {

public entry fun claim<T>(
signer: signer,
distribution_address: address,
index: u64,
amount: u64,
merkle_proof: vector<vector<u8>>
) {
let coins = MerkleDistributor::claim<T>(&signer, distribution_address, index, amount, merkle_proof);
let account_addr = signer::address_of(&signer);
coin::deposit<T>(account_addr, coins);
}
}

module MerkleProof {
module StarcoinAssociation::MerkleProof {
use std::hash;
use std::vector;
use starcoin_std::comparator;
Expand All @@ -28,19 +42,18 @@ module MerkleProof {
let computed_hash = leaf;
let i = 0;
let proof_length = vector::length(proof);
while(i < proof_length) {
while (i < proof_length) {
let sibling = vector::borrow(proof, i);
// computed_hash is left.
if (!comparator::is_greater_than(&comparator::compare_u8_vector(computed_hash,*sibling))) {
if (!comparator::is_greater_than(&comparator::compare_u8_vector(computed_hash, *sibling))) {
let concated = concat(computed_hash, *sibling);
computed_hash = hash::sha3_256(concated);
} else {
let concated = concat(*sibling, computed_hash);
computed_hash = hash::sha3_256(concated);

};

i = i+1;
i = i + 1;
};
&computed_hash == root
}
Expand All @@ -53,27 +66,27 @@ module MerkleProof {
}



module MerkleDistributor {
module StarcoinAssociation::MerkleDistributor {
use StarcoinAssociation::MerkleProof;
use std::bcs;
use starcoin_framework::coin;
use std::bcs;
use std::error;
use std::hash;
use std::vector;
use starcoin_std::signer;


struct MerkleDistribution<T: store> has key {
struct MerkleDistribution<phantom T> has key {
merkle_root: vector<u8>,
coins: coin::Coin<T>,
claimed_bitmap: vector<u64>,
}

const INVALID_PROOF: u64 = 1;
const ALREADY_CLAIMED: u64 = 2;

/// Initialization.
public fun create<T: store>(signer: &signer, merkle_root: vector<u8>, coins: coin::Coin<T>, leaves: u64) {
public fun create<T>(signer: &signer, merkle_root: vector<u8>, coins: coin::Coin<T>, leaves: u64) {
let bitmap_count = leaves / 64;
if (bitmap_count * 64 < leaves) {
bitmap_count = bitmap_count + 1;
Expand All @@ -84,7 +97,7 @@ module MerkleDistributor {
vector::push_back(&mut claimed_bitmap, 0u64);
j = j + 1;
};
let distribution = MerkleDistribution{
let distribution = MerkleDistribution {
merkle_root,
coins,
claimed_bitmap,
Expand All @@ -93,29 +106,48 @@ module MerkleDistributor {
}

/// claim for some address.
public fun claim_for_address<T: store>(signer: &signer, distribution_address: address, index: u64, account: address, amount: u64, merkle_proof: vector<vector<u8>>)
acquires MerkleDistribution {
public fun claim_for_address<T>(
signer: &signer,
distribution_address: address,
index: u64,
account: address,
amount: u64,
merkle_proof: vector<vector<u8>>
)
acquires MerkleDistribution {
let distribution = borrow_global_mut<MerkleDistribution<T>>(distribution_address);
let claimed_coins = internal_claim(signer, distribution, index, account, amount, merkle_proof);
coin::deposit(account, claimed_coins);
}

/// claim by myself.
public fun claim<T: store>(signer: &signer, distribution_address: address, index: u64, amount: u64, merkle_proof: vector<vector<u8>>): coin::Coin<T>
acquires MerkleDistribution {
public fun claim<T>(
signer: &signer,
distribution_address: address,
index: u64,
amount: u64,
merkle_proof: vector<vector<u8>>
): coin::Coin<T> acquires MerkleDistribution {
let distribution = borrow_global_mut<MerkleDistribution<T>>(distribution_address);
internal_claim(signer, distribution, index, signer::address_of(signer), amount, merkle_proof)
}

/// Query whether `index` of `distribution_address` has already claimed.
public fun is_claimed<T: store>(distribution_address: address, index: u64): bool
public fun is_claimed<T>(distribution_address: address, index: u64): bool
acquires MerkleDistribution {
let distribution = borrow_global<MerkleDistribution<T>>(distribution_address);
is_claimed_(distribution, index)
}

fun internal_claim<T: store>(signer: &signer, distribution: &mut MerkleDistribution<T>, index: u64, account: address, amount: u64, merkle_proof: vector<vector<u8>>): coin::Coin<T> {
let claimed = is_claimed_(distribution, index);
fun internal_claim<T>(
signer: &signer,
distribution: &mut MerkleDistribution<T>,
index: u64,
account: address,
amount: u64,
merkle_proof: vector<vector<u8>>
): coin::Coin<T> {
let claimed = is_claimed_(distribution, index);
assert!(!claimed, error::invalid_argument(ALREADY_CLAIMED));

let leaf_data = encode_leaf(&index, &account, &amount);
Expand All @@ -127,15 +159,15 @@ module MerkleDistributor {
coin::withdraw(signer, amount)
}

fun is_claimed_<T: store>(distribution: &MerkleDistribution<T>, index: u64): bool {
fun is_claimed_<T>(distribution: &MerkleDistribution<T>, index: u64): bool {
let claimed_word_index = index / 64;
let claimed_bit_index = ((index % 64) as u8);
let word = vector::borrow(&distribution.claimed_bitmap, claimed_word_index);
let mask = 1u64 << claimed_bit_index;
(*word & mask) == mask
}

fun set_claimed_<T: store>(distribution: &mut MerkleDistribution<T>, index: u64) {
fun set_claimed_<T>(distribution: &mut MerkleDistribution<T>, index: u64) {
let claimed_word_index = index / 64;
let claimed_bit_index = ((index % 64) as u8);
let word = vector::borrow_mut(&mut distribution.claimed_bitmap, claimed_word_index);
Expand All @@ -151,5 +183,4 @@ module MerkleDistributor {
vector::append(&mut leaf, bcs::to_bytes(amount));
leaf
}
}
}
2 changes: 1 addition & 1 deletion contrib-contracts/src/merkle_distributor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn test_merkle_distributor() -> Result<()> {
Identifier::new("MerkleDistributorScripts").unwrap(),
),
Identifier::new("create").unwrap(),
vec![],
vec![stc_type_tag()],
vec![
merkle_root.simple_serialize().unwrap(),
rewards_total.simple_serialize().unwrap(),
Expand Down

0 comments on commit 7743d0e

Please sign in to comment.