#How to authorize a sub invocation where the address that's being required is the root contract?

1 messages · Page 1 of 1 (latest)

pale hedge
#

I have a contract which makes a payment in a cross contract call where the source is the root contract address. This requires a non-root invoker require_auth in the root contract for the root address.
env.current_contract_address().require_auth()

Adding the above allows the simulation to pass successfully without the missing root invoker error but now I have an auth field I'm not quite sure how to authorize. Do I need to build some sort of __check_auth?

#

The flow is Contract A -> Contract B (which calls require_auth on the Contract A Address) -> Contract C (which also calls require_auth on the Contract A Address)

split flame
#

This requires a non-root invoker require_auth in the root contract
this sentence doesn't make much sense to me. IIUC what you want is authorize_as_current_contract for the transfer in the root contract. env.current_contract_address().require_auth() would actually require root to be a custom account, this is probably not what you want (and you call this 'invoker', so I assume you want invoker auth here)

proud vapor
# split flame > This requires a non-root invoker require_auth in the root contract this sente...

When u say that using require auth on the current contract address would require root to be a custom account. You mean implement the account interfact or have custom auth policies or both? I thought with account abstraction you can treat them similar because you can do somecontract.require_auth where somecontract is an address of a contract. What methods have to be implemented to ensure it works on a c address and a g address

vivid estuary
# pale hedge I have a contract which makes a payment in a cross contract call where the sourc...

Yep, env.current_contract_address().require_auth() is the right call to avoid the root invoker error. Since the contract is authorizing itself, you just need to include an auth entry for the contract address in the transaction—no need to write a custom __check_auth unless you're doing custom logic. Just make sure the contract's own address is authorized properly in your simulation or test.

split flame
#

please ignore the message above, it's incorrect (and seems AI generated).

split flame
# proud vapor When u say that using require auth on the current contract address would require...

When u say that using require auth on the current contract address would require root to be a custom account
I'm not saying that. I'm saying that when you call require_auth on an address A we first check if A is an invoker (direct or indirect). if it's not an invoker, we go through the external auth verification procedure (based on the auth entries attached to the transaction): if A is A G-account, we'll perform G-account auth, otherwise we perform C-account auth which calls __check_auth. now, when A is the current contract, it obviously can't be invoker, because Soroban prohibits re-entrance. so we go into external auth verification mode, which means that we'll look for __check_auth for the current contract. but it's highly unlikely that it's what you actually want, besides authorizing operations in custom account contracts (like we do here: https://github.com/stellar/soroban-examples/blob/ac65a9ce68f3dc972e84d8c0e9f5503cd7ff7a8b/account/src/lib.rs#L72). it seems to me like the question in the thread just requires indirect invoker auth via authorize_as_current_contract .
What methods have to be implemented to ensure it works on a c address and a g address
the caller of require_auth doesn't need to distinguish between C and G addresses. but in order for the call to succeed, the respective C or G address must provide sufficient auth, as per algorithm described above.

GitHub

Example Soroban Contracts. Contribute to stellar/soroban-examples development by creating an account on GitHub.

proud vapor
proud vapor
split flame
#

it's not possible to get the invoker at the moment, you gotta rely on auth

proud vapor
pale hedge
#

@split flame Thanks for the help. I've switched from using current_contract_address.require_auth and __check_auth to env.authorize_as_current_contract but I'm still getting

data:["[recording authorization only] encountered authorization not tied to the root contract invocation for an address. Use `require_auth()` in the top invocation or enable non-root authorization.", CCOX26HUL6Y5RCSPEMEKEP4E4KJ3NXXHXW2AHEMDWLCPCYPPGTLLDKOW]
#

CCOX26HUL6Y5RCSPEMEKEP4E4KJ3NXXHXW2AHEMDWLCPCYPPGTLLDKOW is my contract where I'm including the env.authorize_as_current_contract

#

Nvm. Got it! I had constructed my authorize_as_current_contract incorrectly

#

I'd very much like to see better errors here. the

Use `require_auth()` in the top invocation or enable non-root authorization.

is quite misleading given there's another option in the authorize_as_current_contract.

#

If there is a authorize_as_current_contract I'd love to see the error revolve more around debugging that. I know auth is hard but it's hard for debugging as much as it is for surfacing errors and this error will absolutely lead to devs thinking they need to use __check_auth when really they just need to carefully craft a authorize_as_current_contract

split flame
#

yeah, I agree that's annoying. given how auth works, we can't really know what your exact intentions are. but we can suggest the most probable cause (like missing invoker auth in case if we're dealing with a non-account contract)

#

would you mind opening an issue for rs-soroban-env?

proud vapor
pale hedge