DEV Community

Maakai123
Maakai123

Posted on

Secure Generics Type Checking APTOS MOVE

Image description

Generics in Move allow functions and structs to work with different data types, like a universal key. But if you don’t verify the type, attackers could sneak in the wrong key, leading to unauthorized actions or transaction failures.

Real-World Example

Picture a dApp offering flash loans on Aptos. Users borrow coins (e.g., USD tokens) and must repay with a fee. Without checking the coin type, someone could borrow USD but repay with worthless “FakeCoin,” cheating the system! 😈Let’s see how this happens and how to fix it.

Insecure Code

This flash loan code doesn’t ensure the repaid Coin matches the borrowed type, allowing users to repay with any coin type.

module 0x42::example {
  struct Coin<T> { amount: u64 }
  struct Receipt { amount: u64 }

  public fun flash_loan<T>(user: &signer, amount: u64): (Coin<T>, Receipt) {
    let (coin, fee) = withdraw(user, amount);
    (coin, Receipt { amount: amount + fee })
  }

  public fun repay_flash_loan<T>(rec: Receipt, coins: Coin<T>) {
    let Receipt { amount } = rec;
    assert!(coin::value<T>(&coins) >= amount, 0);
    deposit(coins);
  }
}
Enter fullscreen mode Exit fullscreen mode

Problem: The Receipt struct isn’t tied to the coin type T, so users can repay a USD loan with any Coin, like a fake token. It’s like accepting a random gift card to settle a bank loan!

Secure Code ✅

Use Move’s type system (e.g., phantom types) to ensure the Receipt and Coin types match, preventing type mismatches.

module 0x42::example {
  struct Coin<T> { amount: u64 }
  struct Receipt<phantom T> { amount: u64 }

  public fun flash_loan<T>(_user: &signer, amount: u64): (Coin<T>, Receipt<T>) {
    let (coin, fee) = withdraw(_user, amount);
    (coin, Receipt { amount: amount + fee })
  }

  public fun repay_flash_loan<T>(rec: Receipt<T>, coins: Coin<T>) {
    let Receipt { amount } = rec;
    assert!(coin::value<T>(&coins) >= amount, 0);
    deposit(coins);
  }
}
Enter fullscreen mode Exit fullscreen mode

Fix: Adding phantom T to Receipt ensures the repaid Coin matches the borrowed type. It’s like requiring the exact currency for loan repayment—USD in, USD out!

Top comments (0)