Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pausable & unpausable function #8

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
8 changes: 7 additions & 1 deletion src/pair/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ use starknet::ContractAddress;

use openzeppelin::token::erc20::interface::{IERC20Dispatcher};

#[starknet::interface]
pub trait IPausable<TContractState> {
fn pause(ref self: TContractState);
fn unpause(ref self: TContractState);
}

#[starknet::interface]
pub trait IPair<TContractState> {
fn initialize(ref self: TContractState, token0: ContractAddress, token1: ContractAddress);
Expand All @@ -25,4 +31,4 @@ pub trait IPair<TContractState> {
#[starknet::interface]
pub trait IFactory<T> {
fn get_fee_to(self: @T) -> ContractAddress;
}
}
39 changes: 35 additions & 4 deletions src/pair/pair.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ trait PairInternalTrait<TContractState> {

#[starknet::contract]
mod Pair {
use univ2::pair::interface::{IPair, IFactoryDispatcher, IFactoryDispatcherTrait};
use univ2::pair::interface::{IPair, IPausable, IFactoryDispatcher, IFactoryDispatcherTrait};
use starknet::{
ContractAddress, get_caller_address, get_contract_address, get_block_timestamp,
contract_address_const
Expand All @@ -16,6 +16,8 @@ mod Pair {
use openzeppelin::token::erc20::interface::{
IERC20Dispatcher, IERC20DispatcherTrait, IERC20Mixin
};
use openzeppelin::access::ownable::OwnableComponent;
use openzeppelin::security::pausable::PausableComponent;

use core::cmp::min;
#[feature("corelib-internal-use")]
Expand All @@ -26,17 +28,21 @@ mod Pair {

use openzeppelin::token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
use openzeppelin::security::reentrancyguard::ReentrancyGuardComponent;

use ERC20Component::InternalTrait;
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
component!(
path: ReentrancyGuardComponent, storage: reentrancy_guard, event: ReentrancyGuardEvent
);
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
component!(path: PausableComponent, storage: pausable, event: PausableEvent);


#[abi(embed_v0)]
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
impl ERC20Internal = ERC20Component::InternalImpl<ContractState>;
impl ReentrancyGuardInternal = ReentrancyGuardComponent::InternalImpl<ContractState>;
impl OwnableInternal = OwnableComponent::InternalImpl<ContractState>;
impl PausableInternal = PausableComponent::InternalImpl<ContractState>;


const MINIMUM_LIQUIDITY: u256 = 10_000;
Expand All @@ -57,6 +63,10 @@ mod Pair {
erc20: ERC20Component::Storage,
#[substorage(v0)]
reentrancy_guard: ReentrancyGuardComponent::Storage,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
#[substorage(v0)]
pausable: PausableComponent::Storage,
}

#[event]
Expand All @@ -68,6 +78,8 @@ mod Pair {
Burn: Burn,
ERC20Event: ERC20Component::Event,
ReentrancyGuardEvent: ReentrancyGuardComponent::Event,
OwnableEvent: OwnableComponent::Event,
PausableEvent: PausableComponent::Event,
}

#[derive(Drop, starknet::Event)]
Expand Down Expand Up @@ -115,11 +127,28 @@ mod Pair {
pub const K: felt252 = 'Pair: K';
}

impl PausableImpl of IPausable<ContractState> {
fn pause(ref self: ContractState) {
// Only owner can pause
self.ownable.assert_only_owner();
self.pausable.assert_not_paused();
self.pausable.pause();
}

fn unpause(ref self: ContractState) {
// Only owner can unpause
self.ownable.assert_only_owner();
self.pausable.assert_paused();
self.pausable.unpause();
}
}

#[constructor]
fn constructor(ref self: ContractState) {
let factory = get_caller_address();

self._factory.write(factory);
self.ownable._transfer_ownership(factory);
}

fn _uq_encode(y: u128) -> u256 {
Expand Down Expand Up @@ -339,6 +368,9 @@ mod Pair {
// lock the swap to prevent another call to swap as the swap is being executed
ReentrancyGuardInternal::start(ref self.reentrancy_guard);

// Check if contract is paused
self.pausable.assert_not_paused();

let this = get_contract_address();

let reserve0 = self._reserve0.read();
Expand Down Expand Up @@ -412,7 +444,6 @@ mod Pair {
);

ReentrancyGuardInternal::end(ref self.reentrancy_guard);
self.reentrancy_guard.end();
}

fn skim(ref self: ContractState, to: ContractAddress) {
Expand Down Expand Up @@ -451,4 +482,4 @@ mod Pair {
ReentrancyGuardInternal::end(ref self.reentrancy_guard);
}
}
}
}