diff --git a/auction/src/lib.rs b/auction/src/lib.rs
index b6c1604a112b3892ee02b90bef2e3512ce806b70..fd8e733d53b258ad42138fb467cd5d3311af558e 100644
--- a/auction/src/lib.rs
+++ b/auction/src/lib.rs
@@ -4,7 +4,7 @@ use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, P
 use frame_system::{self as system, ensure_signed};
 use orml_utilities::{LinkedItem, LinkedList};
 use sp_runtime::{
-	traits::{MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, Zero},
+	traits::{MaybeSerializeDeserialize, Member, One, SimpleArithmetic, Zero},
 	DispatchResult,
 };
 
@@ -38,7 +38,7 @@ type AuctionIdLinkedItem<T> = LinkedItem<<T as Trait>::AuctionId>;
 decl_storage! {
 	trait Store for Module<T: Trait> as Auction {
 		pub Auctions get(fn auctions): map T::AuctionId => Option<AuctionInfo<T::AccountId, T::Balance, T::BlockNumber>>;
-		pub AuctionsCount get(fn auctions_count): T::AuctionId;
+		pub AuctionsIndex get(fn auctions_index): T::AuctionId;
 		pub AuctionEndTime get(fn auction_end_time): map(T::BlockNumber, Option<T::AuctionId>) => Option<AuctionIdLinkedItem<T>>;
 	}
 }
@@ -105,14 +105,11 @@ decl_error! {
 impl<T: Trait> Module<T> {
 	fn _on_finalize(now: T::BlockNumber) {
 		let ended_auctions = <AuctionEndTimeList<T>>::take_all(&now);
-		let mut count = Self::auctions_count();
 		ended_auctions.for_each(|auction_id| {
 			if let Some(auction) = <Auctions<T>>::take(&auction_id) {
 				T::Handler::on_auction_ended(auction_id, auction.bid.clone());
-				count = count.saturating_sub(T::AuctionId::one());
 			}
 		});
-		<AuctionsCount<T>>::put(count);
 	}
 }
 
@@ -141,8 +138,8 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> {
 
 	fn new_auction(start: T::BlockNumber, end: Option<T::BlockNumber>) -> Self::AuctionId {
 		let auction = AuctionInfo { bid: None, start, end };
-		let auction_id = Self::auctions_count();
-		<AuctionsCount<T>>::mutate(|n| *n += Self::AuctionId::from(1));
+		let auction_id = Self::auctions_index();
+		<AuctionsIndex<T>>::mutate(|n| *n += Self::AuctionId::one());
 		<Auctions<T>>::insert(auction_id, auction);
 		if let Some(end_block) = end {
 			<AuctionEndTimeList<T>>::append(&end_block, auction_id);
@@ -150,4 +147,12 @@ impl<T: Trait> Auction<T::AccountId, T::BlockNumber> for Module<T> {
 
 		auction_id
 	}
+
+	fn remove_auction(id: Self::AuctionId) {
+		if let Some(auction) = <Auctions<T>>::take(&id) {
+			if let Some(end_block) = auction.end {
+				<AuctionEndTimeList<T>>::remove(&end_block, id);
+			}
+		}
+	}
 }
diff --git a/auction/src/tests.rs b/auction/src/tests.rs
index 79e4f583592464465e1d733a4c21e8ebb5ce9379..1792f0f78544d16aff712be442af209cca89abaf 100644
--- a/auction/src/tests.rs
+++ b/auction/src/tests.rs
@@ -71,18 +71,33 @@ fn bid_should_fail() {
 	});
 }
 
+#[test]
+fn remove_auction_should_work() {
+	ExtBuilder::default().build().execute_with(|| {
+		assert_eq!(AuctionModule::new_auction(10, Some(100)), 0);
+		assert_eq!(AuctionModule::auctions_index(), 1);
+		assert_eq!(AuctionModule::auctions(0).is_some(), true);
+		assert_eq!(AuctionModule::auction_end_time((100, Some(0))).is_some(), true);
+		AuctionModule::remove_auction(0);
+		assert_eq!(AuctionModule::auctions(0), None);
+		assert_eq!(AuctionModule::auction_end_time((100, Some(0))), None);
+	});
+}
+
 #[test]
 fn cleanup_auction_should_work() {
 	ExtBuilder::default().build().execute_with(|| {
 		assert_eq!(AuctionModule::new_auction(10, Some(100)), 0);
-		assert_eq!(AuctionModule::auctions_count(), 1);
+		assert_eq!(AuctionModule::auctions_index(), 1);
 		assert_eq!(AuctionModule::new_auction(10, Some(50)), 1);
-		assert_eq!(AuctionModule::auctions_count(), 2);
-		AuctionModule::on_finalize(1);
-		assert_eq!(AuctionModule::auctions_count(), 2);
+		assert_eq!(AuctionModule::auctions_index(), 2);
+		assert_eq!(AuctionModule::auctions(0).is_some(), true);
+		assert_eq!(AuctionModule::auctions(1).is_some(), true);
 		AuctionModule::on_finalize(50);
-		assert_eq!(AuctionModule::auctions_count(), 1);
+		assert_eq!(AuctionModule::auctions(0).is_some(), true);
+		assert_eq!(AuctionModule::auctions(1).is_some(), false);
 		AuctionModule::on_finalize(100);
-		assert_eq!(AuctionModule::auctions_count(), 0);
+		assert_eq!(AuctionModule::auctions(0).is_some(), false);
+		assert_eq!(AuctionModule::auctions(1).is_some(), false);
 	});
 }
diff --git a/traits/src/auction.rs b/traits/src/auction.rs
index 1805acdd231cff3e0db9ffddeefdcd5d49962cef..0878c01f85155d0c5ae7b91632ad0641a9263a4a 100644
--- a/traits/src/auction.rs
+++ b/traits/src/auction.rs
@@ -1,6 +1,9 @@
 use codec::FullCodec;
 use codec::{Decode, Encode};
-use rstd::fmt::Debug;
+use rstd::{
+	cmp::{Eq, PartialEq},
+	fmt::Debug,
+};
 use sp_runtime::{
 	traits::{MaybeSerializeDeserialize, SimpleArithmetic},
 	DispatchResult, RuntimeDebug,
@@ -21,7 +24,7 @@ pub struct AuctionInfo<AccountId, Balance, BlockNumber> {
 /// Abstraction over a simple auction system.
 pub trait Auction<AccountId, BlockNumber> {
 	/// The id of an AuctionInfo
-	type AuctionId: FullCodec + Default + Copy + MaybeSerializeDeserialize + Debug;
+	type AuctionId: FullCodec + Default + Copy + Eq + PartialEq + MaybeSerializeDeserialize + Debug;
 	/// The price to bid.
 	type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default;
 
@@ -31,6 +34,8 @@ pub trait Auction<AccountId, BlockNumber> {
 	fn update_auction(id: Self::AuctionId, info: AuctionInfo<AccountId, Self::Balance, BlockNumber>) -> DispatchResult;
 	/// Create new auction with specific startblock and endblock, return the id of the auction
 	fn new_auction(start: BlockNumber, end: Option<BlockNumber>) -> Self::AuctionId;
+	/// Remove auction by `id`
+	fn remove_auction(id: Self::AuctionId);
 }
 
 /// The result of bid handling.