Skip to content

Commit

Permalink
test initiate_liquidity_withdraw (#97)
Browse files Browse the repository at this point in the history
* initial commit

* rebase and implementation of remaining tests

* minor improvements

---------

Co-authored-by: 0xChqrles <[email protected]>
  • Loading branch information
chachaleo and 0xChqrles authored Sep 28, 2024
1 parent bd4ff65 commit fa01485
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 27 deletions.
4 changes: 3 additions & 1 deletion contracts/src/components/registry/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use zkramp::utils::hash::HashSerializable;

#[derive(Drop, Copy, Serde, Debug, PartialEq, starknet::Store)]
pub enum OffchainId {
Revolut: felt252
#[default]
None,
Revolut: felt252,
}

#[starknet::interface]
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/contracts/ramps/revolut/revolut.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ pub mod RevolutRamp {
// Constants
//

const LOCK_DURATION_STEP: u64 = 900; // 15min
const MINIMUM_LOCK_DURATION: u64 = 3600; // 1h
pub const LOCK_DURATION_STEP: u64 = 900; // 15min
pub const MINIMUM_LOCK_DURATION: u64 = 3600; // 1h

//
// Storage
Expand Down
275 changes: 251 additions & 24 deletions contracts/src/contracts/ramps/revolut/revolut_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use snforge_std::{
stop_cheat_caller_address, test_address
};
use zkramp::contracts::ramps::revolut::interface::{ZKRampABIDispatcher, ZKRampABIDispatcherTrait, LiquidityKey};
use zkramp::contracts::ramps::revolut::revolut::RevolutRamp::{Event, LiquidityAdded, LiquidityLocked};
use zkramp::contracts::ramps::revolut::revolut::RevolutRamp::{
Event, LiquidityAdded, LiquidityLocked, LiquidityShareRequested, MINIMUM_LOCK_DURATION
};
use zkramp::tests::constants;
use zkramp::tests::utils;

Expand Down Expand Up @@ -373,51 +375,276 @@ fn test_retrieve_liquidity_with_expired_requests() {
// initiate_liquidity_withdraw & withdraw_liquidity
//

// #[test]
// #[should_panic(expected: 'Caller is the owner')]
#[test]
#[should_panic(expected: 'Caller is the owner')]
fn test_initiate_liquidity_withdraw_from_owner() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::CALLER();
let offchain_id = constants::REVOLUT_ID();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, :amount, :offchain_id);
}

// #[test]
// #[should_panic(expected: 'Amount cannot be null')]
#[test]
#[should_panic(expected: 'Amount cannot be null')]
fn test_initiate_liquidity_withdraw_zero_amount() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::CALLER();
let liquidity_withdrawer = constants::OTHER();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer = constants::REVOLUT_ID2();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// register offchain ID withdrawer
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer);
revolut_ramp.register(offchain_id: offchain_id_withdrawer);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, amount: 0, offchain_id: offchain_id_withdrawer);
}

// #[test]
// #[should_panic(expected: 'Liquidity is not available')]
#[test]
#[should_panic(expected: 'Liquidity is not available')]
fn test_initiate_liquidity_withdraw_locked() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::CALLER();
let liquidity_withdrawer = constants::OTHER();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer = constants::REVOLUT_ID2();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// locks liquidity
revolut_ramp.initiate_liquidity_retrieval(:liquidity_key);

// register offchain ID withdrawer
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer);
revolut_ramp.register(offchain_id: offchain_id_withdrawer);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, :amount, offchain_id: offchain_id_withdrawer);
}

// #[test]
// #[should_panic(expected: 'Caller is not registered')]
#[test]
#[should_panic(expected: 'Caller is not registered')]
fn test_initiate_liquidity_withdraw_with_unregistered_offchain_id() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::CALLER();
let liquidity_withdrawer = constants::OTHER();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer = constants::REVOLUT_ID2();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// initiate liquidity withdraw
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer);
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, :amount, offchain_id: offchain_id_withdrawer);
}

// #[test]
// #[should_panic(expected: 'Not enough liquidity')]
#[test]
#[should_panic(expected: 'Not enough liquidity')]
fn test_initiate_liquidity_withdraw_without_enough_liquidity() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::CALLER();
let liquidity_withdrawer = constants::OTHER();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer = constants::REVOLUT_ID2();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// register offchain ID withdrawer
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer);
revolut_ramp.register(offchain_id: offchain_id_withdrawer);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, amount: amount + 1, offchain_id: offchain_id_withdrawer);
}

// #[test]
// #[should_panic(expected: 'Not enough liquidity')]
#[test]
#[should_panic(expected: 'Not enough liquidity')]
fn test_initiate_liquidity_withdraw_without_enough_available_liquidity() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::CALLER();
let liquidity_withdrawer1 = constants::OTHER();
let liquidity_withdrawer2 = constants::OTHER2();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer1 = constants::REVOLUT_ID2();
let offchain_id_withdrawer2 = constants::REVOLUT_ID3();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// register offchain ID withdrawer 1
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer1);
revolut_ramp.register(offchain_id: offchain_id_withdrawer1);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, amount: 1, offchain_id: offchain_id_withdrawer1);

// assert state before
assert_eq!(revolut_ramp.available_liquidity(:liquidity_key), amount - 1);
assert_eq!(revolut_ramp.all_liquidity(:liquidity_key), amount);

// register offchain ID withdrawer 2
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer2);
revolut_ramp.register(offchain_id: offchain_id_withdrawer2);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, :amount, offchain_id: offchain_id_withdrawer2);
}

// #[test]
#[test]
fn test_initiate_liquidity_withdraw() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let mut spy = spy_events();
let liquidity_owner = constants::CALLER();
let liquidity_withdrawer = constants::OTHER();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer = constants::REVOLUT_ID2();
let amount = 42;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, :amount);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(:amount, :offchain_id);

// assert state before
assert_eq!(revolut_ramp.all_liquidity(:liquidity_key), amount);
assert_eq!(revolut_ramp.available_liquidity(:liquidity_key), amount);
assert_eq!(erc20.balance_of(liquidity_owner), 0);

// register offchain ID withdrawer
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer);
revolut_ramp.register(offchain_id: offchain_id_withdrawer);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, :amount, offchain_id: offchain_id_withdrawer);

// assert state after
assert_eq!(revolut_ramp.all_liquidity(liquidity_key), amount);
assert_eq!(revolut_ramp.available_liquidity(liquidity_key), 0);
assert_eq!(erc20.balance_of(liquidity_owner), 0);

// check on emitted events
spy
.assert_emitted(
@array![
(
revolut_ramp.contract_address,
Event::LiquidityShareRequested(
LiquidityShareRequested {
requestor: liquidity_withdrawer,
amount,
liquidity_key,
offchain_id: offchain_id_withdrawer,
expiration_date: MINIMUM_LOCK_DURATION
}
)
)
]
)
}

// #[test]
// #[should_panic(expected: 'This offchainID is busy')]
#[test]
#[should_panic(expected: 'This offchainID is busy')]
fn test_initiate_liquidity_withdraw_twice() {
panic!("Not implemented yet");
let (revolut_ramp, erc20) = setup();
let liquidity_owner = constants::OTHER();
let liquidity_withdrawer = constants::CALLER();
let offchain_id = constants::REVOLUT_ID();
let offchain_id_withdrawer = constants::REVOLUT_ID2();
let amount1 = 42;
let amount2 = 75;
let liquidity_key = LiquidityKey { owner: liquidity_owner, offchain_id };

// fund the account
fund_and_approve(
token: erc20, recipient: liquidity_owner, spender: revolut_ramp.contract_address, amount: amount1 + amount2
);

// register offchain ID owner
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_owner);
revolut_ramp.register(:offchain_id);

// add liquidity
revolut_ramp.add_liquidity(amount: amount1 + amount2, :offchain_id);

// register offchain ID withdrawer
start_cheat_caller_address(revolut_ramp.contract_address, liquidity_withdrawer);
revolut_ramp.register(offchain_id: offchain_id_withdrawer);

// initiate liquidity withdraw
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, amount: amount1, offchain_id: offchain_id_withdrawer);
revolut_ramp.initiate_liquidity_withdrawal(:liquidity_key, amount: amount2, offchain_id: offchain_id_withdrawer);
}

// #[test]
Expand Down
16 changes: 16 additions & 0 deletions contracts/src/tests/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ use zkramp::components::registry::interface::OffchainId;

const REVTAG: felt252 = 'just a random revtag hash';

const REVTAG2: felt252 = 'just a 2nd random revtag hash';

const REVTAG3: felt252 = 'just a 3rd random revtag hash';

pub fn REVOLUT_ID() -> OffchainId {
OffchainId::Revolut(REVTAG)
}

pub fn REVOLUT_ID2() -> OffchainId {
OffchainId::Revolut(REVTAG2)
}

pub fn REVOLUT_ID3() -> OffchainId {
OffchainId::Revolut(REVTAG3)
}

pub fn CALLER() -> ContractAddress {
contract_address_const::<'caller'>()
}
Expand All @@ -27,6 +39,10 @@ pub fn OTHER() -> ContractAddress {
contract_address_const::<'other'>()
}

pub fn OTHER2() -> ContractAddress {
contract_address_const::<'other2'>()
}

pub const SUPPLY: u256 = 1_000_000_000_000_000_000; // 1 ETH


Expand Down

0 comments on commit fa01485

Please sign in to comment.