Skip to content

Commit

Permalink
Deposit/Withdraw testcases (#6)
Browse files Browse the repository at this point in the history
* feat: initiliased testcases

* admin function tests

* fix: max total balance check

* feat: block token test

* disable limit test

* feat: add failing tc for withdraw limit

* fixed testcases after rebase

* chore: added messaging mock

* Update src/bridge/token_bridge.cairo

Co-authored-by: Apoorv Sadana <[email protected]>

* resolve comments

* add reactivate and unblock

* add reactivate and unblock

* unblock tests

* reactivate and unblock tests

* resolved merge conflicts

* restructure testcases

* fix: visibility modifier

* deposit tests

* make them unit

* make them unit

* deposit flow tests

* change to mock usdc address

* improve: not needed to deploy usdc in while mock testing

* unit testcases

* add token actions restructure

* migrate to latest foundry

* restructure

* deposit failing tc

* test: happy withdraw test

* chore: ran formatter

* fix settlement of message

* change deposit tests to use message_payloads

* add assert

* failing withdraw tc

* cancel request

* deposit with message cancels

* Update tests/deposit_test.cairo

Co-authored-by: Apoorv Sadana <[email protected]>

* resolved comments

* fix consume message

* fix consume message check

* reclaim testcases (#7)

* reclaim testcases

* consume message

* add balance check

* add events in actions

* Unit tests (#9)

* deactivate tc

* send messages tc

* change name

* resolved comments

* Update tests/withdrawal_limit_bridge_test.cairo

Co-authored-by: Apoorv Sadana <[email protected]>

---------

Co-authored-by: Apoorv Sadana <[email protected]>

---------

Co-authored-by: Apoorv Sadana <[email protected]>

* add setup functions

---------

Co-authored-by: Apoorv Sadana <[email protected]>
  • Loading branch information
byteZorvin and apoorvsadana authored Aug 13, 2024
1 parent a11d2f6 commit afb386a
Show file tree
Hide file tree
Showing 23 changed files with 1,518 additions and 220 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scarb 2.6.5
starknet-foundry 0.26.0
starknet-foundry 0.27.0
4 changes: 2 additions & 2 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ dependencies = [

[[package]]
name = "snforge_std"
version = "0.26.0"
source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.26.0#50eb589db65e113efe4f09241feb59b574228c7e"
version = "0.27.0"
source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.27.0#2d99b7c00678ef0363881ee0273550c44a9263de"

[[package]]
name = "starknet_bridge"
Expand Down
3 changes: 2 additions & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ starknet = "2.6.4"
piltover = { git = "https://github.com/byteZorvin/piltover", branch="bridge-testing"}

[dev-dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.26.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.27.0" }

[[target.starknet-contract]]
casm = true


[scripts]
test = "snforge test"
241 changes: 241 additions & 0 deletions src/bridge/tests/messaging_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
use piltover::messaging::interface::IMessagingDispatcherTrait;
use starknet_bridge::bridge::token_bridge::TokenBridge::{
__member_module_appchain_bridge::InternalContractMemberStateTrait,
__member_module_token_settings::InternalContractMemberStateTrait as tokenSettingsStateTrait,
TokenBridgeInternal
};
use snforge_std as snf;
use snforge_std::ContractClassTrait;
use starknet::{ContractAddress, storage::StorageMemberAccessTrait};
use starknet_bridge::mocks::{
messaging::{IMockMessagingDispatcherTrait, IMockMessagingDispatcher}, erc20::ERC20, hash
};
use piltover::messaging::interface::IMessagingDispatcher;
use starknet_bridge::bridge::{
ITokenBridge, ITokenBridgeAdmin, ITokenBridgeDispatcher, ITokenBridgeDispatcherTrait,
ITokenBridgeAdminDispatcher, ITokenBridgeAdminDispatcherTrait, IWithdrawalLimitStatusDispatcher,
IWithdrawalLimitStatusDispatcherTrait, TokenBridge, TokenBridge::Event,
types::{TokenStatus, TokenSettings},
tests::constants::{OWNER, L3_BRIDGE_ADDRESS, USDC_MOCK_ADDRESS, DELAY_TIME}
};
use openzeppelin::{
token::erc20::interface::{IERC20MetadataDispatcher, IERC20MetadataDispatcherTrait},
access::ownable::{
OwnableComponent, OwnableComponent::Event as OwnableEvent,
interface::{IOwnableTwoStepDispatcher, IOwnableTwoStepDispatcherTrait}
}
};
use starknet_bridge::bridge::tests::utils::message_payloads;
use starknet::contract_address::{contract_address_const};
use starknet_bridge::constants;


/// Returns the state of a contract for testing. This must be used
/// to test internal functions or directly access the storage.
/// You can't spy event with this. Use deploy instead.
pub fn mock_state_testing() -> TokenBridge::ContractState {
TokenBridge::contract_state_for_testing()
}

fn deploy_erc20(name: ByteArray, symbol: ByteArray) -> ContractAddress {
let erc20_class_hash = snf::declare("ERC20").unwrap();
let mut constructor_args = ArrayTrait::new();
name.serialize(ref constructor_args);
symbol.serialize(ref constructor_args);
let fixed_supply: u256 = 1000000000;
fixed_supply.serialize(ref constructor_args);
OWNER().serialize(ref constructor_args);

let (usdc, _) = erc20_class_hash.deploy(@constructor_args).unwrap();
return usdc;
}


#[test]
fn deploy_message_payload_ok() {
let usdc_address = deploy_erc20("USDC", "USDC");
let calldata = TokenBridge::deployment_message_payload(usdc_address);

let expected_calldata: Span<felt252> = array![
3346236667719676623895870229889359551507408296949803518172317961543243553075, // usdc_address
0,
1431520323, // -- USDC
4,
0,
1431520323, // USDC
4,
18 // Decimals
]
.span();
assert(calldata == expected_calldata, 'Incorrect serialisation');
}

#[test]
fn deposit_message_payload_with_message_false_ok() {
let usdc_address = USDC_MOCK_ADDRESS();
let calldata = TokenBridge::deposit_message_payload(
usdc_address, 100, snf::test_address(), false, array![].span()
);

let expected_calldata = array![
26445726369279219922997965683, 0, 469394814521890341860918960550914, 100, 0
]
.span();
assert(calldata == expected_calldata, 'Incorrect serialization');
}


#[test]
fn send_deploy_message_ok() {
let mut mock = mock_state_testing();
let usdc_address = deploy_erc20("USDC", "USDC");

// Deploy messaging mock with 5 days cancellation delay
let messaging_mock_class_hash = snf::declare("messaging_mock").unwrap();
// Deploying with 5 days as the delay time (5 * 86400 = 432000)
let (messaging_contract_address, _) = messaging_mock_class_hash
.deploy(@array![DELAY_TIME])
.unwrap();

let messaging = IMessagingDispatcher { contract_address: messaging_contract_address };

snf::start_cheat_caller_address_global(snf::test_address());
TokenBridge::constructor(ref mock, L3_BRIDGE_ADDRESS(), messaging_contract_address, OWNER());

mock.send_deploy_message(usdc_address);
let hash = hash::compute_message_hash_sn_to_appc(
1,
L3_BRIDGE_ADDRESS(),
constants::HANDLE_TOKEN_DEPLOYMENT_SELECTOR,
message_payloads::deployment_message_payload(usdc_address)
);
assert(messaging.sn_to_appchain_messages(hash) == 1, 'Message not recieved');
}

#[test]
#[should_panic(expected: ('L3 bridge not set',))]
fn send_deploy_message_bridge_unset() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

mock.send_deploy_message(usdc_address);
}

#[test]
fn send_deposit_message_ok() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

// Deploy messaging mock with 5 days cancellation delay
let messaging_mock_class_hash = snf::declare("messaging_mock").unwrap();
// Deploying with 5 days as the delay time (5 * 86400 = 432000)
let (messaging_contract_address, _) = messaging_mock_class_hash
.deploy(@array![DELAY_TIME])
.unwrap();
let messaging = IMessagingDispatcher { contract_address: messaging_contract_address };
TokenBridge::constructor(ref mock, L3_BRIDGE_ADDRESS(), messaging_contract_address, OWNER());

let no_message: Span<felt252> = array![].span();
snf::start_cheat_caller_address_global(snf::test_address());
mock
.send_deposit_message(
usdc_address,
100,
snf::test_address(),
no_message,
constants::HANDLE_TOKEN_DEPOSIT_SELECTOR
);

let hash = hash::compute_message_hash_sn_to_appc(
1,
L3_BRIDGE_ADDRESS(),
constants::HANDLE_TOKEN_DEPOSIT_SELECTOR,
message_payloads::deposit_message_payload(
usdc_address, 100, snf::test_address(), snf::test_address(), false, array![].span()
)
);

assert(messaging.sn_to_appchain_messages(hash) == 1, 'Message not recieved');
}

#[test]
#[should_panic(expected: ('L3 bridge not set',))]
fn send_deposit_message_bridge_unset() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

let no_message: Span<felt252> = array![].span();
mock
.send_deposit_message(
usdc_address,
100,
snf::test_address(),
no_message,
constants::HANDLE_TOKEN_DEPOSIT_SELECTOR
);
}

#[test]
fn consume_message_ok() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

// Deploy messaging mock with 5 days cancellation delay
let messaging_mock_class_hash = snf::declare("messaging_mock").unwrap();
// Deploying with 5 days as the delay time (5 * 86400 = 432000)
let (messaging_contract_address, _) = messaging_mock_class_hash
.deploy(@array![DELAY_TIME])
.unwrap();

TokenBridge::constructor(ref mock, L3_BRIDGE_ADDRESS(), messaging_contract_address, OWNER());

let messaging_mock = IMockMessagingDispatcher { contract_address: messaging_contract_address };
// Register a withdraw message from appchain to piltover
messaging_mock
.process_message_to_starknet(
L3_BRIDGE_ADDRESS(),
snf::test_address(),
message_payloads::withdraw_message_payload_from_appchain(
usdc_address, 100, snf::test_address()
)
);

mock.consume_message(usdc_address, 100, snf::test_address());
}

#[test]
#[should_panic(expected: ('INVALID_MESSAGE_TO_CONSUME',))]
fn consume_message_no_message() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

// Deploy messaging mock with 5 days cancellation delay
let messaging_mock_class_hash = snf::declare("messaging_mock").unwrap();
// Deploying with 5 days as the delay time (5 * 86400 = 432000)
let (messaging_contract_address, _) = messaging_mock_class_hash
.deploy(@array![DELAY_TIME])
.unwrap();

TokenBridge::constructor(ref mock, L3_BRIDGE_ADDRESS(), messaging_contract_address, OWNER());

mock.consume_message(usdc_address, 100, snf::test_address());
}

#[test]
#[should_panic(expected: ('L3 bridge not set',))]
fn consume_message_bridge_unset() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

mock.consume_message(usdc_address, 100, snf::test_address());
}

#[test]
#[should_panic(expected: ('Invalid recipient',))]
fn consume_message_zero_recipient() {
let mut mock = mock_state_testing();
let usdc_address = USDC_MOCK_ADDRESS();

mock.appchain_bridge.write(L3_BRIDGE_ADDRESS());
mock.consume_message(usdc_address, 100, contract_address_const::<0>());
}
Loading

0 comments on commit afb386a

Please sign in to comment.