Changing approved allowance

Hi,

I have rust backend canister. it takes multiple requests to perform swaps of different tokens. as part of the transfer it also does an icrc2_approve. However, if a second token swap request comes in whilst a previous one is being transferred i get ApprovalError(AllowanceChanged { current_allowance: Nat(5200000) }))

 icrc2_approve(ledger_id, icrc2_approve::Args {
                    from_subaccount: None,
                    spender: Account { owner: nft_canister, subaccount: None },
                    amount: amount.clone(),
                    expected_allowance: Some(Nat::from(0u64)),
                    expires_at: None,
                    fee: None,
                    memo: None,
                    created_at_time: None,
                }),

Is there a way i can update the allowance? so that I may increase it when a second request comes in?

1 Like

Yeah, i fully agree
If there is a lot of differents call to the canister trying to increase the allowance, each time it’s reseted. In my opinion we should add a way to add allowance

You have to either provide the correct expected allowance, in the case above expected_allowance: Some(Nat::from(5200000u64)) or disable the expected allowance check expected_allowance: None. See ICRC-1/standards/ICRC-2 at main · dfinity/ICRC-1 · GitHub

Hi,

Thanks for your reply. Unfortunately this doesn’t work for us. Too many requests come in at the same time for this to work. I changed the expected allowance to a None value however I get for the icrc7_transfer method.

Err(#InsufficientAllowance({allowance = 0}))

before i call the icrc7_transfer i also check the allowance and in most cases it’s 0. I would guess because we’re processing a lot of requests at the same time and so the allowance hasn’t been changed for some of them.

Hi @frederico02,

Would it be an option to set different subaccount values for the spender? That way there could be one allowance per request flow, and the expected_allowance could be used as before.

An alternative could be to set a very large allowance amount, and make sure that the from account only has enough funds for the transfers it wants to make.

Hi,

Yes that is a solution, although not the best since we’d also incur fees transferring first to sub accounts. I do appreciate your input though :slight_smile: We are fortunate to have a different option at our disposal. but i will mark your response as the solution answer.

Maybe your use case is different from what I’m thinking of, and/or there are additional dimensions of complexity, but it shouldn’t be necessary to transfer to different subaccounts and incur fees. One point here is that no fees are collected from the spender in the transfer_from operation - all fees are taken from the from account specified in the allowance. Maybe the below example can help to clarify:

  • One user with a single principal that wants to make multiple swaps, meaning multiple approve + transfer_from flows (in parallel). This user has all its funds in a single subaccount (probably subaccount None, but it could be any). This is the (principal, subaccount) that will be specified as the from in all the approve transactions, and in the transfer_from. Fees for the approve and transfer_from operations will be taken from the above (principal, subaccount).
  • A single spender that will perform all the transfer_from transactions.
  • The to account in the transfer_from transactions can be any (principal, subaccount) - in particular, it could be the spenders’s principal, and the None subaccount - it doesn’t need to match the (principal, subaccount) specified in the approval.

Maybe the last bullet point is what you were thinking of when saying that you’d incur fees transferring first to sub accounts? If you were specifying the spenders (principal, subaccount) as the to in the transfer_from, then you’d end up with funds in multiple subaccounts, and indeed incur fees consolidating them in a single subaccount later.

Hey,
The idea here would to be able - in case of big asynchronous application - to add approval, instead of resetting each time we call the method the allowance. It’s necessary for a lot of use cases, and for now it’s impossible, or you have to do it via a lot of subaccount, which is a bit unclean/complicated for no good reason.
Can we discuss that point ?
Gautier