#[cfg(test)]
mod transfer_tests {
use odra::casper_types::U256;
use odra::host::{Deployer, HostRef, NoArgs};
use odra::prelude::Addressable;
use crate::cep18::cep18_client_contract::Cep18ClientContract;
use crate::cep18::errors::Error::{CannotTargetSelfUser, InsufficientBalance};
use crate::cep18::events::{Transfer, TransferFrom};
use crate::cep18_token::tests::{
setup, ALLOWANCE_AMOUNT_1, TOKEN_TOTAL_SUPPLY, TRANSFER_AMOUNT_1
};
#[test]
fn should_transfer_full_owned_amount() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let alice = cep18_token.env().get_account(1);
let amount = TOKEN_TOTAL_SUPPLY.into();
cep18_token.transfer(&alice, &amount);
assert_eq!(cep18_token.balance_of(&owner), 0.into());
assert_eq!(cep18_token.balance_of(&alice), amount);
assert_eq!(cep18_token.total_supply(), amount);
assert!(cep18_token.env().emitted_event(
&cep18_token,
Transfer {
sender: owner,
recipient: alice,
amount
}
));
}
#[test]
fn should_not_transfer_more_than_owned_balance() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let alice = cep18_token.env().get_account(1);
let amount = TOKEN_TOTAL_SUPPLY.into();
let result = cep18_token.try_transfer(&alice, &(amount + 1));
assert_eq!(result.err().unwrap(), InsufficientBalance.into());
assert_eq!(cep18_token.balance_of(&owner), amount);
assert_eq!(cep18_token.balance_of(&alice), 0.into());
assert_eq!(cep18_token.total_supply(), amount);
}
#[test]
fn should_transfer_from_account_to_account() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let alice = cep18_token.env().get_account(1);
let transfer_amount = TRANSFER_AMOUNT_1.into();
let allowance_amount = ALLOWANCE_AMOUNT_1.into();
cep18_token.approve(&alice, &allowance_amount);
assert_eq!(cep18_token.allowance(&owner, &alice), allowance_amount);
cep18_token.env().set_caller(alice);
cep18_token.transfer_from(&owner, &alice, &transfer_amount);
assert_eq!(
cep18_token.balance_of(&owner),
U256::from(TOKEN_TOTAL_SUPPLY) - transfer_amount
);
assert_eq!(cep18_token.balance_of(&alice), transfer_amount);
assert_eq!(
cep18_token.allowance(&owner, &alice),
allowance_amount - transfer_amount
);
assert!(cep18_token.env().emitted_event(
&cep18_token,
TransferFrom {
spender: alice,
owner,
recipient: alice,
amount: transfer_amount
}
));
}
#[test]
fn should_only_change_allowance_between_owner_and_spender_on_transfer_from() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let spender = cep18_token.env().get_account(1);
let recipient = cep18_token.env().get_account(2);
let allowance_amount = ALLOWANCE_AMOUNT_1.into();
let transfer_amount = TRANSFER_AMOUNT_1.into();
cep18_token.approve(&spender, &allowance_amount);
cep18_token.env().set_caller(spender);
cep18_token.transfer_from(&owner, &recipient, &transfer_amount);
assert_eq!(
cep18_token.allowance(&owner, &spender),
allowance_amount - transfer_amount
);
assert_eq!(cep18_token.allowance(&owner, &recipient), U256::zero());
assert_eq!(cep18_token.allowance(&spender, &owner), U256::zero());
assert_eq!(cep18_token.allowance(&spender, &recipient), U256::zero());
assert_eq!(cep18_token.allowance(&recipient, &owner), U256::zero());
assert_eq!(cep18_token.allowance(&recipient, &spender), U256::zero());
}
#[test]
fn should_transfer_from_account_by_contract() {
let mut cep18_token = setup();
let client_contract = Cep18ClientContract::deploy(cep18_token.env(), NoArgs);
let spender = cep18_token.env().get_account(1);
let owner = cep18_token.env().get_account(0);
cep18_token.approve(&client_contract.address(), &ALLOWANCE_AMOUNT_1.into());
let spender_allowance_before = cep18_token.allowance(&owner, &client_contract.address());
let owner_balance_before = cep18_token.balance_of(&owner);
client_contract.transfer_from_as_stored_contract(
cep18_token.address(),
owner,
spender,
ALLOWANCE_AMOUNT_1.into()
);
assert_eq!(
spender_allowance_before - ALLOWANCE_AMOUNT_1,
cep18_token.allowance(&owner, &spender)
);
assert_eq!(
owner_balance_before - ALLOWANCE_AMOUNT_1,
cep18_token.balance_of(&owner)
);
assert_eq!(
U256::from(ALLOWANCE_AMOUNT_1),
cep18_token.balance_of(&spender)
);
}
#[test]
fn should_not_be_able_to_own_transfer() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let amount = TOKEN_TOTAL_SUPPLY.into();
let result = cep18_token.try_transfer(&owner, &amount);
assert_eq!(result.err().unwrap(), CannotTargetSelfUser.into());
assert_eq!(cep18_token.balance_of(&owner), amount);
assert_eq!(cep18_token.total_supply(), amount);
}
#[test]
fn should_not_be_able_to_own_transfer_from() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let amount = TOKEN_TOTAL_SUPPLY.into();
let result = cep18_token.try_transfer_from(&owner, &owner, &amount);
assert_eq!(result.err().unwrap(), CannotTargetSelfUser.into());
assert_eq!(cep18_token.balance_of(&owner), amount);
assert_eq!(cep18_token.total_supply(), amount);
}
#[test]
fn should_verify_zero_amount_transfer_is_noop() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let alice = cep18_token.env().get_account(1);
let amount = TOKEN_TOTAL_SUPPLY.into();
cep18_token.transfer(&alice, &U256::zero());
assert_eq!(cep18_token.balance_of(&owner), amount);
assert_eq!(cep18_token.balance_of(&alice), 0.into());
assert_eq!(cep18_token.total_supply(), amount);
}
#[test]
fn should_verify_zero_amount_transfer_from_is_noop() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let alice = cep18_token.env().get_account(1);
let amount = TOKEN_TOTAL_SUPPLY.into();
cep18_token.approve(&alice, &ALLOWANCE_AMOUNT_1.into());
cep18_token.transfer_from(&owner, &alice, &U256::zero());
assert_eq!(cep18_token.balance_of(&owner), amount);
assert_eq!(cep18_token.balance_of(&alice), 0.into());
assert_eq!(cep18_token.total_supply(), amount);
}
#[test]
fn should_transfer() {
let mut cep18_token = setup();
let owner = cep18_token.env().get_account(0);
let client_contract = Cep18ClientContract::deploy(cep18_token.env(), NoArgs);
cep18_token.transfer(&client_contract.address(), &TRANSFER_AMOUNT_1.into());
assert_eq!(
cep18_token.balance_of(&owner),
(TOKEN_TOTAL_SUPPLY - TRANSFER_AMOUNT_1).into()
);
assert_eq!(
cep18_token.balance_of(&client_contract.address()),
TRANSFER_AMOUNT_1.into()
);
client_contract.transfer_as_stored_contract(
cep18_token.address(),
cep18_token.address(),
TRANSFER_AMOUNT_1.into()
);
assert_eq!(cep18_token.balance_of(&client_contract.address()), 0.into());
assert_eq!(
cep18_token.balance_of(&cep18_token.address()),
TRANSFER_AMOUNT_1.into()
);
}
}