diff --git a/contracts/token/Cargo.toml b/contracts/token/Cargo.toml index 792f2a620..aa9a66a29 100644 --- a/contracts/token/Cargo.toml +++ b/contracts/token/Cargo.toml @@ -16,7 +16,7 @@ stylus-proc = { version = "0.4.3", default-features = false } mini-alloc = "0.4.2" [dev-dependencies] -wavm-shims = { path = "../../lib/wavm-shims" } +test-utils = { path = "../test-utils" } [features] default = [] diff --git a/contracts/token/src/erc20/mod.rs b/contracts/token/src/erc20/mod.rs index 925d58e2a..81beacacc 100644 --- a/contracts/token/src/erc20/mod.rs +++ b/contracts/token/src/erc20/mod.rs @@ -358,48 +358,87 @@ mod tests { storage::{StorageMap, StorageType, StorageU256}, }; #[allow(unused_imports)] - use wavm_shims::*; + use test_utils::*; - use crate::erc20::ERC20; + use crate::erc20::{Error, ERC20}; - fn init_token() -> ERC20 { - let root = U256::ZERO; - let token = ERC20 { - _balances: unsafe { StorageMap::new(root, 0) }, - _allowances: unsafe { StorageMap::new(root + U256::from(32), 0) }, - _total_supply: unsafe { - StorageU256::new(root + U256::from(64), 0) - }, - }; + impl Default for ERC20 { + fn default() -> Self { + let root = U256::ZERO; + let token = ERC20 { + _balances: unsafe { StorageMap::new(root, 0) }, + _allowances: unsafe { + StorageMap::new(root + U256::from(32), 0) + }, + _total_supply: unsafe { + StorageU256::new(root + U256::from(64), 0) + }, + }; - token + token + } } #[test] fn reads_balance() { - let token = init_token(); - let balance = token.balance_of(Address::ZERO); - assert_eq!(balance, U256::ZERO); + test_utils::with_storage::(|token| { + let balance = token.balance_of(Address::ZERO); + assert_eq!(balance, U256::ZERO); + }) } #[test] fn transfers_from() { - let mut token = init_token(); - let alice = address!("A11CEacF9aa32246d767FCCD72e02d6bCbcC375d"); - let bob = address!("B0B0cB49ec2e96DF5F5fFB081acaE66A2cBBc2e2"); + test_utils::with_storage::(|token| { + let alice = address!("A11CEacF9aa32246d767FCCD72e02d6bCbcC375d"); + let bob = address!("B0B0cB49ec2e96DF5F5fFB081acaE66A2cBBc2e2"); + + // Alice approves `msg::sender`. + let one = U256::from(1); + token._allowances.setter(alice).setter(msg::sender()).set(one); + + // Mint some tokens for Alice. + let two = U256::from(2); + token._balances.setter(alice).set(two); + assert_eq!(two, token.balance_of(alice)); - // Alice approves `msg::sender`. - let one = U256::from(1); - token._allowances.setter(alice).setter(msg::sender()).set(one); + token.transfer_from(alice, bob, one).unwrap(); - // Mint some tokens for Alice. - let two = U256::from(2); - token._balances.setter(alice).set(two); - assert_eq!(two, token.balance_of(alice)); + assert_eq!(one, token.balance_of(alice)); + assert_eq!(one, token.balance_of(bob)); + }) + } + + #[test] + fn transfer_errors_when_insufficient_balance() { + test_utils::with_storage::(|token| { + let alice = address!("A11CEacF9aa32246d767FCCD72e02d6bCbcC375d"); + let bob = address!("B0B0cB49ec2e96DF5F5fFB081acaE66A2cBBc2e2"); + + // Alice approves `msg::sender`. + let one = U256::from(1); + token._allowances.setter(alice).setter(msg::sender()).set(one); + assert_eq!(U256::ZERO, token.balance_of(alice)); + + let one = U256::from(1); + let result = token.transfer_from(alice, bob, one); + assert!(matches!(result, Err(Error::InsufficientBalance(_)))); + }) + } + + #[test] + fn transfer_errors_when_insufficient_allowance() { + test_utils::with_storage::(|token| { + let alice = address!("A11CEacF9aa32246d767FCCD72e02d6bCbcC375d"); + let bob = address!("B0B0cB49ec2e96DF5F5fFB081acaE66A2cBBc2e2"); - token.transfer_from(alice, bob, one).unwrap(); + // Mint some tokens for Alice. + let one = U256::from(1); + token._balances.setter(alice).set(one); + assert_eq!(one, token.balance_of(alice)); - assert_eq!(one, token.balance_of(alice)); - assert_eq!(one, token.balance_of(bob)); + let result = token.transfer_from(alice, bob, one); + assert!(matches!(result, Err(Error::InsufficientAllowance(_)))); + }) } }