Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
5.2 kB
2
Indexable
Never
#[starknet::interface]
pub trait IBankAccount<TContractState> {
    fn deposit(ref self: TContractState, address: starknet::ContractAddress, amount: u128);
    fn withdraw(ref self: TContractState, address: starknet::ContractAddress, amount: u128);
    fn get_balance(self: @TContractState, address: starknet::ContractAddress) -> u128;
    fn transfer(ref self: TContractState, from: starknet::ContractAddress, to: starknet::ContractAddress, amount: u128);
}

#[starknet::contract]
pub mod BankAccount {
    use starknet::{get_caller_address, ContractAddress};

    #[storage]
    struct Storage {
        balances: LegacyMap<ContractAddress, u128>,
    }

    #[constructor]
    pub fn constructor(ref self: ContractState, initial_balance: u128, _contract_address: ContractAddress) {
        self.balances.write(_contract_address, initial_balance);
    }

    #[abi(embed_v0)]
    pub impl BackAccountImpl of super::IBankAccount<ContractState> {

        fn deposit(ref self: ContractState, address: ContractAddress, amount: u128) {
            let _balance = self.balances.read(address);
            self.balances.write(address, _balance + amount);
        }

        fn get_balance(self: @ContractState, address: ContractAddress) -> u128 {
            self.balances.read(address)
        }

        fn withdraw(ref self: ContractState, address: ContractAddress, amount: u128) {
            let _balance = self.balances.read(address);
            if _balance < amount {
                panic!("Insufficient funds");
            }
            self.balances.write(address, _balance - amount);
        }

        fn transfer(ref self: ContractState, from: ContractAddress, to: ContractAddress, amount: u128) {
            let _from_balance = self.balances.read(from);
            if _from_balance < amount {
                panic!("From account has insufficient funds");
            }
            let _to_balance = self.balances.read(to);
            self.balances.write(from, _from_balance - amount);
            self.balances.write(to, _to_balance + amount);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{BankAccount, IBankAccountDispatcher, IBankAccountDispatcherTrait};

    use starknet::{SyscallResultTrait, syscalls::deploy_syscall};
    use starknet::{ContractAddress, contract_address_const};
    use starknet::testing::set_contract_address;

    fn deploy(initial_balance: u128, contract_address: ContractAddress) -> IBankAccountDispatcher {
        let (contract_address, _) = deploy_syscall(
            BankAccount::TEST_CLASS_HASH.try_into().unwrap(),
            0,
            array![initial_balance.into(), contract_address.into()].span(),
            false
        )
            .unwrap_syscall();
        IBankAccountDispatcher { contract_address }
    }

    #[test]
    fn test_deploy() {
        let initial_balance = 100;
        let contract_address = contract_address_const::<'default'>();

        let bank_account = deploy(initial_balance, contract_address);
        assert_eq!(bank_account.get_balance(contract_address), initial_balance);   
    }

    #[test]
    fn test_desposit() {
        let initial_balance = 100;
        let contract_address = contract_address_const::<'default'>();
        let bank_account = deploy(initial_balance, contract_address);
        let deposit_amount = 100;
        bank_account.deposit(contract_address, deposit_amount);
        assert_eq!(bank_account.get_balance(contract_address), initial_balance + deposit_amount);
    }

    #[test]
    fn test_withdraw() {
        let initial_balance = 100;
        let contract_address = contract_address_const::<'default'>();
        let bank_account = deploy(initial_balance, contract_address);
        let withdraw_amount = 50;
        bank_account.withdraw(contract_address, withdraw_amount);
        assert_eq!(bank_account.get_balance(contract_address), initial_balance - withdraw_amount);
    }

    #[test]
    fn test_transfer() {
        let initial_balance = 100;
        let from_contract_address = contract_address_const::<'from'>();
        let to_contract_address = contract_address_const::<'to'>();
    
        let bank_account = deploy(initial_balance, from_contract_address);

        assert_eq!(bank_account.get_balance(from_contract_address), initial_balance);
        assert_eq!(bank_account.get_balance(to_contract_address), 0);

        let transfer_amount = 50;
        bank_account.transfer(from_contract_address, to_contract_address, transfer_amount);

        assert_eq!(bank_account.get_balance(from_contract_address), initial_balance - transfer_amount);
        assert_eq!(bank_account.get_balance(to_contract_address), transfer_amount);
    }

    #[test]
    #[should_panic]
    fn test_withdraw_insufficient_funds() {
        let initial_balance = 100;
        let contract_address = contract_address_const::<'default'>();
        let bank_account = deploy(initial_balance, contract_address);
        let withdraw_amount = 150;
        bank_account.withdraw(contract_address, withdraw_amount);
    }
}


fn main() {
    println!("Hello, world!");
}
Leave a Comment