diff --git a/Scarb.lock b/Scarb.lock
index 9ce4f52a..f7fb8280 100644
--- a/Scarb.lock
+++ b/Scarb.lock
@@ -11,34 +11,107 @@ name = "ekubo"
 version = "0.1.0"
 source = "git+https://github.com/ekuboprotocol/abis?rev=edb6de8#edb6de8c9baf515f1053bbab3d86825d54a63bc3"
 
+[[package]]
+name = "openzeppelin"
+version = "0.19.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:33174cc8f66cd2c1a527fd7f13a800dcb107d59f5c77e998e0c896a1da9cf1df"
+dependencies = [
+ "openzeppelin_access",
+ "openzeppelin_account",
+ "openzeppelin_finance",
+ "openzeppelin_governance",
+ "openzeppelin_introspection",
+ "openzeppelin_merkle_tree",
+ "openzeppelin_presets",
+ "openzeppelin_security",
+ "openzeppelin_token",
+ "openzeppelin_upgrades",
+ "openzeppelin_utils",
+]
+
+[[package]]
+name = "openzeppelin_access"
+version = "0.19.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:0f5055ef443327bb613a56a812ccf31157abfd7d36a18739556f78b67f5b1116"
+dependencies = [
+ "openzeppelin_introspection",
+ "openzeppelin_utils",
+]
+
 [[package]]
 name = "openzeppelin_account"
-version = "0.18.0"
+version = "0.19.0"
 source = "registry+https://scarbs.xyz/"
-checksum = "sha256:83e6571cac4c67049c8d0ab4e3c7ad146d582d7605e7354248835833e1d26c4a"
+checksum = "sha256:0c92c856e44080e3280788d1c46f89ac707c64fa555eb02c343e492709a1ee50"
 dependencies = [
  "openzeppelin_introspection",
  "openzeppelin_utils",
 ]
 
+[[package]]
+name = "openzeppelin_finance"
+version = "0.19.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:3d38c8aff02478431ddbb0538be5281a89eb159016105195bf6409bf6c3c4fc4"
+dependencies = [
+ "openzeppelin_access",
+ "openzeppelin_token",
+]
+
+[[package]]
+name = "openzeppelin_governance"
+version = "0.19.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:fc6afb45e3cdcb5e843bbc80c6e12bb2536a34f557b74787c256872b86f2a81a"
+dependencies = [
+ "openzeppelin_access",
+ "openzeppelin_account",
+ "openzeppelin_introspection",
+ "openzeppelin_token",
+]
+
 [[package]]
 name = "openzeppelin_introspection"
-version = "0.18.0"
+version = "0.19.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:a1dda07a91c447b83ccfcc4895897ec134917f0ff6d2ca876b93ea27466d7693"
+
+[[package]]
+name = "openzeppelin_merkle_tree"
+version = "0.19.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:e7aaa00b9ea0f73938d3be6351aaa88efd21304bf6d5fd1b66c61e048a7a2375"
+
+[[package]]
+name = "openzeppelin_presets"
+version = "0.19.0"
 source = "registry+https://scarbs.xyz/"
-checksum = "sha256:46c4cc6c95c9baa4c7d5cc0ed2bdaf334f46c25a8c92b3012829fff936e3042b"
+checksum = "sha256:57d5c48724025072419c63a929903d71b949287338dc86d561e52b52d869c06f"
+dependencies = [
+ "openzeppelin_access",
+ "openzeppelin_account",
+ "openzeppelin_finance",
+ "openzeppelin_introspection",
+ "openzeppelin_token",
+ "openzeppelin_upgrades",
+ "openzeppelin_utils",
+]
 
 [[package]]
 name = "openzeppelin_security"
-version = "0.18.0"
+version = "0.19.0"
 source = "registry+https://scarbs.xyz/"
-checksum = "sha256:1db3a41e02ed48806587981340ed01ee7d552c3ad52cb33a6d81c1ed5cba9ee0"
+checksum = "sha256:0f1462d6de898cd28199cde0110304b4248fb19c7e788d4121d26c93b290e991"
 
 [[package]]
 name = "openzeppelin_token"
-version = "0.18.0"
+version = "0.19.0"
 source = "registry+https://scarbs.xyz/"
-checksum = "sha256:eafbe13f6a0487ce212459e25a81ae07f340ba76208ad4616626eb2d25a9625e"
+checksum = "sha256:9cba10f666ca6dd83b581367438d04b244bd5bbf0cfad6a28d193d373c0498b8"
 dependencies = [
+ "openzeppelin_access",
  "openzeppelin_account",
  "openzeppelin_introspection",
  "openzeppelin_utils",
@@ -46,15 +119,15 @@ dependencies = [
 
 [[package]]
 name = "openzeppelin_upgrades"
-version = "0.18.0"
+version = "0.19.0"
 source = "registry+https://scarbs.xyz/"
-checksum = "sha256:33c9d0865364fc18a5e7b471fe53c3b0f3e0aec56a94f435089638fad2a4a35b"
+checksum = "sha256:3f2badf764a2219b0ea5b567b039daeb4c1707331f98e4f7b985ca2b562b4e10"
 
 [[package]]
 name = "openzeppelin_utils"
-version = "0.18.0"
+version = "0.19.0"
 source = "registry+https://scarbs.xyz/"
-checksum = "sha256:725b212839f3eddc32791408609099c5e808c167ca0cf331d8c1d778b07a4e21"
+checksum = "sha256:0e0e6f6b20b3c4075b92941a2c124430a59f1c207f8fbdfd56ce9239e6d666a8"
 
 [[package]]
 name = "pragma_lib"
@@ -80,9 +153,7 @@ version = "0.1.0"
 dependencies = [
  "alexandria_math",
  "ekubo",
- "openzeppelin_security",
- "openzeppelin_token",
- "openzeppelin_upgrades",
+ "openzeppelin",
  "pragma_lib",
  "snforge_std",
 ]
diff --git a/Scarb.toml b/Scarb.toml
index ef538667..0603cf05 100644
--- a/Scarb.toml
+++ b/Scarb.toml
@@ -10,9 +10,7 @@ cairo-version = "2.8.2"
 starknet = "2.8.2"
 ekubo = { git = "https://github.com/ekuboprotocol/abis", rev = "edb6de8" }
 alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev = "8208871" }
-openzeppelin_token = "0.18.0"
-openzeppelin_security = "0.18.0"
-openzeppelin_upgrades = "0.18.0"
+openzeppelin = "0.19.0"
 
 [dev-dependencies]
 pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib", tag = "2.8.2" }
diff --git a/src/deposit.cairo b/src/deposit.cairo
index 6209aac6..37de33f0 100644
--- a/src/deposit.cairo
+++ b/src/deposit.cairo
@@ -8,10 +8,11 @@ mod Deposit {
         types::{i129::i129, keys::PoolKey}
     };
 
-    use openzeppelin_security::ReentrancyGuardComponent;
-
-    use openzeppelin_token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait};
-    use openzeppelin_upgrades::{UpgradeableComponent, interface::IUpgradeable};
+    use openzeppelin::{
+        security::ReentrancyGuardComponent,
+        token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait},
+        upgrades::{UpgradeableComponent, interface::IUpgradeable}, access::ownable::OwnableComponent
+    };
     use spotnet::{
         constants::{ZK_SCALE_DECIMALS, STRK_ADDRESS},
         interfaces::{
@@ -33,18 +34,25 @@ mod Deposit {
         path: ReentrancyGuardComponent, storage: reentrancy_guard, event: ReentrancyGuardEvent
     );
     component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);
+    component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
+
+    impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
+    #[abi(embed_v0)]
+    impl OwnableTwoStepMixinImpl =
+        OwnableComponent::OwnableTwoStepMixinImpl<ContractState>;
 
     impl ReentrancyInternalImpl = ReentrancyGuardComponent::InternalImpl<ContractState>;
     impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;
 
     #[storage]
     struct Storage {
-        owner: ContractAddress,
         ekubo_core: ICoreDispatcher,
         zk_market: IMarketDispatcher,
         treasury: ContractAddress,
         is_position_open: bool,
         #[substorage(v0)]
+        ownable: OwnableComponent::Storage,
+        #[substorage(v0)]
         reentrancy_guard: ReentrancyGuardComponent::Storage,
         #[substorage(v0)]
         upgradeable: UpgradeableComponent::Storage
@@ -59,7 +67,7 @@ mod Deposit {
         treasury: ContractAddress
     ) {
         assert(owner.is_non_zero(), 'Owner address is zero');
-        self.owner.write(owner);
+        self.ownable.initializer(owner);
         self.ekubo_core.write(ekubo_core);
         self.zk_market.write(zk_market);
         self.treasury.write(treasury);
@@ -93,7 +101,8 @@ mod Deposit {
         supply_decimals: DecimalScale,
         debt_decimals: DecimalScale
     ) -> u256 {
-        let deposited = ((total_deposited * ZK_SCALE_DECIMALS * supply_token_price.into()) / supply_decimals.into());
+        let deposited = ((total_deposited * ZK_SCALE_DECIMALS * supply_token_price.into())
+            / supply_decimals.into());
         let free_amount = (((deposited * collateral_factor.into() / ZK_SCALE_DECIMALS)
             * borrow_factor.into()
             / ZK_SCALE_DECIMALS))
@@ -121,11 +130,27 @@ mod Deposit {
         repaid_amount: TokenAmount
     }
 
+    #[derive(starknet::Event, Drop)]
+    struct Withdraw {
+        token: ContractAddress,
+        amount: TokenAmount
+    }
+
+    #[derive(starknet::Event, Drop)]
+    struct ExtraDeposit {
+        token: ContractAddress,
+        amount: TokenAmount
+    }
+
     #[event]
     #[derive(Drop, starknet::Event)]
     enum Event {
         LiquidityLooped: LiquidityLooped,
         PositionClosed: PositionClosed,
+        Withdraw: Withdraw,
+        ExtraDeposit: ExtraDeposit,
+        #[flat]
+        OwnableEvent: OwnableComponent::Event,
         #[flat]
         ReentrancyGuardEvent: ReentrancyGuardComponent::Event,
         #[flat]
@@ -165,7 +190,7 @@ mod Deposit {
             pool_price: TokenPrice
         ) {
             let user_account = get_tx_info().unbox().account_contract_address;
-            assert(user_account == self.owner.read(), 'Caller is not the owner');
+            assert(user_account == self.ownable.owner(), 'Caller is not the owner');
             assert(!self.is_position_open.read(), 'Open position already exists');
             let DepositData { token, amount, multiplier, borrow_portion_percent } = deposit_data;
             assert(
@@ -193,7 +218,7 @@ mod Deposit {
                 (false, pool_key.token0, ekubo_limits.lower)
             };
 
-            token_dispatcher.transferFrom(self.owner.read(), curr_contract_address, amount);
+            token_dispatcher.transferFrom(self.ownable.owner(), curr_contract_address, amount);
             let (deposit_reserve_data, debt_reserve_data) = (
                 zk_market.get_reserve_data(token), zk_market.get_reserve_data(borrowing_token)
             );
@@ -203,6 +228,11 @@ mod Deposit {
                 debt_reserve_data.borrow_factor.into()
             );
 
+            assert(
+                deposit_reserve_data.enabled && debt_reserve_data.enabled,
+                'Reserves must be enabled'
+            );
+
             zk_market.enable_collateral(token);
 
             token_dispatcher.approve(zk_market.contract_address, amount);
@@ -293,7 +323,7 @@ mod Deposit {
             debt_price: TokenPrice
         ) {
             assert(
-                get_tx_info().unbox().account_contract_address == self.owner.read(),
+                get_tx_info().unbox().account_contract_address == self.ownable.owner(),
                 'Caller is not the owner'
             );
             assert(self.is_position_open.read(), 'Open position not exists');
@@ -309,6 +339,11 @@ mod Deposit {
                 debt_reserve_data.borrow_factor.into()
             );
 
+            assert(
+                deposit_reserve_data.enabled && debt_reserve_data.enabled,
+                'Reserves must be enabled'
+            );
+
             let z_token_disp = ERC20ABIDispatcher {
                 contract_address: deposit_reserve_data.z_token_address
             };
@@ -386,7 +421,7 @@ mod Deposit {
             zk_market.disable_collateral(supply_token);
             self.is_position_open.write(false);
             let withdrawn_amount = token_disp.balanceOf(contract_address);
-            token_disp.transfer(self.owner.read(), withdrawn_amount);
+            token_disp.transfer(self.ownable.owner(), withdrawn_amount);
             self
                 .emit(
                     PositionClosed {
@@ -465,10 +500,11 @@ mod Deposit {
             token_dispatcher.approve(zk_market.contract_address, amount);
             zk_market.enable_collateral(token);
             zk_market.deposit(token, amount.try_into().unwrap());
+            self.emit(ExtraDeposit { token, amount });
             self.reentrancy_guard.end();
         }
 
-        /// Withdraws tokens from zkLend if looped tokens are repaid
+        /// Withdraws tokens from zkLend
         ///
         /// # Panics
         /// address of account that started the transaction is not equal to `owner` storage variable
@@ -477,19 +513,25 @@ mod Deposit {
         /// `token`: TokenAddress - token address to withdraw from zkLend
         /// `amount`: TokenAmount - amount to withdraw. Pass `0` to withdraw all
         fn withdraw(ref self: ContractState, token: ContractAddress, amount: TokenAmount) {
-            assert(get_caller_address() == self.owner.read(), 'Caller is not the owner');
+            self.ownable.assert_only_owner();
             let zk_market = self.zk_market.read();
+
             let token_dispatcher = ERC20ABIDispatcher { contract_address: token };
+            let mut withdrawn_amount = amount;
             if amount == 0 {
+                let current_contract = get_contract_address();
+                let initial_balance = ERC20ABIDispatcher { contract_address: token }
+                    .balanceOf(current_contract);
                 zk_market.withdraw_all(token);
-                token_dispatcher
-                    .transfer(
-                        self.owner.read(), token_dispatcher.balanceOf(get_contract_address())
-                    );
+                let new_balance = ERC20ABIDispatcher { contract_address: token }
+                    .balanceOf(current_contract);
+                withdrawn_amount = new_balance - initial_balance;
+                token_dispatcher.transfer(self.ownable.owner(), new_balance);
             } else {
                 zk_market.withdraw(token, amount.try_into().unwrap());
-                token_dispatcher.transfer(self.owner.read(), amount);
+                token_dispatcher.transfer(self.ownable.owner(), amount);
             };
+            self.emit(Withdraw { token, amount: withdrawn_amount });
         }
     }
 
@@ -520,7 +562,7 @@ mod Deposit {
     impl UpgradeableImpl of IUpgradeable<ContractState> {
         fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
             // This function can only be called by the owner
-            assert(get_caller_address() == self.owner.read(), 'Caller is not the owner');
+            self.ownable.assert_only_owner();
 
             self.upgradeable.upgrade(new_class_hash);
         }
diff --git a/src/types.cairo b/src/types.cairo
index be93bc5d..61df23ba 100644
--- a/src/types.cairo
+++ b/src/types.cairo
@@ -40,7 +40,7 @@ pub struct Claim {
 
 #[derive(Drop, Serde, starknet::Store)]
 pub struct MarketReserveData {
-    enabled: bool,
+    pub enabled: bool,
     pub decimals: felt252,
     pub z_token_address: ContractAddress,
     interest_rate_model: ContractAddress,
diff --git a/tests/test_defispring.cairo b/tests/test_defispring.cairo
index 98016f3e..55fd4615 100644
--- a/tests/test_defispring.cairo
+++ b/tests/test_defispring.cairo
@@ -92,7 +92,7 @@ fn test_claim_and_withdraw() {
     let storage_entry_for_hypothetical_owner = array![HYPOTHETICAL_OWNER_ADDR].span();
     store(
         address_eligible_for_zklend_rewards,
-        selector!("owner"),
+        selector!("Ownable_owner"),
         storage_entry_for_hypothetical_owner
     );
 
diff --git a/tests/test_loop.cairo b/tests/test_loop.cairo
index dd2654db..08698def 100644
--- a/tests/test_loop.cairo
+++ b/tests/test_loop.cairo
@@ -2,7 +2,10 @@ use alexandria_math::fast_power::fast_power;
 use core::panic_with_felt252;
 use ekubo::interfaces::core::{ICoreDispatcher, ICoreDispatcherTrait};
 use ekubo::types::keys::{PoolKey};
-use openzeppelin_token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait};
+use openzeppelin::access::ownable::interface::{
+    OwnableTwoStepABIDispatcherTrait, OwnableTwoStepABIDispatcher
+};
+use openzeppelin::token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait};
 
 use pragma_lib::abi::{IPragmaABIDispatcher, IPragmaABIDispatcherTrait};
 use pragma_lib::types::{AggregationMode, DataType, PragmaPricesResponse};
@@ -263,7 +266,13 @@ fn test_loop_unauthorized() {
             + ERC20ABIDispatcher { contract_address: usdc_addr }.decimals())
             .into()
     );
-    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / get_asset_price_pragma('ETH/USD').into()) / ZK_SCALE_DECIMALS).try_into().unwrap();
+    let pool_price = ((1
+        * ZK_SCALE_DECIMALS
+        * decimals_sum_power.into()
+        / get_asset_price_pragma('ETH/USD').into())
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
 
     let disp = get_deposit_dispatcher(user);
 
@@ -308,7 +317,13 @@ fn test_loop_position_exists() {
         (ERC20ABIDispatcher { contract_address: eth_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / get_asset_price_pragma('ETH/USD').into()) / ZK_SCALE_DECIMALS).try_into().unwrap();
+    let pool_price = ((1
+        * ZK_SCALE_DECIMALS
+        * decimals_sum_power.into()
+        / get_asset_price_pragma('ETH/USD').into())
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
     let deposit_disp = get_deposit_dispatcher(user);
     start_cheat_caller_address(usdc_addr.try_into().unwrap(), user);
     token_disp.approve(deposit_disp.contract_address, 60000000);
@@ -429,7 +444,13 @@ fn test_close_position_usdc_valid_time_passed() {
         (ERC20ABIDispatcher { contract_address: eth_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / get_asset_price_pragma('ETH/USD').into()) / ZK_SCALE_DECIMALS).try_into().unwrap();
+    let pool_price = ((1
+        * ZK_SCALE_DECIMALS
+        * decimals_sum_power.into()
+        / get_asset_price_pragma('ETH/USD').into())
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
     let deposit_disp = get_deposit_dispatcher(user);
 
     start_cheat_caller_address(usdc_addr.try_into().unwrap(), user);
@@ -500,7 +521,8 @@ fn test_close_position_amounts_cleared() {
         (ERC20ABIDispatcher { contract_address: eth_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let pool_price = (1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / quote_token_price.into()) / ZK_SCALE_DECIMALS;
+    let pool_price = (1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / quote_token_price.into())
+        / ZK_SCALE_DECIMALS;
     let deposit_disp = get_deposit_dispatcher(user);
 
     start_cheat_caller_address(usdc_addr.try_into().unwrap(), user);
@@ -575,7 +597,10 @@ fn test_close_position_partial_debt_utilization() {
         (ERC20ABIDispatcher { contract_address: usdc_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let quote_token_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / pool_price.into()) / ZK_SCALE_DECIMALS).try_into().unwrap();
+    let quote_token_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / pool_price.into())
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
 
     let deposit_disp = get_deposit_dispatcher(user);
 
@@ -651,7 +676,10 @@ fn test_extra_deposit_valid() {
         (ERC20ABIDispatcher { contract_address: eth_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / quote_token_price) / ZK_SCALE_DECIMALS).try_into().unwrap();
+    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / quote_token_price)
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
     let deposit_disp = get_deposit_dispatcher(user);
 
     start_cheat_caller_address(usdc_addr.try_into().unwrap(), user);
@@ -662,7 +690,7 @@ fn test_extra_deposit_valid() {
     deposit_disp
         .loop_liquidity(
             DepositData {
-                token: usdc_addr, amount: 1000000000, multiplier: 4, borrow_portion_percent: 98
+                token: usdc_addr, amount: 1000000000, multiplier: 4, borrow_portion_percent: 95
             },
             pool_key,
             get_slippage_limits(pool_key),
@@ -721,7 +749,10 @@ fn test_extra_deposit_supply_token_close_position_fuzz(extra_amount: u32) {
         (ERC20ABIDispatcher { contract_address: eth_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let pool_price = 1 * decimals_sum_power.into() / quote_token_price;
+    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / quote_token_price)
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
     let deposit_disp = get_deposit_dispatcher(user);
 
     start_cheat_caller_address(usdc_addr.try_into().unwrap(), user);
@@ -767,7 +798,7 @@ fn test_extra_deposit_supply_token_close_position_fuzz(extra_amount: u32) {
             get_slippage_limits(pool_key),
             95,
             pool_price,
-            quote_token_price
+            quote_token_price.try_into().unwrap()
         );
     stop_cheat_account_contract_address(deposit_disp.contract_address);
 
@@ -810,7 +841,13 @@ fn test_withdraw_valid_fuzz(amount: u32) {
         (ERC20ABIDispatcher { contract_address: eth_addr }.decimals() + token_disp.decimals())
             .into()
     );
-    let pool_price = ((1 * ZK_SCALE_DECIMALS * decimals_sum_power.into() / get_asset_price_pragma('ETH/USD').into()) / ZK_SCALE_DECIMALS).try_into().unwrap();
+    let pool_price = ((1
+        * ZK_SCALE_DECIMALS
+        * decimals_sum_power.into()
+        / get_asset_price_pragma('ETH/USD').into())
+        / ZK_SCALE_DECIMALS)
+        .try_into()
+        .unwrap();
     let deposit_disp = get_deposit_dispatcher(user);
 
     start_cheat_caller_address(usdc_addr.try_into().unwrap(), user);
@@ -1001,3 +1038,48 @@ fn test_withdraw_position_open() {
     deposit_disp.withdraw(eth_addr, 100000000000000);
     stop_cheat_caller_address(deposit_disp.contract_address);
 }
+
+#[test]
+fn test_transfer_ownership_valid() {
+    let user = 0x123.try_into().unwrap();
+    let new_owner = 0x456.try_into().unwrap();
+    let deposit_disp = get_deposit_dispatcher(user);
+    let ownable_disp = OwnableTwoStepABIDispatcher {
+        contract_address: deposit_disp.contract_address
+    };
+    start_cheat_caller_address(deposit_disp.contract_address, user);
+    ownable_disp.transfer_ownership(new_owner);
+    stop_cheat_caller_address(deposit_disp.contract_address);
+
+    start_cheat_caller_address(deposit_disp.contract_address, new_owner);
+    ownable_disp.accept_ownership();
+    stop_cheat_caller_address(deposit_disp.contract_address);
+
+    assert(ownable_disp.owner() == new_owner, 'Owner did not change');
+}
+
+#[test]
+#[should_panic(expected: 'Caller is not the pending owner')]
+fn test_transfer_renounced_ownership() {
+    let user = 0x123.try_into().unwrap();
+    let new_owner = 0x456.try_into().unwrap();
+    let deposit_disp = get_deposit_dispatcher(user);
+    let ownable_disp = OwnableTwoStepABIDispatcher {
+        contract_address: deposit_disp.contract_address
+    };
+    start_cheat_caller_address(deposit_disp.contract_address, user);
+    ownable_disp.transfer_ownership(new_owner);
+    stop_cheat_caller_address(deposit_disp.contract_address);
+
+    assert(ownable_disp.pending_owner() == new_owner, 'Pending owner is incorrect');
+
+    start_cheat_caller_address(deposit_disp.contract_address, user);
+    ownable_disp.transfer_ownership(user);
+    stop_cheat_caller_address(deposit_disp.contract_address);
+
+    start_cheat_caller_address(deposit_disp.contract_address, new_owner);
+    ownable_disp.accept_ownership();
+    stop_cheat_caller_address(deposit_disp.contract_address);
+
+    assert(ownable_disp.owner() == new_owner, 'Owner did not change');
+}