I have a method on my contract that transfers a token from the user's account to the contract address.
My contract dynamically computes an upper bound on how much of the token can be sent to it, and the method takes i128::min(parameter_amount, upper_bound) as the value to send via TokenClient::transfer.
Whenever I pass a <= value than my dynamically computed lower bound - everything works well, but whenever I try to pass a value bigger than the upper bound, I get:
❌ error: transaction submission failed: Some(
{
...
result: TxFailed(
VecM(
[
OpInner(
InvokeHostFunction(
Trapped,
),
ext: V0,
..
)
And on the explorer, I can also see:
Unauthorized function call for address line for the transfer invocation.
I tried to reproduce this issue with a smaller contract that looks like this:
#[contractimpl]
impl Contract {
pub fn sends_to_contract(e: Env, amount: i128, user: Address, token_address: Address) {
let inner_cap = e.storage().instance().get(&"INNER_CAP").unwrap();
user.require_auth();let real_amount = i128::min(amount, inner_cap); token::TokenClient::new(&e, &token_address).transfer( &user, &e.current_contract_address(), &real_amount, ); } pub fn change(e: Env, amount: i128) { e.storage().instance().set(&"INNER_CAP", &amount); }}
, but the issue isn't reproduced in this manner - passing value bigger than the bound transfers theupper boundsuccessfully.
Is this some well-known security feature with authorization that I am not aware about?
If yes, it's strange that I cannot reproduce it with a given smaller example.
I'd share my initial code, but I can't do that since we haven't yet launched publicly(. Any advice?)