diff --git a/substrate/frame/aura/Cargo.toml b/substrate/frame/aura/Cargo.toml
index 467f684af594a6eab88d5d96a4471be86af87ea8..2cd7e5c15f5ca5684db0745b2ab13834263e7ef7 100644
--- a/substrate/frame/aura/Cargo.toml
+++ b/substrate/frame/aura/Cargo.toml
@@ -26,7 +26,6 @@ frame-system = { version = "2.0.0", default-features = false, path = "../system"
 sp-timestamp = { version = "2.0.0", default-features = false, path = "../../primitives/timestamp" }
 pallet-timestamp = { version = "2.0.0", default-features = false, path = "../timestamp" }
 
-
 [dev-dependencies]
 sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" }
 sp-io ={ version = "2.0.0", path = "../../primitives/io" }
diff --git a/substrate/frame/aura/src/lib.rs b/substrate/frame/aura/src/lib.rs
index 65c6a4db9e5bc73ec66f53d8549458f03e07d87d..7e43f49c4dd7c76cbdca80a185cd12b930d75470 100644
--- a/substrate/frame/aura/src/lib.rs
+++ b/substrate/frame/aura/src/lib.rs
@@ -44,14 +44,9 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use pallet_timestamp;
-
 use sp_std::{result, prelude::*};
 use codec::{Encode, Decode};
-use frame_support::{
-	decl_storage, decl_module, Parameter, traits::{Get, FindAuthor},
-	ConsensusEngineId,
-};
+use frame_support::{Parameter, traits::{Get, FindAuthor}, ConsensusEngineId};
 use sp_runtime::{
 	RuntimeAppPublic,
 	traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem,
@@ -59,37 +54,67 @@ use sp_runtime::{
 use sp_timestamp::OnTimestampSet;
 use sp_inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError};
 use sp_consensus_aura::{
-	AURA_ENGINE_ID, ConsensusLog, AuthorityIndex,
+	AURA_ENGINE_ID, ConsensusLog, AuthorityIndex, Slot,
 	inherents::{INHERENT_IDENTIFIER, AuraInherentData},
 };
 
 mod mock;
 mod tests;
 
-pub trait Config: pallet_timestamp::Config {
-	/// The identifier type for an authority.
-	type AuthorityId: Member + Parameter + RuntimeAppPublic + Default;
-}
+pub use pallet::*;
 
-decl_storage! {
-	trait Store for Module<T: Config> as Aura {
-		/// The last timestamp.
-		LastTimestamp get(fn last): T::Moment;
+#[frame_support::pallet]
+pub mod pallet {
+	use super::*;
+	use frame_support::pallet_prelude::*;
+	use frame_system::pallet_prelude::*;
 
-		/// The current authorities
-		pub Authorities get(fn authorities): Vec<T::AuthorityId>;
+	#[pallet::config]
+	pub trait Config: pallet_timestamp::Config + frame_system::Config {
+		/// The identifier type for an authority.
+		type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + MaybeSerializeDeserialize;
 	}
-	add_extra_genesis {
-		config(authorities): Vec<T::AuthorityId>;
-		build(|config| Module::<T>::initialize_authorities(&config.authorities))
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(sp_std::marker::PhantomData<T>);
+
+	#[pallet::hooks]
+	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
+
+	#[pallet::call]
+	impl<T: Config> Pallet<T> {}
+
+	/// The current authority set.
+	#[pallet::storage]
+	#[pallet::getter(fn authorities)]
+	pub(super) type Authorities<T: Config> = StorageValue<_, Vec<T::AuthorityId>, ValueQuery>;
+
+	/// The last timestamp we have been notified of.
+	#[pallet::storage]
+	#[pallet::getter(fn last_timestamp)]
+	pub(super) type LastTimestamp<T: Config> = StorageValue<_, T::Moment, ValueQuery>;
+
+	#[pallet::genesis_config]
+	pub struct GenesisConfig<T: Config> {
+		pub authorities: Vec<T::AuthorityId>,
+	}
+
+	#[cfg(feature = "std")]
+	impl<T: Config> Default for GenesisConfig<T> {
+		fn default() -> Self {
+			Self { authorities: Vec::new() }
+		}
 	}
-}
 
-decl_module! {
-	pub struct Module<T: Config> for enum Call where origin: T::Origin { }
+	#[pallet::genesis_build]
+	impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
+		fn build(&self) {
+			Pallet::<T>::initialize_authorities(&self.authorities);
+		}
+	}
 }
 
-impl<T: Config> Module<T> {
+impl<T: Config> Pallet<T> {
 	fn change_authorities(new: Vec<T::AuthorityId>) {
 		<Authorities<T>>::put(&new);
 
@@ -106,13 +131,20 @@ impl<T: Config> Module<T> {
 			<Authorities<T>>::put(authorities);
 		}
 	}
+
+	/// Determine the Aura slot-duration based on the Timestamp module configuration.
+	pub fn slot_duration() -> T::Moment {
+		// we double the minimum block-period so each author can always propose within
+		// the majority of its slot.
+		<T as pallet_timestamp::Config>::MinimumPeriod::get().saturating_mul(2u32.into())
+	}
 }
 
-impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
+impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
 	type Public = T::AuthorityId;
 }
 
-impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
+impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Pallet<T> {
 	type Key = T::AuthorityId;
 
 	fn on_genesis_session<'a, I: 'a>(validators: I)
@@ -128,7 +160,7 @@ impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
 		// instant changes
 		if changed {
 			let next_authorities = validators.map(|(_, k)| k).collect::<Vec<_>>();
-			let last_authorities = <Module<T>>::authorities();
+			let last_authorities = Self::authorities();
 			if next_authorities != last_authorities {
 				Self::change_authorities(next_authorities);
 			}
@@ -145,16 +177,15 @@ impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
 	}
 }
 
-impl<T: Config> FindAuthor<u32> for Module<T> {
+impl<T: Config> FindAuthor<u32> for Pallet<T> {
 	fn find_author<'a, I>(digests: I) -> Option<u32> where
 		I: 'a + IntoIterator<Item=(ConsensusEngineId, &'a [u8])>
 	{
 		for (id, mut data) in digests.into_iter() {
 			if id == AURA_ENGINE_ID {
-				if let Ok(slot) = u64::decode(&mut data) {
-					let author_index = slot % Self::authorities().len() as u64;
-					return Some(author_index as u32)
-				}
+				let slot = Slot::decode(&mut data).ok()?;
+				let author_index = *slot % Self::authorities().len() as u64;
+				return Some(author_index as u32)
 			}
 		}
 
@@ -162,7 +193,7 @@ impl<T: Config> FindAuthor<u32> for Module<T> {
 	}
 }
 
-/// We can not implement `FindAuthor` twice, because the compiler does not know if 
+/// We can not implement `FindAuthor` twice, because the compiler does not know if
 /// `u32 == T::AuthorityId` and thus, prevents us to implement the trait twice.
 #[doc(hidden)]
 pub struct FindAccountFromAuthorIndex<T, Inner>(sp_std::marker::PhantomData<(T, Inner)>);
@@ -175,15 +206,15 @@ impl<T: Config, Inner: FindAuthor<u32>> FindAuthor<T::AuthorityId>
 	{
 		let i = Inner::find_author(digests)?;
 
-		let validators = <Module<T>>::authorities();
+		let validators = <Pallet<T>>::authorities();
 		validators.get(i as usize).map(|k| k.clone())
 	}
 }
 
 /// Find the authority ID of the Aura authority who authored the current block.
-pub type AuraAuthorId<T> = FindAccountFromAuthorIndex<T, Module<T>>;
+pub type AuraAuthorId<T> = FindAccountFromAuthorIndex<T, Pallet<T>>;
 
-impl<T: Config> IsMember<T::AuthorityId> for Module<T> {
+impl<T: Config> IsMember<T::AuthorityId> for Pallet<T> {
 	fn is_member(authority_id: &T::AuthorityId) -> bool {
 		Self::authorities()
 			.iter()
@@ -191,26 +222,20 @@ impl<T: Config> IsMember<T::AuthorityId> for Module<T> {
 	}
 }
 
-impl<T: Config> Module<T> {
-	/// Determine the Aura slot-duration based on the Timestamp module configuration.
-	pub fn slot_duration() -> T::Moment {
-		// we double the minimum block-period so each author can always propose within
-		// the majority of its slot.
-		<T as pallet_timestamp::Config>::MinimumPeriod::get().saturating_mul(2u32.into())
-	}
-
-	fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) {
-		let last = Self::last();
-		<Self as Store>::LastTimestamp::put(now);
+impl<T: Config> OnTimestampSet<T::Moment> for Pallet<T> {
+	fn on_timestamp_set(moment: T::Moment) {
+		let last = Self::last_timestamp();
+		LastTimestamp::<T>::put(moment);
 
 		if last.is_zero() {
 			return;
 		}
 
+		let slot_duration = Self::slot_duration();
 		assert!(!slot_duration.is_zero(), "Aura slot duration cannot be zero.");
 
 		let last_slot = last / slot_duration;
-		let cur_slot = now / slot_duration;
+		let cur_slot = moment / slot_duration;
 
 		assert!(last_slot < cur_slot, "Only one block may be authored per slot.");
 
@@ -218,13 +243,7 @@ impl<T: Config> Module<T> {
 	}
 }
 
-impl<T: Config> OnTimestampSet<T::Moment> for Module<T> {
-	fn on_timestamp_set(moment: T::Moment) {
-		Self::on_timestamp_set(moment, Self::slot_duration())
-	}
-}
-
-impl<T: Config> ProvideInherent for Module<T> {
+impl<T: Config> ProvideInherent for Pallet<T> {
 	type Call = pallet_timestamp::Call<T>;
 	type Error = MakeFatalError<sp_inherents::Error>;
 	const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
diff --git a/substrate/frame/aura/src/mock.rs b/substrate/frame/aura/src/mock.rs
index c7c439393de9b35c9360795496f09feb832eecc0..8eef18448d0c92e09fa34bdf8a8acc7f81284533 100644
--- a/substrate/frame/aura/src/mock.rs
+++ b/substrate/frame/aura/src/mock.rs
@@ -25,7 +25,7 @@ use sp_runtime::{
 	traits::IdentityLookup,
 	testing::{Header, UintAuthorityId},
 };
-use frame_support::parameter_types;
+use frame_support::{parameter_types, traits::GenesisBuild};
 use sp_io;
 use sp_core::H256;
 
diff --git a/substrate/frame/aura/src/tests.rs b/substrate/frame/aura/src/tests.rs
index b198308282c48bb61db564e79c1c6a65c5f65dae..00b792c300a583b1dc40b9174dbc33f8382fdc95 100644
--- a/substrate/frame/aura/src/tests.rs
+++ b/substrate/frame/aura/src/tests.rs
@@ -24,7 +24,7 @@ use crate::mock::{Aura, new_test_ext};
 #[test]
 fn initial_values() {
 	new_test_ext(vec![0, 1, 2, 3]).execute_with(|| {
-		assert_eq!(Aura::last(), 0u64);
+		assert_eq!(Aura::last_timestamp(), 0u64);
 		assert_eq!(Aura::authorities().len(), 4);
 	});
 }
diff --git a/substrate/primitives/consensus/aura/src/lib.rs b/substrate/primitives/consensus/aura/src/lib.rs
index 428a3c2f6f458c548edb8d8314f3ba8bfe94be03..95630fa7b5c6b61ece5efd53ae9701c893f85f79 100644
--- a/substrate/primitives/consensus/aura/src/lib.rs
+++ b/substrate/primitives/consensus/aura/src/lib.rs
@@ -61,6 +61,8 @@ pub mod ed25519 {
 	pub type AuthorityId = app_ed25519::Public;
 }
 
+pub use sp_consensus_slots::Slot;
+
 /// The `ConsensusEngineId` of AuRa.
 pub const AURA_ENGINE_ID: ConsensusEngineId = [b'a', b'u', b'r', b'a'];