-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
293 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub mod interfaces; | ||
pub mod mocks; | ||
|
||
#[starknet::contract] | ||
mod StakingRewards { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod mock_reward_token; | ||
pub mod mock_staking_token; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#[starknet::contract] | ||
pub mod RewardToken { | ||
use starknet::event::EventEmitter; | ||
use starknet::{ContractAddress, get_caller_address}; | ||
use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess, Map, StoragePathEntry}; | ||
use synthetix_staking::interfaces::ierc20::IERC20; | ||
use core::num::traits::Zero; | ||
|
||
#[storage] | ||
pub struct Storage { | ||
balances: Map<ContractAddress, u256>, | ||
allowances: Map<(ContractAddress, ContractAddress), u256>, // Mapping<(owner, spender), amount> | ||
token_name: ByteArray, | ||
symbol: ByteArray, | ||
decimal: u8, | ||
total_supply: u256, | ||
owner: ContractAddress, | ||
} | ||
|
||
#[event] | ||
#[derive(Drop, starknet::Event)] | ||
pub enum Event { | ||
Transfer: Transfer, | ||
Approval: Approval, | ||
} | ||
|
||
#[derive(Drop, starknet::Event)] | ||
pub struct Transfer { | ||
#[key] | ||
from: ContractAddress, | ||
#[key] | ||
to: ContractAddress, | ||
amount: u256, | ||
} | ||
|
||
#[derive(Drop, starknet::Event)] | ||
pub struct Approval { | ||
#[key] | ||
owner: ContractAddress, | ||
#[key] | ||
spender: ContractAddress, | ||
value: u256 | ||
} | ||
|
||
#[constructor] | ||
fn constructor(ref self: ContractState) { | ||
self.token_name.write("Reward Token"); | ||
self.symbol.write("RWT"); | ||
self.decimal.write(18); | ||
self.owner.write(get_caller_address()); | ||
} | ||
|
||
#[abi(embed_v0)] | ||
impl RewardTokenImpl of IERC20<ContractState> { | ||
fn total_supply(self: @ContractState) -> u256 { | ||
self.total_supply.read() | ||
} | ||
|
||
fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { | ||
let balance = self.balances.entry(account).read(); | ||
|
||
balance | ||
} | ||
|
||
fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { | ||
let allowance = self.allowances.entry((owner, spender)).read(); | ||
|
||
allowance | ||
} | ||
|
||
fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { | ||
let sender = get_caller_address(); | ||
|
||
let sender_prev_balance = self.balances.entry(sender).read(); | ||
let recipient_prev_balance = self.balances.entry(recipient).read(); | ||
|
||
assert(sender_prev_balance >= amount, 'Insufficient amount'); | ||
|
||
self.balances.entry(sender).write(sender_prev_balance - amount); | ||
self.balances.entry(recipient).write(recipient_prev_balance + amount); | ||
|
||
assert(self.balances.entry(recipient).read() > recipient_prev_balance, 'Transaction failed'); | ||
|
||
self.emit(Transfer { from: sender, to: recipient, amount }); | ||
|
||
true | ||
} | ||
|
||
fn transfer_from(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool { | ||
let spender = get_caller_address(); | ||
|
||
let spender_allowance = self.allowances.entry((sender, spender)).read(); | ||
let sender_balance = self.balances.entry(sender).read(); | ||
let recipient_balance = self.balances.entry(recipient).read(); | ||
|
||
assert(amount <= spender_allowance, 'amount exceeds allowance'); | ||
assert(amount <= sender_balance, 'amount exceeds balance'); | ||
|
||
self.allowances.entry((sender, spender)).write(spender_allowance - amount); | ||
self.balances.entry(sender).write(sender_balance - amount); | ||
self.balances.entry(recipient).write(recipient_balance + amount); | ||
|
||
self.emit(Transfer { from: sender, to: recipient, amount }); | ||
|
||
true | ||
} | ||
|
||
fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool { | ||
let caller = get_caller_address(); | ||
|
||
self.allowances.entry((caller, spender)).write(amount); | ||
|
||
self.emit(Approval { owner: caller, spender, value: amount }); | ||
|
||
true | ||
} | ||
|
||
fn name(self: @ContractState) -> ByteArray { | ||
self.token_name.read() | ||
} | ||
|
||
fn symbol(self: @ContractState) -> ByteArray { | ||
self.symbol.read() | ||
} | ||
|
||
fn decimals(self: @ContractState) -> u8 { | ||
self.decimal.read() | ||
} | ||
|
||
fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { | ||
let previous_total_supply = self.total_supply.read(); | ||
let previous_balance = self.balances.entry(recipient).read(); | ||
|
||
self.total_supply.write(previous_total_supply + amount); | ||
self.balances.entry(recipient).write(previous_balance + amount); | ||
|
||
let zero_address = Zero::zero(); | ||
|
||
self.emit(Transfer { from: zero_address, to: recipient, amount }); | ||
|
||
true | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#[starknet::contract] | ||
pub mod StakingToken { | ||
use starknet::event::EventEmitter; | ||
use starknet::{ContractAddress, get_caller_address}; | ||
use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess, Map, StoragePathEntry}; | ||
use synthetix_staking::interfaces::ierc20::IERC20; | ||
use core::num::traits::Zero; | ||
|
||
#[storage] | ||
pub struct Storage { | ||
balances: Map<ContractAddress, u256>, | ||
allowances: Map<(ContractAddress, ContractAddress), u256>, // Mapping<(owner, spender), amount> | ||
token_name: ByteArray, | ||
symbol: ByteArray, | ||
decimal: u8, | ||
total_supply: u256, | ||
owner: ContractAddress, | ||
} | ||
|
||
#[event] | ||
#[derive(Drop, starknet::Event)] | ||
pub enum Event { | ||
Transfer: Transfer, | ||
Approval: Approval, | ||
} | ||
|
||
#[derive(Drop, starknet::Event)] | ||
pub struct Transfer { | ||
#[key] | ||
from: ContractAddress, | ||
#[key] | ||
to: ContractAddress, | ||
amount: u256, | ||
} | ||
|
||
#[derive(Drop, starknet::Event)] | ||
pub struct Approval { | ||
#[key] | ||
owner: ContractAddress, | ||
#[key] | ||
spender: ContractAddress, | ||
value: u256 | ||
} | ||
|
||
#[constructor] | ||
fn constructor(ref self: ContractState) { | ||
self.token_name.write("Staking Token"); | ||
self.symbol.write("SKT"); | ||
self.decimal.write(18); | ||
self.owner.write(get_caller_address()); | ||
} | ||
|
||
#[abi(embed_v0)] | ||
impl StakingTokenImpl of IERC20<ContractState> { | ||
fn total_supply(self: @ContractState) -> u256 { | ||
self.total_supply.read() | ||
} | ||
|
||
fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { | ||
let balance = self.balances.entry(account).read(); | ||
|
||
balance | ||
} | ||
|
||
fn allowance(self: @ContractState, owner: ContractAddress, spender: ContractAddress) -> u256 { | ||
let allowance = self.allowances.entry((owner, spender)).read(); | ||
|
||
allowance | ||
} | ||
|
||
fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { | ||
let sender = get_caller_address(); | ||
|
||
let sender_prev_balance = self.balances.entry(sender).read(); | ||
let recipient_prev_balance = self.balances.entry(recipient).read(); | ||
|
||
assert(sender_prev_balance >= amount, 'Insufficient amount'); | ||
|
||
self.balances.entry(sender).write(sender_prev_balance - amount); | ||
self.balances.entry(recipient).write(recipient_prev_balance + amount); | ||
|
||
assert(self.balances.entry(recipient).read() > recipient_prev_balance, 'Transaction failed'); | ||
|
||
self.emit(Transfer { from: sender, to: recipient, amount }); | ||
|
||
true | ||
} | ||
|
||
fn transfer_from(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool { | ||
let spender = get_caller_address(); | ||
|
||
let spender_allowance = self.allowances.entry((sender, spender)).read(); | ||
let sender_balance = self.balances.entry(sender).read(); | ||
let recipient_balance = self.balances.entry(recipient).read(); | ||
|
||
assert(amount <= spender_allowance, 'amount exceeds allowance'); | ||
assert(amount <= sender_balance, 'amount exceeds balance'); | ||
|
||
self.allowances.entry((sender, spender)).write(spender_allowance - amount); | ||
self.balances.entry(sender).write(sender_balance - amount); | ||
self.balances.entry(recipient).write(recipient_balance + amount); | ||
|
||
self.emit(Transfer { from: sender, to: recipient, amount }); | ||
|
||
true | ||
} | ||
|
||
fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool { | ||
let caller = get_caller_address(); | ||
|
||
self.allowances.entry((caller, spender)).write(amount); | ||
|
||
self.emit(Approval { owner: caller, spender, value: amount }); | ||
|
||
true | ||
} | ||
|
||
fn name(self: @ContractState) -> ByteArray { | ||
self.token_name.read() | ||
} | ||
|
||
fn symbol(self: @ContractState) -> ByteArray { | ||
self.symbol.read() | ||
} | ||
|
||
fn decimals(self: @ContractState) -> u8 { | ||
self.decimal.read() | ||
} | ||
|
||
fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { | ||
let previous_total_supply = self.total_supply.read(); | ||
let previous_balance = self.balances.entry(recipient).read(); | ||
|
||
self.total_supply.write(previous_total_supply + amount); | ||
self.balances.entry(recipient).write(previous_balance + amount); | ||
|
||
let zero_address = Zero::zero(); | ||
|
||
self.emit(Transfer { from: zero_address, to: recipient, amount }); | ||
|
||
true | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters