# Token interface inference ## Description - Category: `Best practices` - Severity: `Enhancement` - Detector: [`token-interface-inference`](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/token-interface-inference) - Test Cases: [`token-interface-inference-1`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/token-interface-inference/token-interface-inference-1) In Rust, the use of tokens requires strictly following a set of specifications. If any of these are not met, the contract will have errors and fail. Therefore, the use of the `soroban_sdk::token::TokenInterface` trait is really useful because it warns if any of the specifications are not being fulfilled. ## Why is this bad? Not using the `soroban_sdk::token::TokenInterface` trait makes it more difficult to comply with the token interface. ## Issue example Consider the following `Soroban` contract: ```rust #[contract] pub struct TokenInterfaceInference; #[contractimpl] impl TokenInterfaceInference { pub fn initialize( env: Env, admin: Address, decimals: u32, name: String, symbol: String, ) -> Result<(), TIIError> { let current_token_metadata: Option<TokenMetadata> = env.storage().instance().get(&DataKey::TokenMetadata); if current_token_metadata.is_some() { return Err(TIIError::AlreadyInitialized); } else { env.storage().instance().set( &DataKey::TokenMetadata, &TokenMetadata { decimals, name, symbol, admin, }, ); } Ok(()) } ``` In this example, the trait `soroban_sdk::token::TokenInterface` is not implemented; instead, a contract named "TokenInterfaceInference" is implemented. The code example can be found [here](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/token-interface-inference/token-interface-inference-1/vulnerable-example). ## Remediated example Consider the following `Soroban` contract: ```rust #[contractimpl] impl token::TokenInterface for TokenInterfaceEvents { fn allowance(env: Env, from: Address, spender: Address) -> i128 { let allowance = Self::get_allowance(env.clone(), from, spender); if allowance.expiration_ledger < env.ledger().sequence() { 0 } else { allowance.amount } } ``` In this example, the trait `soroban_sdk::token::TokenInterface` is implemented on a contract called "TokenInterfaceEvents". The remediated code example can be found [here](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/token-interface-inference/token-interface-inference-1/remediated-example). ## How is it detected? Checks if token handling is being implemented in the contract and warns if the trait `soroban_sdk::token::TokenInterface` is not being used.