Skip to content

Commit

Permalink
simple_vault test implementation (#220)
Browse files Browse the repository at this point in the history
  • Loading branch information
LamsyA authored Jul 19, 2024
1 parent 630092f commit 098f403
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 17 deletions.
1 change: 1 addition & 0 deletions listings/applications/simple_vault/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = '2023_11'

[dependencies]
starknet.workspace = true
erc20 = { path = "../erc20" }

[scripts]
test.workspace = true
Expand Down
1 change: 1 addition & 0 deletions listings/applications/simple_vault/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod simple_vault;


#[cfg(test)]
mod tests;
162 changes: 145 additions & 17 deletions listings/applications/simple_vault/src/simple_vault.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,34 @@ use starknet::ContractAddress;
// we need to have the interface of the remote ERC20 contract defined to import the Dispatcher.
#[starknet::interface]
pub trait IERC20<TContractState> {
fn name(self: @TContractState) -> felt252;
fn symbol(self: @TContractState) -> felt252;
fn decimals(self: @TContractState) -> u8;
fn total_supply(self: @TContractState) -> u256;
fn balance_of(self: @TContractState, account: ContractAddress) -> u256;
fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256;
fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256) -> bool;
fn get_name(self: @TContractState) -> felt252;
fn get_symbol(self: @TContractState) -> felt252;
fn get_decimals(self: @TContractState) -> u8;
fn get_total_supply(self: @TContractState) -> felt252;
fn balance_of(self: @TContractState, account: ContractAddress) -> felt252;
fn allowance(
self: @TContractState, owner: ContractAddress, spender: ContractAddress
) -> felt252;
fn transfer(ref self: TContractState, recipient: ContractAddress, amount: felt252);
fn transfer_from(
ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256
) -> bool;
fn approve(ref self: TContractState, spender: ContractAddress, amount: u256) -> bool;
ref self: TContractState,
sender: ContractAddress,
recipient: ContractAddress,
amount: felt252
);
fn approve(ref self: TContractState, spender: ContractAddress, amount: felt252);
fn increase_allowance(ref self: TContractState, spender: ContractAddress, added_value: felt252);
fn decrease_allowance(
ref self: TContractState, spender: ContractAddress, subtracted_value: felt252
);
}

#[starknet::interface]
pub trait ISimpleVault<TContractState> {
fn deposit(ref self: TContractState, amount: u256);
fn withdraw(ref self: TContractState, shares: u256);
fn user_balance_of(ref self: TContractState, account: ContractAddress) -> u256;
fn contract_total_supply(ref self: TContractState) -> u256;
}

#[starknet::contract]
Expand Down Expand Up @@ -51,11 +62,22 @@ pub mod SimpleVault {
self.total_supply.write(self.total_supply.read() - shares);
self.balance_of.write(from, self.balance_of.read(from) - shares);
}

}

#[abi(embed_v0)]
impl SimpleVault of super::ISimpleVault<ContractState> {
fn deposit(ref self: ContractState, amount: u256) {

fn user_balance_of(ref self: ContractState, account: ContractAddress) -> u256 {
self.balance_of.read(account)
}

fn contract_total_supply(ref self: ContractState) -> u256 {
self.total_supply.read()
}


fn deposit(ref self: ContractState, amount: u256){
// a = amount
// B = balance of token before deposit
// T = total supply
Expand All @@ -71,12 +93,15 @@ pub mod SimpleVault {
if self.total_supply.read() == 0 {
shares = amount;
} else {
let balance = self.token.read().balance_of(this);
let balance: u256 = self.token.read().balance_of(this).try_into()
.unwrap();
shares = (amount * self.total_supply.read()) / balance;
}

PrivateFunctions::_mint(ref self, caller, shares);
self.token.read().transfer_from(caller, this, amount);

PrivateFunctions::_mint(ref self, caller, shares);

let amount_felt252: felt252 = amount.low.into();
self.token.read().transfer_from(caller, this, amount_felt252);
}

fn withdraw(ref self: ContractState, shares: u256) {
Expand All @@ -91,11 +116,114 @@ pub mod SimpleVault {
let caller = get_caller_address();
let this = get_contract_address();

let balance = self.token.read().balance_of(this);
let balance = self.user_balance_of(this);
let amount = (shares * balance) / self.total_supply.read();
PrivateFunctions::_burn(ref self, caller, shares);
self.token.read().transfer(caller, amount);
let amount_felt252: felt252 = amount.low.into();
self.token.read().transfer(caller, amount_felt252);
}
}
}
// ANCHOR_END: simple_vault

#[cfg(test)]
mod tests {
use core::traits::Into;
use super::{
SimpleVault, ISimpleVaultDispatcher, ISimpleVaultDispatcherTrait, IERC20Dispatcher,
IERC20DispatcherTrait
};

// use erc20::token::IERC20;
use erc20::token::{IERC20DispatcherTrait as IERC20DispatcherTrait_token,
IERC20Dispatcher as IERC20Dispatcher_token
};

use core::num::traits::Zero;

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

const token_name: felt252 = 'myToken';
const decimals: u8 = 18;
const initial_supply: felt252 = 100000;
const symbols: felt252 = 'mtk';

fn deploy() -> (ISimpleVaultDispatcher, ContractAddress, IERC20Dispatcher_token) {
let _token_address: ContractAddress = contract_address_const::<'token_address'>();
let caller = contract_address_const::<'caller'>();

let (token_contract_address, _) = deploy_syscall(
erc20::token::erc20::TEST_CLASS_HASH.try_into().unwrap(),
caller.into(),
array![caller.into(), 'myToken', '8', '1000'.into(), 'MYT'].span(),
false
)
.unwrap_syscall();

let (contract_address, _) = deploy_syscall(
SimpleVault::TEST_CLASS_HASH.try_into().unwrap(),
0,
array![token_contract_address.into()].span(),
false
)
.unwrap_syscall();

(
ISimpleVaultDispatcher { contract_address },
contract_address,
IERC20Dispatcher_token { contract_address: token_contract_address }
)
}

#[test]
fn test_deposit() {
let caller = contract_address_const::<'caller'>();
let (dispatcher, vault_address, token_dispatcher) = deploy();

// Approve the vault to transfer tokens on behalf of the caller
let amount: felt252 = 10.into();
token_dispatcher.approve(vault_address.into(), amount);
set_contract_address(caller);

// Deposit tokens into the vault
let amount: u256 = 10.into();
let _deposit = dispatcher.deposit(amount);
println!("deposit :{:?}", _deposit);

// Check balances and total supply
let balance_of_caller = dispatcher.user_balance_of(caller);
let total_supply = dispatcher.contract_total_supply();

assert(balance_of_caller == amount, 'Deposit failed');
assert(total_supply == amount, 'total supply mismatch');

}

#[test]
fn test_deposit_withdraw() {
let caller = contract_address_const::<'caller'>();
let (dispatcher, vault_address, token_dispatcher) = deploy();

// Approve the vault to transfer tokens on behalf of the caller
let amount: felt252 = 10.into();
token_dispatcher.approve(vault_address.into(), amount);
set_contract_address(caller);
set_account_contract_address(vault_address);

// Deposit tokens into the vault
let amount: u256 = 10.into();
dispatcher.deposit(amount);
dispatcher.withdraw(amount);

// Check balances of user in the vault after withdraw
let balance_of_caller = dispatcher.user_balance_of(caller);

assert(balance_of_caller == 0.into(), 'withdraw failed');
}


}

0 comments on commit 098f403

Please sign in to comment.