I am trying to port Ethereum's allowance function into Solana program,
token.allowance(msg.sender, address(this))
it seems there is no such allowance function existing in Solana SPL, or Anchor SPL... is there?
Solana SPL: https://spl.solana.com/token#authority-delegation ... Quote "Authority delegation# Account owners may delegate authority over some or all of their token balance using the Approve instruction. Delegated authorities may transfer or burn up to the amount they've been delegated. Authority delegation may be revoked by the Account's owner via the Revoke instruction." ... this does not say clearly how to use such a function
https://github.com/solana-labs/solana-program-library/blob/master/token/program/src/instruction.rs#L919 ... the approve function in is Rust, but it is difficult to be used
Anchor SPL https://docs.rs/anchor-spl/0.18.2/anchor_spl/token/struct.Approve.html I see Anchor makes calling Solana's approve function easier. but I could not find the allowance function.
https://docs.rs/anchor-spl/0.19.0/anchor_spl/token/index.html This is used to check token amounts on certain account. not allowance.
It seems in Solana, we do not need to check the allowance given from an user to another address... because I found this in Anchor's cashiers check test example:
// Transfer funds to the check.
let cpi_accounts = Transfer {
from: ctx.accounts.from.to_account_info().clone(),
to: ctx.accounts.vault.to_account_info().clone(),
authority: ctx.accounts.owner.clone(),
};
let cpi_program = ctx.accounts.token_program.clone();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::transfer(cpi_ctx, amount)?;
That example above does not check for user's given allowance on the program.
To answer your questions...
Does that mean any Solana program can transfer any user's tokens without their consent?
That would be quite a security flaw! The concept is that, when you transfer
tokens, some account must sign to validate the transfer. That account may be the owner, or some pre-approved delegate. In the exsample that you've shown, authority
is given as ctx.accounts.owner.clone()
, which means that the owner has likely already signed the transaction. If the owner approves some amount to a delegate, and then signs with that delegate, the token program figures out that the delegate has signed, and allows the transfer.
Why does the approve function exist if we cannot check the allowance?
To check the allowance, you'll have to deserialize the account into a token Account
https://docs.rs/anchor-spl/0.19.0/anchor_spl/token/struct.TokenAccount.html. You can use one of the helpers, like try_deserialize
, which gives you a type that wraps spl_token::state::Account
.
With your spl_token::state::Account
, you can check the delegated_amount
field to see how much has been approved by the user: https://github.com/solana-labs/solana-program-library/blob/8eb2c3ce60bfe943e277eb172ba8e9ce9b6bdae6/token/program/src/state.rs#L103