Skip to content

Commit

Permalink
implement the erc20 part and start working on the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
moodysalem committed May 16, 2024
1 parent 4f93c15 commit 9d36340
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 13 deletions.
84 changes: 71 additions & 13 deletions src/fungible_staked_token.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ pub trait IFungibleStakedToken<TContractState> {
// Returns the address of the staker that this staked token wrapper uses
fn get_staker(self: @TContractState) -> ContractAddress;

// Returns the address of the token that this fungible staked wrapper stakes
fn get_token(self: @TContractState) -> ContractAddress;

// Get the address to whom the owner is delegated to
fn get_delegated_to(self: @TContractState, owner: ContractAddress) -> ContractAddress;

Expand All @@ -26,12 +23,11 @@ pub trait IFungibleStakedToken<TContractState> {

// Same as above but with a specified amount
fn deposit_amount(ref self: TContractState, amount: u128);
// // Withdraws the entire staked balance from the contract from the caller
// fn withdraw(ref self: TContractState);

// Withdraws the entire staked balance from the contract from the caller
fn withdraw(ref self: TContractState);

// Withdraws the specified amount of token from the contract from the caller
fn withdraw_amount(ref self: TContractState, amount: u128);
// // Withdraws the specified amount of token from the contract from the caller
// fn withdraw_amount(ref self: TContractState, amount: u128);
}

#[starknet::contract]
Expand All @@ -51,6 +47,8 @@ pub mod FungibleStakedToken {
total_staked: u128,
last_seconds_per_total_staked_time: u64,
seconds_per_total_staked: felt252,
balances: LegacyMap<ContractAddress, u128>,
allowances: LegacyMap<(ContractAddress, ContractAddress), u128>,
}

#[constructor]
Expand All @@ -77,12 +75,27 @@ pub mod FungibleStakedToken {
pub to: ContractAddress,
}

#[derive(starknet::Event, PartialEq, Debug, Drop)]
pub struct Transfer {
pub from: ContractAddress,
pub to: ContractAddress,
pub amount: u256,
}
#[derive(starknet::Event, PartialEq, Debug, Drop)]
pub struct Approval {
pub owner: ContractAddress,
pub spender: ContractAddress,
pub amount: u256,
}

#[derive(starknet::Event, Drop)]
#[event]
enum Event {
Deposit: Deposit,
Withdrawal: Withdrawal,
Delegation: Delegation,
Transfer: Transfer,
Approval: Approval,
}

#[generate_trait]
Expand All @@ -100,18 +113,63 @@ pub mod FungibleStakedToken {
}

#[abi(embed_v0)]
impl FungibleStakedTokenERC20 of IERC20<ContractState> {}
impl FungibleStakedTokenERC20 of IERC20<ContractState> {
fn balanceOf(self: @ContractState, account: ContractAddress) -> u256 {
self.balances.read(account).into()
}
fn allowance(
self: @ContractState, owner: ContractAddress, spender: ContractAddress
) -> u256 {
self.allowances.read((owner, spender)).into()
}
fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool {
let from = get_caller_address();
let balance = self.balances.read(from);
assert(balance.into() >= amount, 'INSUFFICIENT_BALANCE');
let small_amount: u128 = amount.try_into().unwrap();
self.balances.write(from, balance - small_amount);
self.balances.write(recipient, self.balances.read(recipient) + small_amount);
self.emit(Transfer { from, to: recipient, amount: amount });
self.move_delegates(from, recipient, small_amount);
true
}
fn transferFrom(
ref self: ContractState,
sender: ContractAddress,
recipient: ContractAddress,
amount: u256
) -> bool {
let spender = get_caller_address();
let allowance = self.allowances.read((sender, spender));
assert(allowance.into() >= amount, 'INSUFFICIENT_ALLOWANCE');
let small_amount: u128 = amount.try_into().unwrap();
self.allowances.write((sender, spender), allowance - small_amount);

let balance = self.balances.read(sender);

self.balances.write(sender, balance - small_amount);
self.balances.write(recipient, self.balances.read(recipient) + small_amount);
self.emit(Transfer { from: sender, to: recipient, amount: amount });

self.move_delegates(sender, recipient, small_amount);

true
}
fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool {
let owner = get_caller_address();
let small_amount: u128 = amount.try_into().expect('AMOUNT_EXCEEDS_U128');
self.allowances.write((owner, spender), small_amount);
self.emit(Approval { owner, spender, amount });
true
}
}

#[abi(embed_v0)]
impl FungibleStakedTokenImpl of IFungibleStakedToken<ContractState> {
fn get_staker(self: @ContractState) -> ContractAddress {
self.staker.read().contract_address
}

fn get_token(self: @ContractState) -> ContractAddress {
self.staker.read().get_token()
}

fn get_delegated_to(self: @ContractState, owner: ContractAddress) -> ContractAddress {
self.delegated_to.read(owner)
}
Expand Down
53 changes: 53 additions & 0 deletions src/fungible_staked_token_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use core::array::SpanTrait;
use core::array::{ArrayTrait};
use core::num::traits::zero::{Zero};
use core::option::{OptionTrait};

use core::result::{Result, ResultTrait};
use core::serde::Serde;
use core::traits::{TryInto};

use governance::execution_state::{ExecutionState};
use governance::fungible_staked_token::{
IFungibleStakedToken, IFungibleStakedTokenDispatcher, IFungibleStakedTokenDispatcherTrait,
FungibleStakedToken
};
use governance::interfaces::erc20::{IERC20Dispatcher, IERC20DispatcherTrait};
use governance::staker::{IStakerDispatcher, IStakerDispatcherTrait};
use governance::staker_test::{setup as setup_staker};
use starknet::account::{Call};
use starknet::{
get_contract_address, syscalls::deploy_syscall, ClassHash, contract_address_const,
ContractAddress, get_block_timestamp,
testing::{set_block_timestamp, set_contract_address, pop_log}
};


fn deploy(staker: IStakerDispatcher) -> IFungibleStakedTokenDispatcher {
let mut constructor_args: Array<felt252> = ArrayTrait::new();
Serde::serialize(@(staker), ref constructor_args);

let (address, _) = deploy_syscall(
FungibleStakedToken::TEST_CLASS_HASH.try_into().unwrap(), 0, constructor_args.span(), true
)
.expect('DEPLOY_GV_FAILED');
return IFungibleStakedTokenDispatcher { contract_address: address };
}

fn setup() -> (IStakerDispatcher, IERC20Dispatcher, IFungibleStakedTokenDispatcher) {
let (staker, token) = setup_staker(1000000);
let fungible_staked_token = deploy(staker);

(staker, token, fungible_staked_token)
}


#[test]
fn test_setup() {
let (staker, token, fst) = setup();

assert_eq!(fst.get_staker(), staker.contract_address);
assert_eq!(
IStakerDispatcher { contract_address: fst.get_staker() }.get_token(), token.contract_address
);
}
2 changes: 2 additions & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub mod execution_state;
#[cfg(test)]
pub(crate) mod execution_state_test;
pub mod fungible_staked_token;
#[cfg(test)]
pub mod fungible_staked_token_test;
pub mod governor;
#[cfg(test)]
pub(crate) mod governor_test;
Expand Down

0 comments on commit 9d36340

Please sign in to comment.