I have 2 contracts Contract_A and Contract_B
Contract_A: Has token vault, it has a function named transfer_token_to_Contract_B
Contract_B: There is a function call_transfer, which will call transfer_token_to_Contract_B using invoke_contract().
Alice: There is an admin user only who can execute call_transfer().
How to make authorization tree so that call structure look like:
Alice -> Contract_B -> Contract_A -> Token_Contract_Transfer()?
How to code require_auth() in each of these functions?
#Understanding call authorization tree
7 messages · Page 1 of 1 (latest)
can you share a code snippet?
to be more specific, you should sketch a call signature for every method and note who has to authorized which action.
then TBH all you need to is to call require_auth for the 'who' identifiied above. but please feel free to post here for more guidance.
@wooden matrix
Vault contract
pub fn transfer_to_swap_handler(
env: Env,
trader: Address,
token: Address,
swap_handler: Address,
amount: i128,
) {
// Verify the caller is the authorized trader
trader.require_auth();
// Verify the caller is the registered trader
match Self::get_trader(env.clone()) {
Some(configured_trader) => {
if configured_trader != trader {
panic!("Only the authorized trader can transfer tokens to swap handler");
}
}
None => panic!("No trader configured for this vault"),
}
// Verify amount is positive
if amount <= 0 {
panic!("Amount must be positive");
}
// Get token client for the specified token
let token_client = token::Client::new(&env, &token);
// Check if vault has enough balance
let contract_address = env.current_contract_address();
let current_balance = token_client.balance(&contract_address);
if current_balance < amount {
panic!("Insufficient balance in vault for token {:?}", token);
}
// Transfer tokens to swap handler
token_client.transfer(
&contract_address,
&swap_handler,
&amount
);
log!(&env, "Transfer to swap handler: {} of token {} to {}", amount, token, swap_handler);
}
}
Swap_handler contract
pub fn transfer_to_swap_handler(
env: Env,
vault: Address,
trader: Address,
token: Address,
swap_handler: Address,
amount: i128,
) {
let vault_client = VaultClient::new(env.clone(), vault.clone());
vault_client.transfer_to_swap_handler(trader, token, swap_handler, amount);
}
My requirement is to call transfer only from swap handler.
Current code is resulting in an error:
error: transaction simulation failed: HostError: Error(WasmVm, InvalidAction)
Event log (newest first):
0: [Diagnostic Event] contract:CBLT33SARAERHVKUGU7ADQP2ICYDUHRS44QDFHUJC2ARKXZJVMZRYMG3, topics:[error, Error(WasmVm, InvalidAction)], data:["VM call trapped: UnreachableCodeReached", transfer_to_swap_handler]
1: [Diagnostic Event] contract:CD5JZ4ASE3IJH6KGBSHWVLIYZRA3C3JKPQLBV4BY22OL5TNFIMQDKSVI, topics:[fn_return, transfer_to_swap_handler], data:Void
2: [Diagnostic Event] contract:CA2D2WZ4OFT2XJLAY2IFSQFJJSNMIV4I4FQZOJ6DD6VQNIGOP7N24VZW, topics:[fn_return, transfer], data:Void
3: [Contract Event] contract:CA2D2WZ4OFT2XJLAY2IFSQFJJSNMIV4I4FQZOJ6DD6VQNIGOP7N24VZW, topics:[transfer, CD5JZ4ASE3IJH6KGBSHWVLIYZRA3C3JKPQLBV4BY22OL5TNFIMQDKSVI, CBLT33SARAERHVKUGU7ADQP2ICYDUHRS44QDFHUJC2ARKXZJVMZRYMG3], data:10000000
@heavy island Looks like your call is hitting unreachable code — likely because require_auth is missing in the handler contract.
For starters, you need to add trader.require.auth() to the handler contract.
And then since the handler contract is calling vault contract on behalf of the trader, you will need to add deep auth logic into the function in the handler contract. Something similar to the logic in the image.
See the deep contract auth example for more details https://github.com/stellar/soroban-examples/blob/main/deep_contract_auth/src/lib.rs
GitHub
Example Soroban Contracts. Contribute to stellar/soroban-examples development by creating an account on GitHub.
did you set a trader address in the vault contract before calling it?