diff --git a/currencies/src/lib.rs b/currencies/src/lib.rs
index 7ec25e9ef10eb50eb0f8038e58c095ae7062638b..f52e0680318105c727c1a51e2b20e3e057583c87 100644
--- a/currencies/src/lib.rs
+++ b/currencies/src/lib.rs
@@ -48,6 +48,10 @@ decl_event!(
 		Transferred(CurrencyId, AccountId, AccountId, Balance),
 		/// Update balance success (currency_id, who, amount)
 		BalanceUpdated(CurrencyId, AccountId, Amount),
+		/// Deposit success (currency_id, who, amount)
+		Deposited(CurrencyId, AccountId, Balance),
+		/// Withdraw success (currency_id, who, amount)
+		Withdrawn(CurrencyId, AccountId, Balance),
 	}
 );
 
@@ -77,8 +81,6 @@ decl_module! {
 			let from = ensure_signed(origin)?;
 			let to = T::Lookup::lookup(dest)?;
 			<Self as MultiCurrency<T::AccountId>>::transfer(currency_id, &from, &to, amount)?;
-
-			Self::deposit_event(RawEvent::Transferred(currency_id, from, to, amount));
 		}
 
 		/// Transfer native currency balance from one account to another.
@@ -147,26 +149,32 @@ impl<T: Trait> MultiCurrency<T::AccountId> for Module<T> {
 		amount: Self::Balance,
 	) -> DispatchResult {
 		if currency_id == T::GetNativeCurrencyId::get() {
-			T::NativeCurrency::transfer(from, to, amount)
+			T::NativeCurrency::transfer(from, to, amount)?;
 		} else {
-			T::MultiCurrency::transfer(currency_id, from, to, amount)
+			T::MultiCurrency::transfer(currency_id, from, to, amount)?;
 		}
+		Self::deposit_event(RawEvent::Transferred(currency_id, from.clone(), to.clone(), amount));
+		Ok(())
 	}
 
 	fn deposit(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
 		if currency_id == T::GetNativeCurrencyId::get() {
-			T::NativeCurrency::deposit(who, amount)
+			T::NativeCurrency::deposit(who, amount)?;
 		} else {
-			T::MultiCurrency::deposit(currency_id, who, amount)
+			T::MultiCurrency::deposit(currency_id, who, amount)?;
 		}
+		Self::deposit_event(RawEvent::Deposited(currency_id, who.clone(), amount));
+		Ok(())
 	}
 
 	fn withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
 		if currency_id == T::GetNativeCurrencyId::get() {
-			T::NativeCurrency::withdraw(who, amount)
+			T::NativeCurrency::withdraw(who, amount)?;
 		} else {
-			T::MultiCurrency::withdraw(currency_id, who, amount)
+			T::MultiCurrency::withdraw(currency_id, who, amount)?;
 		}
+		Self::deposit_event(RawEvent::Withdrawn(currency_id, who.clone(), amount));
+		Ok(())
 	}
 
 	fn slash(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> Self::Balance {
diff --git a/currencies/src/mock.rs b/currencies/src/mock.rs
index 65b4540625e96f5f97c792f91a2ba2d1b71c2cb3..86ecaeff17c208512a31a39fabf4551bb823d775 100644
--- a/currencies/src/mock.rs
+++ b/currencies/src/mock.rs
@@ -2,7 +2,7 @@
 
 #![cfg(test)]
 
-use frame_support::{impl_outer_origin, parameter_types};
+use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
 use pallet_balances;
 use primitives::H256;
 use sp_runtime::{testing::Header, traits::IdentityLookup, Perbill};
@@ -11,6 +11,19 @@ use tokens;
 
 use super::*;
 
+mod currencies {
+	pub use crate::Event;
+}
+
+impl_outer_event! {
+	pub enum TestEvent for Runtime {
+		frame_system<T>,
+		currencies<T>,
+		tokens<T>,
+		pallet_balances<T>,
+	}
+}
+
 impl_outer_origin! {
 	pub enum Origin for Runtime where system = frame_system {}
 }
@@ -36,7 +49,7 @@ impl frame_system::Trait for Runtime {
 	type AccountId = AccountId;
 	type Lookup = IdentityLookup<Self::AccountId>;
 	type Header = Header;
-	type Event = ();
+	type Event = TestEvent;
 	type BlockHashCount = BlockHashCount;
 	type MaximumBlockWeight = MaximumBlockWeight;
 	type MaximumBlockLength = MaximumBlockLength;
@@ -47,6 +60,7 @@ impl frame_system::Trait for Runtime {
 	type OnNewAccount = ();
 	type OnReapAccount = ();
 }
+pub type System = system::Module<Runtime>;
 
 type CurrencyId = u32;
 type Balance = u64;
@@ -58,7 +72,7 @@ parameter_types! {
 impl pallet_balances::Trait for Runtime {
 	type Balance = Balance;
 	type DustRemoval = ();
-	type Event = ();
+	type Event = TestEvent;
 	type ExistentialDeposit = ExistentialDeposit;
 	type AccountStore = frame_system::Module<Runtime>;
 }
@@ -66,7 +80,7 @@ impl pallet_balances::Trait for Runtime {
 pub type PalletBalances = pallet_balances::Module<Runtime>;
 
 impl tokens::Trait for Runtime {
-	type Event = ();
+	type Event = TestEvent;
 	type Balance = Balance;
 	type Amount = i64;
 	type CurrencyId = CurrencyId;
@@ -82,7 +96,7 @@ parameter_types! {
 }
 
 impl Trait for Runtime {
-	type Event = ();
+	type Event = TestEvent;
 	type MultiCurrency = tokens::Module<Runtime>;
 	type NativeCurrency = AdaptedBasicCurrency;
 	type GetNativeCurrencyId = GetNativeCurrencyId;
diff --git a/currencies/src/tests.rs b/currencies/src/tests.rs
index 9ba7788be159604e739891971e74ae24d57b39e4..8f2bbf2099318988503260175087f5822a304709 100644
--- a/currencies/src/tests.rs
+++ b/currencies/src/tests.rs
@@ -5,8 +5,8 @@
 use super::*;
 use frame_support::{assert_noop, assert_ok};
 use mock::{
-	AccountId, AdaptedBasicCurrency, Currencies, ExtBuilder, NativeCurrency, Origin, PalletBalances, ALICE, BOB, EVA,
-	NATIVE_CURRENCY_ID, X_TOKEN_ID,
+	AccountId, AdaptedBasicCurrency, Currencies, ExtBuilder, NativeCurrency, Origin, PalletBalances, System, TestEvent,
+	ALICE, BOB, EVA, NATIVE_CURRENCY_ID, X_TOKEN_ID,
 };
 use sp_runtime::traits::BadOrigin;
 
@@ -169,3 +169,43 @@ fn update_balance_call_fails_if_not_root_origin() {
 		);
 	});
 }
+
+#[test]
+fn call_event_should_work() {
+	ExtBuilder::default()
+		.one_hundred_for_alice_n_bob()
+		.build()
+		.execute_with(|| {
+			assert_ok!(Currencies::transfer(Some(ALICE).into(), BOB, X_TOKEN_ID, 50));
+			assert_eq!(Currencies::balance(X_TOKEN_ID, &ALICE), 50);
+			assert_eq!(Currencies::balance(X_TOKEN_ID, &BOB), 150);
+
+			let transferred_event = TestEvent::currencies(RawEvent::Transferred(X_TOKEN_ID, ALICE, BOB, 50));
+			assert!(System::events().iter().any(|record| record.event == transferred_event));
+
+			assert_ok!(<Currencies as MultiCurrency<AccountId>>::transfer(
+				X_TOKEN_ID, &ALICE, &BOB, 10
+			));
+			assert_eq!(Currencies::balance(X_TOKEN_ID, &ALICE), 40);
+			assert_eq!(Currencies::balance(X_TOKEN_ID, &BOB), 160);
+
+			let transferred_event = TestEvent::currencies(RawEvent::Transferred(X_TOKEN_ID, ALICE, BOB, 10));
+			assert!(System::events().iter().any(|record| record.event == transferred_event));
+
+			assert_ok!(<Currencies as MultiCurrency<AccountId>>::deposit(
+				X_TOKEN_ID, &ALICE, 100
+			));
+			assert_eq!(Currencies::balance(X_TOKEN_ID, &ALICE), 140);
+
+			let transferred_event = TestEvent::currencies(RawEvent::Deposited(X_TOKEN_ID, ALICE, 100));
+			assert!(System::events().iter().any(|record| record.event == transferred_event));
+
+			assert_ok!(<Currencies as MultiCurrency<AccountId>>::withdraw(
+				X_TOKEN_ID, &ALICE, 20
+			));
+			assert_eq!(Currencies::balance(X_TOKEN_ID, &ALICE), 120);
+
+			let transferred_event = TestEvent::currencies(RawEvent::Withdrawn(X_TOKEN_ID, ALICE, 20));
+			assert!(System::events().iter().any(|record| record.event == transferred_event));
+		});
+}