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

Added a swap pause functionality #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
54 changes: 42 additions & 12 deletions src/pair/pair.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,36 @@ 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")]
use core::integer::u256_sqrt;


//init the components

// Components
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);


// Implement component interfaces
#[abi(embed_v0)]
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
impl ERC20Internal = ERC20Component::InternalImpl<ContractState>;
impl ReentrancyGuardInternal = ReentrancyGuardComponent::InternalImpl<ContractState>;

impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;

const MINIMUM_LIQUIDITY: u256 = 10_000;


#[storage]
struct Storage {
_factory: ContractAddress,
Expand All @@ -57,6 +61,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 +76,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 @@ -113,13 +123,16 @@ mod Pair {
pub const INVALID_TO: felt252 = 'Pair: Invalid to';
pub const INSUFFICIENT_INPUT: felt252 = 'Pair: Insufficient input';
pub const K: felt252 = 'Pair: K';
pub const NOT_OWNER: felt252 = 'Caller is not the owner';
}

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

self._factory.write(factory);

// Initialize owner as the factory
self.ownable.initializer(factory);
}

fn _uq_encode(y: u128) -> u256 {
Expand Down Expand Up @@ -189,6 +202,23 @@ mod Pair {
}
}

// Add pause/unpause functions that can only be called by owner
#[external(v0)]
fn pause(ref self: ContractState) {
// Check if caller is owner
self.ownable.assert_only_owner();
// Pause the contract
self.pausable.pause();
}

#[external(v0)]
fn unpause(ref self: ContractState) {
// Check if caller is owner
self.ownable.assert_only_owner();
// Unpause the contract
self.pausable.unpause();
}

#[abi(embed_v0)]
impl PairImpl of IPair<ContractState> {
fn initialize(ref self: ContractState, token0: ContractAddress, token1: ContractAddress) {
Expand Down Expand Up @@ -336,7 +366,10 @@ mod Pair {
fn swap(
ref self: ContractState, amount0_out: u256, amount1_out: u256, to: ContractAddress
) {
// lock the swap to prevent another call to swap as the swap is being executed
// Check if contract is paused
self.pausable.assert_not_paused();

// Lock the swap to prevent another call to swap as the swap is being executed
ReentrancyGuardInternal::start(ref self.reentrancy_guard);

let this = get_contract_address();
Expand All @@ -358,12 +391,10 @@ mod Pair {
);

if amount0_out > 0 {
// optimistic transfer of token0 to user
token0.transfer(to, amount0_out);
}

if amount1_out > 0 {
// optimistic transfer of token1 to user
token1.transfer(to, amount1_out);
}

Expand Down Expand Up @@ -412,8 +443,7 @@ mod Pair {
);

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

}
fn skim(ref self: ContractState, to: ContractAddress) {
ReentrancyGuardInternal::start(ref self.reentrancy_guard);

Expand Down