From 1e09b19683e12c396af896e2680ab93af2f909e0 Mon Sep 17 00:00:00 2001 From: tomasavola <108414862+tomasavola@users.noreply.github.com> Date: Thu, 12 Sep 2024 10:49:00 -0300 Subject: [PATCH] add 27-token-interface-inference.md --- .../detectors/27-token-interface-inference.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/docs/detectors/27-token-interface-inference.md diff --git a/docs/docs/detectors/27-token-interface-inference.md b/docs/docs/detectors/27-token-interface-inference.md new file mode 100644 index 00000000..3e51a106 --- /dev/null +++ b/docs/docs/detectors/27-token-interface-inference.md @@ -0,0 +1,97 @@ +# 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 = + 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. + + + + + + + + + + +