diff --git a/authority/src/default_weight.rs b/authority/src/default_weight.rs
index 818c0509065e703780a5c8bc4ec755d01ee39a6d..7f30ef57628cb0ae60555229419e7960bf3c89c9 100644
--- a/authority/src/default_weight.rs
+++ b/authority/src/default_weight.rs
@@ -1,33 +1,42 @@
+//! Weights for orml_authority
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0
+//! DATE: 2020-11-18, STEPS: [1, ], REPEAT: 1, LOW RANGE: [], HIGH RANGE: []
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB
+//! CACHE: 128
 
 #![allow(unused_parens)]
 #![allow(unused_imports)]
-#![allow(clippy::unnecessary_cast)]
 
 use frame_support::weights::{constants::RocksDbWeight as DbWeight, Weight};
+use sp_std::marker::PhantomData;
 
+/// Weight functions for orml_authority.
 impl crate::WeightInfo for () {
 	fn dispatch_as() -> Weight {
-		(43_132_000 as Weight)
+		(48_680_000 as Weight)
 	}
 	fn schedule_dispatch_without_delay() -> Weight {
-		(123_715_000 as Weight)
+		(121_510_000 as Weight)
 			.saturating_add(DbWeight::get().reads(3 as Weight))
 			.saturating_add(DbWeight::get().writes(3 as Weight))
 	}
 	fn schedule_dispatch_with_delay() -> Weight {
-		(116_719_000 as Weight)
+		(130_696_000 as Weight)
 			.saturating_add(DbWeight::get().reads(3 as Weight))
 			.saturating_add(DbWeight::get().writes(3 as Weight))
 	}
 	fn fast_track_scheduled_dispatch() -> Weight {
-		(59_055_000 as Weight)
+		(145_530_000 as Weight)
+			.saturating_add(DbWeight::get().reads(3 as Weight))
+			.saturating_add(DbWeight::get().writes(3 as Weight))
 	}
 	fn delay_scheduled_dispatch() -> Weight {
-		(44_796_000 as Weight)
+		(145_169_000 as Weight)
+			.saturating_add(DbWeight::get().reads(3 as Weight))
+			.saturating_add(DbWeight::get().writes(3 as Weight))
 	}
 	fn cancel_scheduled_dispatch() -> Weight {
-		(140_123_000 as Weight)
+		(104_990_000 as Weight)
 			.saturating_add(DbWeight::get().reads(2 as Weight))
 			.saturating_add(DbWeight::get().writes(2 as Weight))
 	}
diff --git a/authority/src/lib.rs b/authority/src/lib.rs
index 6f889cccd567e6525173ee268b7793cd35e6e259..b924d344ad34b626d23d708b78256f9d15675e9b 100644
--- a/authority/src/lib.rs
+++ b/authority/src/lib.rs
@@ -167,6 +167,10 @@ decl_error! {
 		FailedToSchedule,
 		/// Failed to cancel a task.
 		FailedToCancel,
+		/// Failed to fast track a task.
+		FailedToFastTrack,
+		/// Failed to delay a task.
+		FailedToDelay,
 	}
 }
 
@@ -266,7 +270,6 @@ decl_module! {
 		}
 
 		/// Fast track a scheduled dispatchable.
-		/// WARN: This is not fully implemented.
 		#[weight = T::WeightInfo::fast_track_scheduled_dispatch()]
 		pub fn fast_track_scheduled_dispatch(
 			origin,
@@ -281,34 +284,34 @@ decl_module! {
 				DispatchTime::After(x) => x
 			};
 
-			T::AuthorityConfig::check_fast_track_schedule(origin, &initial_origin, new_delay)?;
-
-			let now = frame_system::Module::<T>::block_number();
-
-			let when = match when {
+			let dispatch_at = match when {
 				DispatchTime::At(x) => x,
 				DispatchTime::After(x) => now.saturating_add(x)
 			};
 
-			// TODO: depends https://github.com/paritytech/substrate/issues/6774
+			T::AuthorityConfig::check_fast_track_schedule(origin, &initial_origin, new_delay)?;
+
+			T::Scheduler::reschedule_named((&initial_origin, task_id).encode(), when).map_err(|_| Error::<T>::FailedToFastTrack)?;
 
-			Self::deposit_event(RawEvent::FastTracked(initial_origin, task_id, when));
+			Self::deposit_event(RawEvent::FastTracked(initial_origin, task_id, dispatch_at));
 		}
 
 		/// Delay a scheduled dispatchable.
-		/// WARN: This is not fully implemented.
 		#[weight = T::WeightInfo::delay_scheduled_dispatch()]
 		pub fn delay_scheduled_dispatch(
 			origin,
 			initial_origin: T::PalletsOrigin,
 			task_id: ScheduleTaskIndex,
-			_additional_delay: T::BlockNumber,
+			additional_delay: T::BlockNumber,
 		) {
 			T::AuthorityConfig::check_delay_schedule(origin, &initial_origin)?;
 
-			// TODO: depends https://github.com/paritytech/substrate/issues/6774
+			T::Scheduler::reschedule_named((&initial_origin, task_id).encode(), DispatchTime::After(additional_delay)).map_err(|_| Error::<T>::FailedToDelay)?;
+
+			let now = frame_system::Module::<T>::block_number();
+			let dispatch_at = now.saturating_add(additional_delay);
 
-			Self::deposit_event(RawEvent::Delayed(initial_origin, task_id, 0u32.into()));
+			Self::deposit_event(RawEvent::Delayed(initial_origin, task_id, dispatch_at));
 		}
 
 		/// Cancel a scheduled dispatchable.
diff --git a/authority/src/tests.rs b/authority/src/tests.rs
index 29bb6d43cc484497bceeb8a5fa596e0eb652fc15..a1c18d5d4294e9b81ae9462467d2be58b440a47c 100644
--- a/authority/src/tests.rs
+++ b/authority/src/tests.rs
@@ -172,30 +172,147 @@ fn schedule_dispatch_after_work() {
 fn fast_track_scheduled_dispatch_work() {
 	ExtBuilder::default().build().execute_with(|| {
 		System::set_block_number(1);
-		//let ensure_root_call =
-		// Call::System(frame_system::Call::fill_block(Perbill::one()));
-		// let ensure_signed_call = Call::System(frame_system::Call::remark(vec![]));
+		let ensure_root_call = Call::System(frame_system::Call::fill_block(Perbill::one()));
+		let call = Call::Authority(authority::Call::dispatch_as(
+			MockAsOriginId::Root,
+			Box::new(ensure_root_call.clone()),
+		));
+		run_to_block(1);
+		assert_ok!(Authority::schedule_dispatch(
+			Origin::root(),
+			DispatchTime::At(2),
+			0,
+			true,
+			Box::new(call.clone())
+		));
+		let event = mock::Event::authority(RawEvent::Scheduled(
+			OriginCaller::authority(DelayedOrigin {
+				delay: 1,
+				origin: Box::new(OriginCaller::system(RawOrigin::Root)),
+			}),
+			0,
+		));
+		assert!(System::events().iter().any(|record| record.event == event));
+
+		let schedule_origin = {
+			let origin: <Runtime as Trait>::Origin = From::from(Origin::root());
+			let origin: <Runtime as Trait>::Origin =
+				From::from(DelayedOrigin::<BlockNumber, <Runtime as Trait>::PalletsOrigin> {
+					delay: 1,
+					origin: Box::new(origin.caller().clone()),
+				});
+			origin
+		};
+
+		let pallets_origin = schedule_origin.caller().clone();
 		assert_ok!(Authority::fast_track_scheduled_dispatch(
 			Origin::root(),
-			frame_system::RawOrigin::Root.into(),
+			pallets_origin,
 			0,
 			DispatchTime::At(4),
 		));
+		let event = mock::Event::authority(RawEvent::FastTracked(
+			OriginCaller::authority(DelayedOrigin {
+				delay: 1,
+				origin: Box::new(OriginCaller::system(RawOrigin::Root)),
+			}),
+			0,
+			4,
+		));
+		assert!(System::events().iter().any(|record| record.event == event));
+
+		assert_ok!(Authority::schedule_dispatch(
+			Origin::root(),
+			DispatchTime::At(2),
+			0,
+			false,
+			Box::new(call.clone())
+		));
+		let event = mock::Event::authority(RawEvent::Scheduled(OriginCaller::system(RawOrigin::Root), 1));
+		assert!(System::events().iter().any(|record| record.event == event));
+
+		assert_ok!(Authority::fast_track_scheduled_dispatch(
+			Origin::root(),
+			frame_system::RawOrigin::Root.into(),
+			1,
+			DispatchTime::At(4),
+		));
+		let event = mock::Event::authority(RawEvent::FastTracked(OriginCaller::system(RawOrigin::Root), 1, 4));
+		assert!(System::events().iter().any(|record| record.event == event));
 	});
 }
 
 #[test]
 fn delay_scheduled_dispatch_work() {
 	ExtBuilder::default().build().execute_with(|| {
-		//let ensure_root_call =
-		// Call::System(frame_system::Call::fill_block(Perbill::one()));
-		// let ensure_signed_call = Call::System(frame_system::Call::remark(vec![]));
+		System::set_block_number(1);
+		let ensure_root_call = Call::System(frame_system::Call::fill_block(Perbill::one()));
+		let call = Call::Authority(authority::Call::dispatch_as(
+			MockAsOriginId::Root,
+			Box::new(ensure_root_call.clone()),
+		));
+		run_to_block(1);
+		assert_ok!(Authority::schedule_dispatch(
+			Origin::root(),
+			DispatchTime::At(2),
+			0,
+			true,
+			Box::new(call.clone())
+		));
+		let event = mock::Event::authority(RawEvent::Scheduled(
+			OriginCaller::authority(DelayedOrigin {
+				delay: 1,
+				origin: Box::new(OriginCaller::system(RawOrigin::Root)),
+			}),
+			0,
+		));
+		assert!(System::events().iter().any(|record| record.event == event));
+
+		let schedule_origin = {
+			let origin: <Runtime as Trait>::Origin = From::from(Origin::root());
+			let origin: <Runtime as Trait>::Origin =
+				From::from(DelayedOrigin::<BlockNumber, <Runtime as Trait>::PalletsOrigin> {
+					delay: 1,
+					origin: Box::new(origin.caller().clone()),
+				});
+			origin
+		};
+
+		let pallets_origin = schedule_origin.caller().clone();
 		assert_ok!(Authority::delay_scheduled_dispatch(
 			Origin::root(),
-			frame_system::RawOrigin::Root.into(),
+			pallets_origin,
+			0,
+			4,
+		));
+		let event = mock::Event::authority(RawEvent::Delayed(
+			OriginCaller::authority(DelayedOrigin {
+				delay: 1,
+				origin: Box::new(OriginCaller::system(RawOrigin::Root)),
+			}),
 			0,
 			5,
 		));
+		assert!(System::events().iter().any(|record| record.event == event));
+
+		assert_ok!(Authority::schedule_dispatch(
+			Origin::root(),
+			DispatchTime::At(2),
+			0,
+			false,
+			Box::new(call.clone())
+		));
+		let event = mock::Event::authority(RawEvent::Scheduled(OriginCaller::system(RawOrigin::Root), 1));
+		assert!(System::events().iter().any(|record| record.event == event));
+
+		assert_ok!(Authority::delay_scheduled_dispatch(
+			Origin::root(),
+			frame_system::RawOrigin::Root.into(),
+			1,
+			4,
+		));
+		let event = mock::Event::authority(RawEvent::Delayed(OriginCaller::system(RawOrigin::Root), 1, 5));
+		assert!(System::events().iter().any(|record| record.event == event));
 	});
 }
 
@@ -243,7 +360,6 @@ fn cancel_scheduled_dispatch_work() {
 			}),
 			0,
 		));
-		println!("{:?}", System::events());
 		assert!(System::events().iter().any(|record| record.event == event));
 
 		assert_ok!(Authority::schedule_dispatch(
diff --git a/vesting/src/lib.rs b/vesting/src/lib.rs
index dd220daf4e56a364a90a39e5fba0dd251d45eeb4..72bf9cd5079e0f0dfaf99630ac85a00deb59e854 100644
--- a/vesting/src/lib.rs
+++ b/vesting/src/lib.rs
@@ -292,7 +292,8 @@ impl<T: Trait> Module<T> {
 		})
 	}
 
-	fn _do_vested_transfer(from: &T::AccountId, to: &T::AccountId, schedule: VestingScheduleOf<T>) -> DispatchResult {
+	#[transactional]
+	fn do_vested_transfer(from: &T::AccountId, to: &T::AccountId, schedule: VestingScheduleOf<T>) -> DispatchResult {
 		let schedule_amount = Self::ensure_valid_vesting_schedule(&schedule)?;
 
 		ensure!(
@@ -307,17 +308,9 @@ impl<T: Trait> Module<T> {
 		T::Currency::transfer(from, to, schedule_amount, ExistenceRequirement::AllowDeath)?;
 		T::Currency::set_lock(VESTING_LOCK_ID, to, total_amount, WithdrawReasons::all());
 		<VestingSchedules<T>>::append(to, schedule);
-
 		Ok(())
 	}
 
-	#[transactional]
-	fn do_vested_transfer(from: &T::AccountId, to: &T::AccountId, schedule: VestingScheduleOf<T>) -> DispatchResult {
-		// workaround bug of #[transactional] does not handle return in body correctly.
-		// TODO: Update once https://github.com/paritytech/substrate/pull/7188 is available.
-		Self::_do_vested_transfer(from, to, schedule)
-	}
-
 	fn do_update_vesting_schedules(who: &T::AccountId, schedules: Vec<VestingScheduleOf<T>>) -> DispatchResult {
 		let total_amount = schedules.iter().try_fold::<_, _, Result<BalanceOf<T>, Error<T>>>(
 			Zero::zero(),