diff --git a/.github/workflows/eth-test.yml b/.github/workflows/eth-test.yml new file mode 100644 index 00000000..fbce4b7b --- /dev/null +++ b/.github/workflows/eth-test.yml @@ -0,0 +1,20 @@ +name: ETH YABTransfer Tests + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] + +jobs: + test-ETH: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Run tests + run: make ethereum-test diff --git a/.github/workflows/sn-test.yml b/.github/workflows/sn-test.yml new file mode 100644 index 00000000..2d153ba1 --- /dev/null +++ b/.github/workflows/sn-test.yml @@ -0,0 +1,37 @@ +name: SN Escrow Tests + +on: + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] + +jobs: + test-SN: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install scarb + uses: software-mansion/setup-scarb@v1 + with: + scarb-version: "2.3.1" + + - name: Install starkliup + run: | + curl https://get.starkli.sh | sh + + - name: Install Starkli + run: | + /home/runner/.config/.starkli/bin/starkliup --version 0.1.20 + sudo mv /home/runner/.config/.starkli/bin/starkli /usr/local/bin/ + + - name: Install snFoundry + uses: foundry-rs/setup-snfoundry@v2 + with: + starknet-foundry-version: 0.12.0 + + - name: Run make starknet-test + run: | + make starknet-test diff --git a/contracts/cairo/src/escrow.cairo b/contracts/cairo/src/escrow.cairo index 04a8619f..651f2542 100644 --- a/contracts/cairo/src/escrow.cairo +++ b/contracts/cairo/src/escrow.cairo @@ -36,7 +36,7 @@ mod Escrow { use openzeppelin::{ access::ownable::OwnableComponent, upgrades::{UpgradeableComponent, interface::IUpgradeable}, - security::PausableComponent + security::PausableComponent, }; use starknet::{ ContractAddress, EthAddress, ClassHash, get_caller_address, get_contract_address, diff --git a/contracts/cairo/src/lib.cairo b/contracts/cairo/src/lib.cairo index a7188ff1..87cce74f 100644 --- a/contracts/cairo/src/lib.cairo +++ b/contracts/cairo/src/lib.cairo @@ -16,7 +16,6 @@ mod mocks { #[cfg(test)] mod tests { mod test_escrow_allowance; - mod test_escrow_cancel; mod test_escrow_pause; mod test_escrow_upgrade; mod test_escrow_ownable; diff --git a/contracts/cairo/src/tests/test_escrow_cancel.cairo b/contracts/cairo/src/tests/test_escrow_cancel.cairo deleted file mode 100644 index 532260bd..00000000 --- a/contracts/cairo/src/tests/test_escrow_cancel.cairo +++ /dev/null @@ -1,145 +0,0 @@ -mod Escrow { - use core::to_byte_array::FormatAsByteArray; - use core::serde::Serde; - use core::traits::Into; - use starknet::{EthAddress, ContractAddress}; - use integer::BoundedInt; - - use snforge_std::{declare, ContractClassTrait, L1Handler, L1HandlerTrait}; - use snforge_std::{CheatTarget, start_prank, stop_prank, start_warp, stop_warp}; - - use yab::mocks::mock_Escrow_changed_functions::{IEscrow_mock_changed_functionsDispatcher, IEscrow_mock_changed_functionsDispatcherTrait}; - use yab::mocks::mock_pausableEscrow::{IEscrow_mockPausableDispatcher, IEscrow_mockPausableDispatcherTrait}; - use yab::interfaces::IERC20::{IERC20Dispatcher, IERC20DispatcherTrait}; - use yab::escrow::{IEscrowDispatcher, IEscrowDispatcherTrait, Order}; - use yab::interfaces::IEVMFactsRegistry::{ - IEVMFactsRegistryDispatcher, IEVMFactsRegistryDispatcherTrait - }; - - use yab::tests::utils::{ - constants::EscrowConstants::{ - USER, OWNER, MM_STARKNET, MM_ETHEREUM, ETH_TRANSFER_CONTRACT, ETH_USER - }, - }; - - use openzeppelin::{ - upgrades::{ - UpgradeableComponent, - interface::{IUpgradeable, IUpgradeableDispatcher, IUpgradeableDispatcherTrait} - }, - }; - - fn setup() -> (IEscrowDispatcher, IERC20Dispatcher) { - setup_general(BoundedInt::max(), BoundedInt::max()) - } - - fn setup_approved(approved: u256) -> (IEscrowDispatcher, IERC20Dispatcher){ - setup_general(BoundedInt::max(), approved) - } - - fn setup_balance(balance: u256) -> (IEscrowDispatcher, IERC20Dispatcher){ - setup_general(balance, BoundedInt::max()) - } - - fn setup_general(balance: u256, approved: u256) -> (IEscrowDispatcher, IERC20Dispatcher){ - let eth_token = deploy_erc20('ETH', '$ETH', BoundedInt::max(), OWNER()); - let escrow = deploy_escrow( - OWNER(), - ETH_TRANSFER_CONTRACT(), - MM_ETHEREUM(), - MM_STARKNET(), - eth_token.contract_address - ); - - start_prank(CheatTarget::One(eth_token.contract_address), OWNER()); - eth_token.transfer(USER(), balance); - stop_prank(CheatTarget::One(eth_token.contract_address)); - - start_prank(CheatTarget::One(eth_token.contract_address), USER()); - eth_token.approve(escrow.contract_address, approved); - stop_prank(CheatTarget::One(eth_token.contract_address)); - - (escrow, eth_token) - } - - fn deploy_escrow( - escrow_owner: ContractAddress, - eth_transfer_contract: EthAddress, - mm_ethereum_contract: EthAddress, - mm_starknet_contract: ContractAddress, - native_token_eth_starknet: ContractAddress - ) -> IEscrowDispatcher { - let escrow = declare('Escrow'); - let mut calldata: Array = ArrayTrait::new(); - calldata.append(escrow_owner.into()); - calldata.append(eth_transfer_contract.into()); - calldata.append(mm_ethereum_contract.into()); - calldata.append(mm_starknet_contract.into()); - calldata.append(native_token_eth_starknet.into()); - let address = escrow.deploy(@calldata).unwrap(); - return IEscrowDispatcher { contract_address: address }; - } - - fn deploy_erc20( - name: felt252, symbol: felt252, initial_supply: u256, recipent: ContractAddress - ) -> IERC20Dispatcher { - let erc20 = declare('ERC20'); - let mut calldata = array![name, symbol]; - Serde::serialize(@initial_supply, ref calldata); - calldata.append(recipent.into()); - let address = erc20.deploy(@calldata).unwrap(); - return IERC20Dispatcher { contract_address: address }; - } - - #[test] - fn test_cancel_order() { - let (escrow, eth_token) = setup_balance(500); - - start_prank(CheatTarget::One(escrow.contract_address), USER()); - let order = Order { recipient_address: 12345.try_into().unwrap(), amount: 500, fee: 0 }; - let order_id = escrow.set_order(order); - - // check balance - assert(eth_token.balanceOf(escrow.contract_address) == 500, 'set_order: wrong balance '); - assert(eth_token.balanceOf(MM_STARKNET()) == 0, 'set_order: wrong balance'); - assert(eth_token.balanceOf(USER()) == 0, 'set_order: wrong allowance'); - - start_warp(CheatTarget::One(escrow.contract_address), 43201); - escrow.cancel_order(order_id); - stop_warp(CheatTarget::One(escrow.contract_address)); - - stop_prank(CheatTarget::One(escrow.contract_address)); - - // check balance - assert(eth_token.balanceOf(escrow.contract_address) == 0, 'cancel_order: wrong balance '); - assert(eth_token.balanceOf(MM_STARKNET()) == 0, 'cancel_order: wrong balance'); - assert(eth_token.balanceOf(USER()) == 500, 'cancel_order: wrong allowance'); - } - - #[test] - #[should_panic(expected: ('Not enough time has passed',))] - fn test_cancel_order_fail_time() { - let (escrow, eth_token) = setup_balance(500); - - start_prank(CheatTarget::One(escrow.contract_address), USER()); - let order = Order { recipient_address: 12345.try_into().unwrap(), amount: 500, fee: 0 }; - let order_id = escrow.set_order(order); - - escrow.cancel_order(order_id); - stop_prank(CheatTarget::One(escrow.contract_address)); - } - - #[test] - #[should_panic(expected: ('Only sender allowed',))] - fn test_cancel_order_fail_sender() { - let (escrow, eth_token) = setup_balance(500); - - start_prank(CheatTarget::One(escrow.contract_address), USER()); - let order = Order { recipient_address: 12345.try_into().unwrap(), amount: 500, fee: 0 }; - let order_id = escrow.set_order(order); - - start_warp(CheatTarget::One(escrow.contract_address), 43201); - start_prank(CheatTarget::One(escrow.contract_address), MM_STARKNET()); - escrow.cancel_order(order_id); - } -} diff --git a/contracts/cairo/src/tests/test_escrow_pause.cairo b/contracts/cairo/src/tests/test_escrow_pause.cairo index 8e30469f..d42162a1 100644 --- a/contracts/cairo/src/tests/test_escrow_pause.cairo +++ b/contracts/cairo/src/tests/test_escrow_pause.cairo @@ -25,7 +25,11 @@ mod Escrow { use openzeppelin::{ upgrades::{ UpgradeableComponent, - interface::{IUpgradeable, IUpgradeableDispatcher, IUpgradeableDispatcherTrait} + interface::{IUpgradeable, IUpgradeableDispatcher, IUpgradeableDispatcherTrait}, + }, + security::{ + PausableComponent, + interface::{IPausable, IPausableDispatcher, IPausableDispatcherTrait}, }, }; @@ -94,29 +98,35 @@ mod Escrow { #[test] fn test_start_unpaused() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); - assert(escrow.pause_state() == false, 'Should start unpaused'); + assert(pausable.is_paused() == false, 'Should start unpaused'); stop_prank(CheatTarget::One(escrow.contract_address)); } #[test] fn test_pause() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); escrow.pause(); - assert(escrow.pause_state() == true, 'Should be paused'); + assert(pausable.is_paused() == true, 'Should be paused'); stop_prank(CheatTarget::One(escrow.contract_address)); } #[test] fn test_pause_unpause() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); - assert(escrow.pause_state() == false, 'Should start unpaused'); + assert(pausable.is_paused() == false, 'Should start unpaused'); escrow.pause(); - assert(escrow.pause_state() == true, 'Should be paused'); + assert(pausable.is_paused() == true, 'Should be paused'); escrow.unpause(); - assert(escrow.pause_state() == false, 'Should be unpaused'); + assert(pausable.is_paused() == false, 'Should be unpaused'); stop_prank(CheatTarget::One(escrow.contract_address)); } @@ -124,8 +134,10 @@ mod Escrow { #[should_panic(expected: ('Caller is not the owner',))] fn test_fail_pause_not_owner() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), USER()); - assert(escrow.pause_state() == false, 'Should start unpaused'); + assert(pausable.is_paused() == false, 'Should start unpaused'); escrow.pause(); stop_prank(CheatTarget::One(escrow.contract_address)); } @@ -134,10 +146,12 @@ mod Escrow { #[should_panic(expected: ('Caller is not the owner',))] fn test_fail_unpause_not_owner() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); - assert(escrow.pause_state() == false, 'Should start unpaused'); + assert(pausable.is_paused() == false, 'Should start unpaused'); escrow.pause(); - assert(escrow.pause_state() == true, 'Should be paused'); + assert(pausable.is_paused() == true, 'Should be paused'); stop_prank(CheatTarget::One(escrow.contract_address)); start_prank(CheatTarget::One(escrow.contract_address), USER()); @@ -149,10 +163,12 @@ mod Escrow { #[should_panic(expected: ('Pausable: paused',))] fn test_fail_pause_while_paused() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); - assert(escrow.pause_state() == false, 'Should start unpaused'); + assert(pausable.is_paused() == false, 'Should start unpaused'); escrow.pause(); - assert(escrow.pause_state() == true, 'Should be paused'); + assert(pausable.is_paused() == true, 'Should be paused'); escrow.pause(); stop_prank(CheatTarget::One(escrow.contract_address)); } @@ -161,10 +177,12 @@ mod Escrow { #[should_panic(expected: ('Pausable: not paused',))] fn test_fail_unpause_while_unpaused() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); - assert(escrow.pause_state() == false, 'Should start unpaused'); + assert(pausable.is_paused() == false, 'Should start unpaused'); escrow.unpause(); - assert(escrow.pause_state() == false, 'Should be unpaused'); + assert(pausable.is_paused() == false, 'Should be unpaused'); escrow.unpause(); stop_prank(CheatTarget::One(escrow.contract_address)); } @@ -173,6 +191,8 @@ mod Escrow { #[should_panic(expected: ('Pausable: paused',))] fn test_fail_set_order_when_paused() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); escrow.pause(); stop_prank(CheatTarget::One(escrow.contract_address)); @@ -186,6 +206,8 @@ mod Escrow { #[test] fn test_set_order_when_unpaused_after_prev_pause() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), USER()); let order = Order { recipient_address: 12345.try_into().unwrap(), amount: 500, fee: 0 }; @@ -206,6 +228,7 @@ mod Escrow { #[test] fn test_upgrade_when_paused() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; let upgradeable = IUpgradeableDispatcher { contract_address: escrow.contract_address }; start_prank(CheatTarget::One(escrow.contract_address), OWNER()); @@ -221,6 +244,8 @@ mod Escrow { #[test] fn test_fail_call_l1_handler_while_paused() { let (escrow, _) = setup(); + let pausable = IPausableDispatcher { contract_address: escrow.contract_address }; + start_prank(CheatTarget::One(escrow.contract_address), OWNER()); escrow.pause(); stop_prank(CheatTarget::One(escrow.contract_address));