Skip to content

Commit

Permalink
Testcases (#3)
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

* Update src/bridge/token_bridge.cairo

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

* resolve comments

---------

Co-authored-by: Apoorv Sadana <[email protected]>
  • Loading branch information
byteZorvin and apoorvsadana committed Jul 31, 2024
1 parent 20dab01 commit 2b044ad
Show file tree
Hide file tree
Showing 11 changed files with 446 additions and 178 deletions.
2 changes: 1 addition & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v

[[target.starknet-contract]]
casm = true
build-external-contracts = ["piltover::appchain::appchain"]
build-external-contracts = ["piltover::messaging::mock::messaging_mock"]

[scripts]
test = "snforge test"
14 changes: 0 additions & 14 deletions scripts/my_script/Scarb.lock

This file was deleted.

10 changes: 0 additions & 10 deletions scripts/my_script/Scarb.toml

This file was deleted.

1 change: 0 additions & 1 deletion scripts/my_script/src/lib.cairo

This file was deleted.

2 changes: 1 addition & 1 deletion src/bridge/interface.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub trait ITokenBridge<TContractState> {
appchain_recipient: ContractAddress,
nonce: felt252
);
fn get_remaining_intraday_allowance(self: @TContractState, token: ContractAddress) -> u256;
fn get_max_total_balance(self: @TContractState, token: ContractAddress) -> u256;
}

#[starknet::interface]
Expand Down
165 changes: 80 additions & 85 deletions src/bridge/token_bridge.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[starknet::contract]
pub mod TokenBridge {
use openzeppelin::access::ownable::ownable::OwnableComponent::InternalTrait;
use starknet_bridge::withdrawal_limit::component::WithdrawalLimitComponent::InternalTrait;
use core::option::OptionTrait;
use core::traits::TryInto;
use core::starknet::event::EventEmitter;
Expand Down Expand Up @@ -86,12 +86,13 @@ pub mod TokenBridge {
pub const CANNOT_DEACTIVATE: felt252 = 'Cannot deactivate and block';
pub const CANNOT_BLOCK: felt252 = 'Cannot block';
pub const INVALID_RECIPIENT: felt252 = 'Invalid recipient';
pub const MAX_BALANCE_EXCEEDED: felt252 = 'Max Balance Exceeded';
}


#[derive(Drop, starknet::Event)]
#[event]
enum Event {
pub enum Event {
TokenEnrollmentInitiated: TokenEnrollmentInitiated,
TokenDeactivated: TokenDeactivated,
TokenBlocked: TokenBlocked,
Expand All @@ -117,129 +118,130 @@ pub mod TokenBridge {
}

#[derive(Drop, starknet::Event)]
struct TokenDeactivated {
token: ContractAddress
pub struct TokenDeactivated {
pub token: ContractAddress
}

#[derive(Drop, starknet::Event)]
struct TokenBlocked {
token: ContractAddress
pub struct TokenBlocked {
pub token: ContractAddress
}

#[derive(Drop, starknet::Event)]
struct TokenEnrollmentInitiated {
token: ContractAddress,
deployment_message_hash: MessageHash
pub struct TokenEnrollmentInitiated {
pub token: ContractAddress,
pub deployment_message_hash: MessageHash
}


#[derive(Drop, starknet::Event)]
struct Deposit {
pub struct Deposit {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
#[key]
appchain_recipient: ContractAddress,
nonce: Nonce,
pub appchain_recipient: ContractAddress,
pub nonce: felt252,
}

#[derive(Drop, starknet::Event)]
struct DepositWithMessage {
pub struct DepositWithMessage {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
#[key]
appchain_recipient: ContractAddress,
message: Span<felt252>,
nonce: Nonce,
pub appchain_recipient: ContractAddress,
pub message: Span<felt252>,
pub nonce: felt252,
}

#[derive(Drop, starknet::Event)]
struct DepositCancelRequest {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
#[key]
appchain_recipient: ContractAddress,
nonce: Nonce,
pub appchain_recipient: ContractAddress,
pub nonce: felt252,
}

#[derive(Drop, starknet::Event)]
struct DepositWithMessageCancelRequest {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
#[key]
appchain_recipient: ContractAddress,
message: Span<felt252>,
nonce: felt252
pub appchain_recipient: ContractAddress,
pub message: Span<felt252>,
pub nonce: felt252
}

#[derive(Drop, starknet::Event)]
struct DepositReclaimed {
pub struct DepositReclaimed {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
#[key]
appchain_recipient: ContractAddress,
nonce: Nonce
pub appchain_recipient: ContractAddress,
pub nonce: felt252
}

#[derive(Drop, starknet::Event)]
struct DepositWithMessageReclaimed {
pub struct DepositWithMessageReclaimed {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
#[key]
appchain_recipient: ContractAddress,
message: Span<felt252>,
nonce: Nonce
pub appchain_recipient: ContractAddress,
pub message: Span<felt252>,
pub nonce: felt252
}

#[derive(Drop, starknet::Event)]
struct Withdrawal {
pub struct Withdrawal {
#[key]
recipient: ContractAddress,
pub recipient: ContractAddress,
#[key]
token: ContractAddress,
amount: u256,
pub token: ContractAddress,
pub amount: u256,
}

#[derive(Drop, starknet::Event)]
struct WithdrawalLimitEnabled {
pub struct WithdrawalLimitEnabled {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
pub token: ContractAddress,
}

#[derive(Drop, starknet::Event)]
struct WithdrawalLimitDisabled {
pub struct WithdrawalLimitDisabled {
#[key]
sender: ContractAddress,
pub sender: ContractAddress,
#[key]
token: ContractAddress,
pub token: ContractAddress,
}

#[derive(Drop, starknet::Event)]
struct SetMaxTotalBalance {
pub struct SetMaxTotalBalance {
#[key]
token: ContractAddress,
value: u256
pub token: ContractAddress,
pub value: u256
}


#[derive(Drop, starknet::Event)]
pub struct SetAppchainBridge {
pub appchain_bridge: ContractAddress
Expand Down Expand Up @@ -322,7 +324,10 @@ pub mod TokenBridge {
self.is_servicing_token(token);
let caller = get_caller_address();
let dispatcher = IERC20Dispatcher { contract_address: token };
assert(dispatcher.balance_of(caller) == amount, 'Not enough balance');

let current_balance: u256 = dispatcher.balance_of(get_contract_address());
let max_total_balance = self.get_max_total_balance(token);
assert(current_balance + amount < max_total_balance, Errors::MAX_BALANCE_EXCEEDED);
dispatcher.transfer_from(caller, get_contract_address(), amount);
}
}
Expand Down Expand Up @@ -368,7 +373,7 @@ pub mod TokenBridge {
self.ownable.assert_only_owner();
self.appchain_bridge.write(appchain_bridge);

self.emit(SetAppchainBridge { appchain_bridge: appchain_bridge });
self.emit(SetAppchainBridge { appchain_bridge });
}

// @param token The address of the token contract to be deactivated.
Expand Down Expand Up @@ -460,16 +465,19 @@ pub mod TokenBridge {
.sn_to_appchain_messages(deployment_message_hash);
assert(nonce.is_non_zero(), Errors::DEPLOYMENT_MESSAGE_DOES_NOT_EXIST);

let token_status = TokenSettings {
// Reading existing settings as withdrawal_limit_applied and max_total_balance
// can be set before the token is enrolled.

let old_settings = self.token_settings.read(token);
let new_settings = TokenSettings {
token_status: TokenStatus::Pending,
deployment_message_hash: deployment_message_hash,
pending_deployment_expiration: get_block_timestamp()
+ constants::MAX_PENDING_DURATION.try_into().unwrap(),
max_total_balance: core::integer::BoundedInt::max(),
withdrawal_limit_applied: false
..old_settings
};

self.token_settings.write(token, token_status);
self.token_settings.write(token, new_settings);
self.emit(TokenEnrollmentInitiated { token, deployment_message_hash });
}

Expand Down Expand Up @@ -516,7 +524,6 @@ pub mod TokenBridge {
appchain_recipient: ContractAddress,
message: Span<felt252>
) {
self.reentrancy_guard.start();
self.accept_deposit(token, amount);
let nonce = self
.send_deposit_message(
Expand Down Expand Up @@ -576,10 +583,9 @@ pub mod TokenBridge {
assert(recipient.is_non_zero(), Errors::INVALID_RECIPIENT);

self.consume_message(token, amount, recipient);
let settings = self.token_settings.read(token);
// TODO: Consume quota from here
// DEP(byteZorvin): Complete the withdrawal component in cairo
if (settings.withdrawal_limit_applied) {}

self.withdrawal.consume_withdrawal_quota(token, amount);

let tokenDispatcher = IERC20Dispatcher { contract_address: token };
tokenDispatcher.transfer(recipient, amount);
self.reentrancy_guard.end();
Expand Down Expand Up @@ -730,23 +736,12 @@ pub mod TokenBridge {
self.token_settings.read(token).token_status == TokenStatus::Active
}

// /**
// Returns the remaining amount of withdrawal allowed for this day.
// If the daily allowance was not yet set, it is calculated and returned.
// If the withdraw limit is not enabled for that token - the uint256.max is returned.
// */
// function getRemainingIntradayAllowance(address token) external view returns (uint256) {
// return
// tokenSettings()[token].withdrawalLimitApplied
// ? WithdrawalLimit.getRemainingIntradayAllowance(token)
// : type(uint256).max;
// }
fn get_remaining_intraday_allowance(self: @ContractState, token: ContractAddress) -> u256 {
if (self.token_settings.read(token).withdrawal_limit_applied) {
fn get_max_total_balance(self: @ContractState, token: ContractAddress) -> u256 {
let max_total_balance = self.token_settings.read(token).max_total_balance;
if (max_total_balance == 0) {
return core::integer::BoundedInt::max();
}
// TODO: Write the WithdrawalLimit functionality
return 0;
return max_total_balance;
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ pub mod bridge {
pub mod token_bridge;
pub mod interface;
pub mod types;

pub use token_bridge::TokenBridge;
pub use interface::{
ITokenBridge, ITokenBridgeAdmin, IWithdrawalLimitStatus, ITokenBridgeDispatcher,
ITokenBridgeAdminDispatcher, IWithdrawalLimitStatusDispatcher,
IWithdrawalLimitStatusDispatcherTrait, ITokenBridgeDispatcherTrait,
ITokenBridgeAdminDispatcherTrait
};
}

pub mod withdrawal_limit {
Expand Down
3 changes: 1 addition & 2 deletions src/withdrawal_limit/component.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#[starknet::component]
pub mod WithdrawalLimitComponent {
use starknet::{ContractAddress, get_block_timestamp, get_contract_address};
use starknet_bridge::bridge::interface::IWithdrawalLimitStatus;
use starknet_bridge::constants;
use starknet_bridge::{constants, bridge::IWithdrawalLimitStatus};
use core::integer::BoundedInt;

use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};
Expand Down
14 changes: 14 additions & 0 deletions tests/constants.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use starknet::{ContractAddress, contract_address_const};

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

pub fn L3_BRIDGE_ADDRESS() -> ContractAddress {
contract_address_const::<'l3_bridge_address'>()
}


// 5 days as the delay time (5 * 86400 = 432000)
pub const DELAY_TIME: felt252 = 432000;

3 changes: 2 additions & 1 deletion tests/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod token_bridge_test;
pub mod token_bridge_test;
pub mod constants;

Loading

0 comments on commit 2b044ad

Please sign in to comment.