Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Code generated by scarb DO NOT EDIT.
version = 1

[[package]]
name = "alexandria_storage"
version = "0.2.0"
source = "git+https://github.com/keep-starknet-strange/alexandria.git?tag=cairo-v2.3.0-rc0#ae1d5149ff601a7ac5b39edc867d33ebd83d7f4f"

[[package]]
name = "openzeppelin"
version = "0.8.0"
Expand All @@ -15,6 +20,7 @@ source = "git+https://github.com/astraly-labs/pragma-lib#24bb4da111ae7eb00e7cf40
name = "shisui"
version = "0.1.0"
dependencies = [
"alexandria_storage",
"openzeppelin",
"pragma_lib",
"snforge_std",
Expand Down
1 change: 1 addition & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ starknet = "2.4.0"
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.13.0" }
openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.8.0" }
pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib"}
alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git", tag="cairo-v2.3.0-rc0"}

[[target.starknet-contract]]
sierra = true
Expand Down
54 changes: 0 additions & 54 deletions src/components/shisui_base.cairo

This file was deleted.

224 changes: 147 additions & 77 deletions src/core/debt_token.cairo
Original file line number Diff line number Diff line change
@@ -1,111 +1,181 @@
use starknet::ContractAddress;


#[starknet::interface]
trait IDebtToken<TContractState> {
fn emergency_stop_minting(ref self: TContractState, _delay: u256);

fn mint(
ref self: TContractState, _asset: ContractAddress, _account: ContractAddress, _amount: u256
);

fn mint_from_whitelisted_contract(ref self: TContractState, _amount: u256);
fn mint(ref self: TContractState, account: ContractAddress, amount: u256);

fn burn_from_whitelisted_contract(ref self: TContractState, _amount: u256);
fn mint_from_whitelisted_contract(ref self: TContractState, amount: u256);

fn burn(ref self: TContractState, _account: ContractAddress, _amount: u256);
fn burn_from_whitelisted_contract(ref self: TContractState, amount: u256);

fn send_to_pool(
ref self: TContractState,
_sender: ContractAddress,
poolAddress: ContractAddress,
_amount: u256
);
fn burn(ref self: TContractState, account: ContractAddress, amount: u256);

fn return_from_pool(
ref self: TContractState, poolAddress: ContractAddress, user: ContractAddress, _amount: u256
);
fn add_whitelist(ref self: TContractState, address: ContractAddress);

fn add_whitelist(ref self: TContractState, _address: ContractAddress);
fn remove_whitelist(ref self: TContractState, address: ContractAddress);

fn remove_whitelist(ref self: TContractState, _address: ContractAddress);

fn transfer(ref self: TContractState, _recipient: ContractAddress, _amount: u256);

fn transfer_from(
ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256
);
fn is_whitelisted(self: @TContractState, address: ContractAddress) -> bool;
}


#[starknet::contract]
mod DebtToken {
use starknet::ContractAddress;

use core::starknet::event::EventEmitter;
use openzeppelin::access::ownable::ownable::OwnableComponent::InternalTrait as OwnableInternalTrait;
use shisui::core::debt_token::IDebtToken;
use openzeppelin::token::erc20::erc20::ERC20Component::InternalTrait as ERC20InternalTrait;
use shisui::core::address_provider::IAddressProviderDispatcherTrait;
use starknet::{ContractAddress, get_caller_address};
use openzeppelin::{
access::ownable::{OwnableComponent, OwnableComponent::InternalImpl},
token::erc20::ERC20Component
};
use shisui::{
utils::errors::{CommunErrors, DebtTokenErrors},
core::address_provider::{IAddressProviderDispatcher, AddressesKey}
};

component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
component!(path: ERC20Component, storage: erc20, event: ERC20Event);

#[abi(embed_v0)]
impl OwnableImp = OwnableComponent::OwnableImpl<ContractState>;
#[abi(embed_v0)]
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;

#[storage]
struct Storage {
address_provider: ContractAddress,
emergency_stop_minting_collateral: LegacyMap::<ContractAddress, bool>,
whitelisted_contracts: LegacyMap::<ContractAddress, bool>,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
#[substorage(v0)]
erc20: ERC20Component::Storage
}

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
OwnableEvent: OwnableComponent::Event,
ERC20Event: ERC20Component::Event,
WhitelistChanged: WhitelistChanged,
}

#[derive(Drop, starknet::Event)]
struct WhitelistChanged {
address: ContractAddress,
is_whitelisted: bool,
}

#[constructor]
fn constructor(ref self: ContractState, address_provider: ContractAddress) {}
fn constructor(ref self: ContractState, address_provider: ContractAddress) {
self.ownable.initializer(get_caller_address());
self.address_provider.write(address_provider);
}


#[external(v0)]
impl DebtTokenImpl of super::IDebtToken<ContractState> {
fn emergency_stop_minting(ref self: ContractState, _delay: u256) {}

fn mint(
ref self: ContractState,
_asset: ContractAddress,
_account: ContractAddress,
_amount: u256
) {}

fn mint_from_whitelisted_contract(ref self: ContractState, _amount: u256) {}

fn burn_from_whitelisted_contract(ref self: ContractState, _amount: u256) {}

fn burn(ref self: ContractState, _account: ContractAddress, _amount: u256) {}

fn send_to_pool(
ref self: ContractState,
_sender: ContractAddress,
poolAddress: ContractAddress,
_amount: u256
) {}

fn return_from_pool(
ref self: ContractState,
poolAddress: ContractAddress,
user: ContractAddress,
_amount: u256
) {}

fn add_whitelist(ref self: ContractState, _address: ContractAddress) {}

fn remove_whitelist(ref self: ContractState, _address: ContractAddress) {}

fn transfer(ref self: ContractState, _recipient: ContractAddress, _amount: u256) {}

fn transfer_from(
ref self: ContractState,
sender: ContractAddress,
recipient: ContractAddress,
amount: u256
) {}
fn mint(ref self: ContractState, account: ContractAddress, amount: u256) {
self.require_caller_is_borrower_operations();
self.erc20._mint(account, amount);
}

fn mint_from_whitelisted_contract(ref self: ContractState, amount: u256) {
self.require_caller_is_whitelisted_contract();
self.erc20._mint(get_caller_address(), amount);
}

fn burn_from_whitelisted_contract(ref self: ContractState, amount: u256) {
self.require_caller_is_whitelisted_contract();
self.erc20._burn(get_caller_address(), amount);
}

fn burn(ref self: ContractState, account: ContractAddress, amount: u256) {
self.require_caller_is_bo_or_vesselm_or_sp();
self.erc20._burn(account, amount);
}

fn add_whitelist(ref self: ContractState, address: ContractAddress) {
self.ownable.assert_only_owner();
assert(address.is_non_zero(), CommunErrors::CommunErrors__AddressZero);
self.whitelisted_contracts.write(address, true);
self.emit(WhitelistChanged { address: address, is_whitelisted: true });
}

fn remove_whitelist(ref self: ContractState, address: ContractAddress) {
self.ownable.assert_only_owner();
self.whitelisted_contracts.write(address, false);
self.emit(WhitelistChanged { address: address, is_whitelisted: false });
}

fn is_whitelisted(self: @ContractState, address: ContractAddress) -> bool {
self.whitelisted_contracts.read(address)
}
}

#[generate_trait]
impl InternalFunctions of InternalFunctionsTrait {
fn require_valid_recipient(self: @ContractState, _recipient: ContractAddress) {}
fn require_caller_is_whitelisted_contract(self: @ContractState) {}
fn require_caller_is_borrower_operations(self: @ContractState) {}
fn require_caller_is_bo_or_vesselm_or_sp(self: @ContractState) {}
fn require_caller_is_stability_pool(self: @ContractState) {}
fn require_caller_is_vesselm_or_sp(self: @ContractState) {}
#[inline(always)]
fn require_caller_is_whitelisted_contract(self: @ContractState) {
let caller = get_caller_address();
assert(
self.is_whitelisted(caller) == true, CommunErrors::CommunErrors__CallerNotAuthorized
);
}
#[inline(always)]
fn require_caller_is_borrower_operations(self: @ContractState) {
let caller = get_caller_address();
let address_provider = IAddressProviderDispatcher {
contract_address: (self.address_provider.read())
};
let borrower_operations_manager = address_provider
.get_address(AddressesKey::borrower_operations);
assert(
caller == borrower_operations_manager,
CommunErrors::CommunErrors__CallerNotAuthorized
);
}
#[inline(always)]
fn require_caller_is_bo_or_vesselm_or_sp(self: @ContractState) {
let caller = get_caller_address();
let address_provider = IAddressProviderDispatcher {
contract_address: (self.address_provider.read())
};
let borrower_operations_manager = address_provider
.get_address(AddressesKey::borrower_operations);
let vessel_manager = address_provider.get_address(AddressesKey::vessel_manager);
let stability_pool = address_provider.get_address(AddressesKey::stability_pool);
assert(
caller == borrower_operations_manager
|| caller == vessel_manager
|| caller == stability_pool,
CommunErrors::CommunErrors__CallerNotAuthorized
);
}
#[inline(always)]
fn require_caller_is_stability_pool(self: @ContractState) {
let caller = get_caller_address();
let address_provider = IAddressProviderDispatcher {
contract_address: (self.address_provider.read())
};
let stability_pool = address_provider.get_address(AddressesKey::stability_pool);
assert(caller == stability_pool, CommunErrors::CommunErrors__CallerNotAuthorized);
}
#[inline(always)]
fn require_caller_is_vesselm_or_sp(self: @ContractState) {
let caller = get_caller_address();
let address_provider = IAddressProviderDispatcher {
contract_address: (self.address_provider.read())
};
let vessel_manager = address_provider.get_address(AddressesKey::vessel_manager);
let stability_pool = address_provider.get_address(AddressesKey::stability_pool);
assert(
caller == vessel_manager || caller == stability_pool,
CommunErrors::CommunErrors__CallerNotAuthorized
);
}
}
}
Loading