Root + Impact
DescriptionThe
The function tries to get ModuleData
from @pizza_drop
, but the resource is actually stored on a different resource account created in init_module
.
Impact:
fun init_module(deployer: &signer) {
let seed = b"pizza_drop";
let (resource_signer, resource_signer_cap) = account::create_resource_account(deployer, seed);
@> move_to(deployer, ModuleData {
signer_cap: resource_signer_cap,
});
let state = State {
users_claimed_amount: table::new(),
claimed_users: table::new(),
owner: signer::address_of(deployer),
balance: 0,
};
move_to(&resource_signer, state);
coin::register<AptosCoin>(&resource_signer);
}
#[view]
fun get_resource_address(): address acquires ModuleData {
@> let module_data = borrow_global<ModuleData>(@pizza_drop);
let resource_signer = account::create_signer_with_capability(&module_data.signer_cap);
signer::address_of(&resource_signer)
}
Risk
Impact:
Proof of Concept
#[test(deployer = @0x2,pizza = @pizza_drop, framework = @0x1)]
#[expected_failure(abort_code = E_NOT_OWNER)]
fun test_POC (deployer: &signer,pizza: &signer, framework: &signer) acquires ModuleData , State{
use aptos_framework::timestamp;
use aptos_framework::aptos_coin;
timestamp::set_time_has_started_for_testing(framework);
let (burn_cap, mint_cap) = aptos_coin::initialize_for_test(framework);
init_module(deployer);
let funding_amount = 100000;
let deployer_coins = coin::mint<AptosCoin>(funding_amount, &mint_cap);
coin::register<AptosCoin>(deployer);
coin::deposit<AptosCoin>(@0x2, deployer_coins);
init_module(pizza);
let funding__amount = 100000;
let pizza_coins = coin::mint<AptosCoin>(funding__amount, &mint_cap);
coin::register<AptosCoin>(pizza);
coin::deposit<AptosCoin>(@pizza_drop, pizza_coins);
fund_pizza_drop(deployer,1000);
coin::destroy_burn_cap(burn_cap);
coin::destroy_mint_cap(mint_cap);
}
test run : aptos move test
Running Move unit tests
[ PASS ] 0xccc::airdrop::test_POC
Test result: OK. Total tests: 1; passed: 1; failed: 0
{
"Result": "Success"
}
Recommended Mitigation
#[view]
fun get_resource_address(owner: address): address acquires ModuleData {
- let module_data = borrow_global<ModuleData>(@pizza_drop); //@audit Incorrect borrow_global address
+ let module_data = borrow_global<ModuleData>(owner);
let resource_signer = account::create_signer_with_capability(&module_data.signer_cap);
signer::address_of(&resource_signer)
}