diff --git a/Cargo.lock b/Cargo.lock
index c971ebcba9c68ea4677de19feef67accb3e73323..e8732f64efa07f63de43c4013a48744084b748a7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9827,6 +9827,7 @@ dependencies = [
  "sp-io",
  "sp-runtime",
  "sp-std 14.0.0",
+ "sp-tracing 16.0.0",
 ]
 
 [[package]]
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs
index 742dd50f6fa1f421d6ce4abf221e05f6902cc2ae..ec3a4f31202fd5f5333a1057bb06ca5dde247619 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs
@@ -232,5 +232,5 @@ impl pallet_broker::Config for Runtime {
 	type WeightInfo = weights::pallet_broker::WeightInfo<Runtime>;
 	type PalletId = BrokerPalletId;
 	type AdminOrigin = EnsureRoot<AccountId>;
-	type PriceAdapter = pallet_broker::Linear;
+	type PriceAdapter = pallet_broker::CenterTargetPrice<Balance>;
 }
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
index f43bb1c1e41b86391aee8fab8299095188dfc8b6..b78802790480a6f73e800b1b2b5197ce54732e13 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
@@ -112,6 +112,7 @@ pub type Migrations = (
 	cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
 	cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5<Runtime>,
 	pallet_broker::migration::MigrateV0ToV1<Runtime>,
+	pallet_broker::migration::MigrateV1ToV2<Runtime>,
 	// permanent
 	pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
 );
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs
index 89b1c4c86632ff0d19ee4fe1428978303ef92082..5c9175a18d98a0b6c0c791945dcd9f2cd1892cc4 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_broker::WeightInfo for WeightInfo<T> {
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::SaleInfo` (r:1 w:1)
 	/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:2)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:2)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	/// Storage: `System::Account` (r:1 w:0)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Workplan` (r:0 w:1)
@@ -337,8 +337,8 @@ impl<T: frame_system::Config> pallet_broker::WeightInfo for WeightInfo<T> {
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:1)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:1)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	fn drop_renewal() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `957`
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs
index 41cbc62fa2115ff3828e6910b750622a91ff0251..a5e219b9897e0710e008ffa6b800624710877bcc 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs
@@ -245,5 +245,5 @@ impl pallet_broker::Config for Runtime {
 	type WeightInfo = weights::pallet_broker::WeightInfo<Runtime>;
 	type PalletId = BrokerPalletId;
 	type AdminOrigin = EnsureRoot<AccountId>;
-	type PriceAdapter = pallet_broker::Linear;
+	type PriceAdapter = pallet_broker::CenterTargetPrice<Balance>;
 }
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
index ff2456dc1772ac68109ed49357c099cc5dd502a3..78b963e3b4057a2287fa12d40b52245a7b28ce95 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
@@ -111,6 +111,7 @@ pub type Migrations = (
 	pallet_collator_selection::migration::v2::MigrationToV2<Runtime>,
 	cumulus_pallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
 	pallet_broker::migration::MigrateV0ToV1<Runtime>,
+	pallet_broker::migration::MigrateV1ToV2<Runtime>,
 	// permanent
 	pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>,
 );
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs
index 13d5fcf3898bcc07fce13c7ee2deeb8c2b9fa76f..7e1c832a90924e39c7bc7d7b24d8163ce5d65589 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs
@@ -152,8 +152,8 @@ impl<T: frame_system::Config> pallet_broker::WeightInfo for WeightInfo<T> {
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::SaleInfo` (r:1 w:1)
 	/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:2)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:2)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	/// Storage: `System::Account` (r:1 w:0)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Workplan` (r:0 w:1)
@@ -335,8 +335,8 @@ impl<T: frame_system::Config> pallet_broker::WeightInfo for WeightInfo<T> {
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:1)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:1)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	fn drop_renewal() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `556`
diff --git a/prdoc/pr_4521.prdoc b/prdoc/pr_4521.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..a8b42a2c7ee3fd5f4beca6c2aede7a4a82a8a1b1
--- /dev/null
+++ b/prdoc/pr_4521.prdoc
@@ -0,0 +1,28 @@
+title: AdaptPrice trait is now price controlled
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      The broker pallet price adaptation interface is changed to be less opinionated and more
+      information is made available to the `AdaptPrice` trait. A new example impl is included which
+      adapts the price based not on the number of cores sold, but rather on the price that was
+      achieved during the sale to mitigate a potential price manipulation vector. More information
+      here:
+
+        https://github.com/paritytech/polkadot-sdk/issues/4360
+
+  - audience: Runtime User
+    description: |
+      The price controller of the Rococo and Westend Coretime chain will be
+      adjusted with this release. This will very likely be used in the
+      fellowship production runtime to have a much larger leadin. This fixes a
+      price manipulation issue we discovered with the Kusama launch.
+
+crates:
+  - name: pallet-broker
+    bump: minor
+  - name: coretime-rococo-runtime
+    bump: minor
+  - name: coretime-westend-runtime
+    bump: minor
+
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 7d9128bb940a55bfc2b0497600c1f6f5ffa56119..801abc28d3dda88932e3aa6f4ae0da2a2956ff00 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -2145,7 +2145,7 @@ impl pallet_broker::Config for Runtime {
 	type WeightInfo = ();
 	type PalletId = BrokerPalletId;
 	type AdminOrigin = EnsureRoot<AccountId>;
-	type PriceAdapter = pallet_broker::Linear;
+	type PriceAdapter = pallet_broker::CenterTargetPrice<Balance>;
 }
 
 parameter_types! {
diff --git a/substrate/frame/broker/Cargo.toml b/substrate/frame/broker/Cargo.toml
index 8f3f30ec58ebc2ff868cee03037939d0e9aac884..8a84fbfdfb701c87cde1dfb935ad1dcb6cf56e04 100644
--- a/substrate/frame/broker/Cargo.toml
+++ b/substrate/frame/broker/Cargo.toml
@@ -30,6 +30,7 @@ frame-system = { path = "../system", default-features = false }
 
 [dev-dependencies]
 sp-io = { path = "../../primitives/io" }
+sp-tracing = { path = "../../primitives/tracing" }
 pretty_assertions = "1.3.0"
 
 [features]
diff --git a/substrate/frame/broker/src/adapt_price.rs b/substrate/frame/broker/src/adapt_price.rs
index fbcd7afdf0da059fb7023de3422f15b2344d5407..9b2e1dd8997bd68adfe8aef71bdad74f8c0ff529 100644
--- a/substrate/frame/broker/src/adapt_price.rs
+++ b/substrate/frame/broker/src/adapt_price.rs
@@ -17,59 +17,122 @@
 
 #![deny(missing_docs)]
 
-use crate::CoreIndex;
+use crate::{CoreIndex, SaleInfoRecord};
 use sp_arithmetic::{traits::One, FixedU64};
-use sp_runtime::Saturating;
+use sp_runtime::{FixedPointNumber, FixedPointOperand, Saturating};
+
+/// Performance of a past sale.
+#[derive(Copy, Clone)]
+pub struct SalePerformance<Balance> {
+	/// The price at which the last core was sold.
+	///
+	/// Will be `None` if no cores have been offered.
+	pub sellout_price: Option<Balance>,
+
+	/// The minimum price that was achieved in this sale.
+	pub end_price: Balance,
+
+	/// The number of cores we want to sell, ideally.
+	pub ideal_cores_sold: CoreIndex,
+
+	/// Number of cores which are/have been offered for sale.
+	pub cores_offered: CoreIndex,
+
+	/// Number of cores which have been sold; never more than cores_offered.
+	pub cores_sold: CoreIndex,
+}
+
+/// Result of `AdaptPrice::adapt_price`.
+#[derive(Copy, Clone)]
+pub struct AdaptedPrices<Balance> {
+	/// New minimum price to use.
+	pub end_price: Balance,
+
+	/// Price the controller is optimizing for.
+	///
+	/// This is the price "expected" by the controller based on the previous sale. We assume that
+	/// sales in this period will be around this price, assuming stable market conditions.
+	///
+	/// Think of it as the expected market price. This can be used for determining what to charge
+	/// for renewals, that don't yet have any price information for example. E.g. for expired
+	/// legacy leases.
+	pub target_price: Balance,
+}
+
+impl<Balance: Copy> SalePerformance<Balance> {
+	/// Construct performance via data from a `SaleInfoRecord`.
+	pub fn from_sale<BlockNumber>(record: &SaleInfoRecord<Balance, BlockNumber>) -> Self {
+		Self {
+			sellout_price: record.sellout_price,
+			end_price: record.end_price,
+			ideal_cores_sold: record.ideal_cores_sold,
+			cores_offered: record.cores_offered,
+			cores_sold: record.cores_sold,
+		}
+	}
+
+	#[cfg(test)]
+	fn new(sellout_price: Option<Balance>, end_price: Balance) -> Self {
+		Self { sellout_price, end_price, ideal_cores_sold: 0, cores_offered: 0, cores_sold: 0 }
+	}
+}
 
 /// Type for determining how to set price.
-pub trait AdaptPrice {
+pub trait AdaptPrice<Balance> {
 	/// Return the factor by which the regular price must be multiplied during the leadin period.
 	///
 	/// - `when`: The amount through the leadin period; between zero and one.
 	fn leadin_factor_at(when: FixedU64) -> FixedU64;
-	/// Return the correction factor by which the regular price must be multiplied based on market
-	/// performance.
+
+	/// Return adapted prices for next sale.
 	///
-	/// - `sold`: The number of cores sold.
-	/// - `target`: The target number of cores to be sold (must be larger than zero).
-	/// - `limit`: The maximum number of cores to be sold.
-	fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64;
+	/// Based on the previous sale's performance.
+	fn adapt_price(performance: SalePerformance<Balance>) -> AdaptedPrices<Balance>;
 }
 
-impl AdaptPrice for () {
+impl<Balance: Copy> AdaptPrice<Balance> for () {
 	fn leadin_factor_at(_: FixedU64) -> FixedU64 {
 		FixedU64::one()
 	}
-	fn adapt_price(_: CoreIndex, _: CoreIndex, _: CoreIndex) -> FixedU64 {
-		FixedU64::one()
+	fn adapt_price(performance: SalePerformance<Balance>) -> AdaptedPrices<Balance> {
+		let price = performance.sellout_price.unwrap_or(performance.end_price);
+		AdaptedPrices { end_price: price, target_price: price }
 	}
 }
 
-/// Simple implementation of `AdaptPrice` giving a monotonic leadin and a linear price change based
-/// on cores sold.
-pub struct Linear;
-impl AdaptPrice for Linear {
+/// Simple implementation of `AdaptPrice` with two linear phases.
+///
+/// One steep one downwards to the target price, which is 1/10 of the maximum price and a more flat
+/// one down to the minimum price, which is 1/100 of the maximum price.
+pub struct CenterTargetPrice<Balance>(core::marker::PhantomData<Balance>);
+
+impl<Balance: FixedPointOperand> AdaptPrice<Balance> for CenterTargetPrice<Balance> {
 	fn leadin_factor_at(when: FixedU64) -> FixedU64 {
-		FixedU64::from(2).saturating_sub(when)
-	}
-	fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64 {
-		if sold <= target {
-			// Range of [0.5, 1.0].
-			FixedU64::from_rational(1, 2).saturating_add(FixedU64::from_rational(
-				sold.into(),
-				target.saturating_mul(2).into(),
-			))
+		if when <= FixedU64::from_rational(1, 2) {
+			FixedU64::from(100).saturating_sub(when.saturating_mul(180.into()))
 		} else {
-			// Range of (1.0, 2].
-
-			// Unchecked math: In this branch we know that sold > target. The limit must be >= sold
-			// by construction, and thus target must be < limit.
-			FixedU64::one().saturating_add(FixedU64::from_rational(
-				(sold - target).into(),
-				(limit - target).into(),
-			))
+			FixedU64::from(19).saturating_sub(when.saturating_mul(18.into()))
 		}
 	}
+
+	fn adapt_price(performance: SalePerformance<Balance>) -> AdaptedPrices<Balance> {
+		let Some(sellout_price) = performance.sellout_price else {
+			return AdaptedPrices {
+				end_price: performance.end_price,
+				target_price: FixedU64::from(10).saturating_mul_int(performance.end_price),
+			}
+		};
+
+		let price = FixedU64::from_rational(1, 10).saturating_mul_int(sellout_price);
+		let price = if price == Balance::zero() {
+			// We could not recover from a price equal 0 ever.
+			sellout_price
+		} else {
+			price
+		};
+
+		AdaptedPrices { end_price: price, target_price: sellout_price }
+	}
 }
 
 #[cfg(test)]
@@ -78,37 +141,103 @@ mod tests {
 
 	#[test]
 	fn linear_no_panic() {
-		for limit in 0..10 {
-			for target in 1..10 {
-				for sold in 0..=limit {
-					let price = Linear::adapt_price(sold, target, limit);
-
-					if sold > target {
-						assert!(price > FixedU64::one());
-					} else {
-						assert!(price <= FixedU64::one());
-					}
-				}
+		for sellout in 0..11 {
+			for price in 0..10 {
+				let sellout_price = if sellout == 11 { None } else { Some(sellout) };
+				CenterTargetPrice::adapt_price(SalePerformance::new(sellout_price, price));
 			}
 		}
 	}
 
 	#[test]
-	fn linear_bound_check() {
-		// Using constraints from pallet implementation i.e. `limit >= sold`.
-		// Check extremes
-		let limit = 10;
-		let target = 5;
-
-		// Maximally sold: `sold == limit`
-		assert_eq!(Linear::adapt_price(limit, target, limit), FixedU64::from_float(2.0));
-		// Ideally sold: `sold == target`
-		assert_eq!(Linear::adapt_price(target, target, limit), FixedU64::one());
-		// Minimally sold: `sold == 0`
-		assert_eq!(Linear::adapt_price(0, target, limit), FixedU64::from_float(0.5));
-		// Optimistic target: `target == limit`
-		assert_eq!(Linear::adapt_price(limit, limit, limit), FixedU64::one());
-		// Pessimistic target: `target == 0`
-		assert_eq!(Linear::adapt_price(limit, 0, limit), FixedU64::from_float(2.0));
+	fn leadin_price_bound_check() {
+		assert_eq!(
+			CenterTargetPrice::<u64>::leadin_factor_at(FixedU64::from(0)),
+			FixedU64::from(100)
+		);
+		assert_eq!(
+			CenterTargetPrice::<u64>::leadin_factor_at(FixedU64::from_rational(1, 4)),
+			FixedU64::from(55)
+		);
+
+		assert_eq!(
+			CenterTargetPrice::<u64>::leadin_factor_at(FixedU64::from_float(0.5)),
+			FixedU64::from(10)
+		);
+
+		assert_eq!(
+			CenterTargetPrice::<u64>::leadin_factor_at(FixedU64::from_rational(3, 4)),
+			FixedU64::from_float(5.5)
+		);
+		assert_eq!(CenterTargetPrice::<u64>::leadin_factor_at(FixedU64::one()), FixedU64::one());
+	}
+
+	#[test]
+	fn no_op_sale_is_good() {
+		let prices = CenterTargetPrice::adapt_price(SalePerformance::new(None, 1));
+		assert_eq!(prices.target_price, 10);
+		assert_eq!(prices.end_price, 1);
+	}
+
+	#[test]
+	fn price_stays_stable_on_optimal_sale() {
+		// Check price stays stable if sold at the optimal price:
+		let mut performance = SalePerformance::new(Some(1000), 100);
+		for _ in 0..10 {
+			let prices = CenterTargetPrice::adapt_price(performance);
+			performance.sellout_price = Some(1000);
+			performance.end_price = prices.end_price;
+
+			assert!(prices.end_price <= 101);
+			assert!(prices.end_price >= 99);
+			assert!(prices.target_price <= 1001);
+			assert!(prices.target_price >= 999);
+		}
+	}
+
+	#[test]
+	fn price_adjusts_correctly_upwards() {
+		let performance = SalePerformance::new(Some(10_000), 100);
+		let prices = CenterTargetPrice::adapt_price(performance);
+		assert_eq!(prices.target_price, 10_000);
+		assert_eq!(prices.end_price, 1000);
+	}
+
+	#[test]
+	fn price_adjusts_correctly_downwards() {
+		let performance = SalePerformance::new(Some(100), 100);
+		let prices = CenterTargetPrice::adapt_price(performance);
+		assert_eq!(prices.target_price, 100);
+		assert_eq!(prices.end_price, 10);
+	}
+
+	#[test]
+	fn price_never_goes_to_zero_and_recovers() {
+		// Check price stays stable if sold at the optimal price:
+		let sellout_price = 1;
+		let mut performance = SalePerformance::new(Some(sellout_price), 1);
+		for _ in 0..11 {
+			let prices = CenterTargetPrice::adapt_price(performance);
+			performance.sellout_price = Some(sellout_price);
+			performance.end_price = prices.end_price;
+
+			assert!(prices.end_price <= sellout_price);
+			assert!(prices.end_price > 0);
+		}
+	}
+
+	#[test]
+	fn renewal_price_is_correct_on_no_sale() {
+		let performance = SalePerformance::new(None, 100);
+		let prices = CenterTargetPrice::adapt_price(performance);
+		assert_eq!(prices.target_price, 1000);
+		assert_eq!(prices.end_price, 100);
+	}
+
+	#[test]
+	fn renewal_price_is_sell_out() {
+		let performance = SalePerformance::new(Some(1000), 100);
+		let prices = CenterTargetPrice::adapt_price(performance);
+		assert_eq!(prices.target_price, 1000);
 	}
 }
diff --git a/substrate/frame/broker/src/benchmarking.rs b/substrate/frame/broker/src/benchmarking.rs
index 7533e3dc68c41fa54d39b7bb234ecaafe4e56fab..9cb5ad096c83b74e50a77993c2c3e0049ec2c876 100644
--- a/substrate/frame/broker/src/benchmarking.rs
+++ b/substrate/frame/broker/src/benchmarking.rs
@@ -214,8 +214,8 @@ mod benches {
 			Event::SaleInitialized {
 				sale_start: 2u32.into(),
 				leadin_length: 1u32.into(),
-				start_price: 20u32.into(),
-				regular_price: 10u32.into(),
+				start_price: 1000u32.into(),
+				end_price: 10u32.into(),
 				region_begin: latest_region_begin + config.region_length,
 				region_end: latest_region_begin + config.region_length * 2,
 				ideal_cores_sold: 0,
@@ -288,8 +288,8 @@ mod benches {
 		#[extrinsic_call]
 		_(RawOrigin::Signed(caller), region.core);
 
-		let id = AllowedRenewalId { core: region.core, when: region.begin + region_len * 2 };
-		assert!(AllowedRenewals::<T>::get(id).is_some());
+		let id = PotentialRenewalId { core: region.core, when: region.begin + region_len * 2 };
+		assert!(PotentialRenewals::<T>::get(id).is_some());
 
 		Ok(())
 	}
@@ -670,20 +670,20 @@ mod benches {
 			(T::TimeslicePeriod::get() * (region_len * 3).into()).try_into().ok().unwrap(),
 		);
 
-		let id = AllowedRenewalId { core, when };
-		let record = AllowedRenewalRecord {
+		let id = PotentialRenewalId { core, when };
+		let record = PotentialRenewalRecord {
 			price: 1u32.into(),
 			completion: CompletionStatus::Complete(new_schedule()),
 		};
-		AllowedRenewals::<T>::insert(id, record);
+		PotentialRenewals::<T>::insert(id, record);
 
 		let caller: T::AccountId = whitelisted_caller();
 
 		#[extrinsic_call]
 		_(RawOrigin::Signed(caller), core, when);
 
-		assert!(AllowedRenewals::<T>::get(id).is_none());
-		assert_last_event::<T>(Event::AllowedRenewalDropped { core, when }.into());
+		assert!(PotentialRenewals::<T>::get(id).is_none());
+		assert_last_event::<T>(Event::PotentialRenewalDropped { core, when }.into());
 
 		Ok(())
 	}
@@ -776,12 +776,12 @@ mod benches {
 		let config = new_config_record::<T>();
 
 		let now = frame_system::Pallet::<T>::block_number();
-		let price = 10u32.into();
+		let end_price = 10u32.into();
 		let commit_timeslice = Broker::<T>::latest_timeslice_ready_to_commit(&config);
 		let sale = SaleInfoRecordOf::<T> {
 			sale_start: now,
 			leadin_length: Zero::zero(),
-			price,
+			end_price,
 			sellout_price: None,
 			region_begin: commit_timeslice,
 			region_end: commit_timeslice.saturating_add(config.region_length),
@@ -815,8 +815,8 @@ mod benches {
 			Event::SaleInitialized {
 				sale_start: 2u32.into(),
 				leadin_length: 1u32.into(),
-				start_price: 20u32.into(),
-				regular_price: 10u32.into(),
+				start_price: 1000u32.into(),
+				end_price: 10u32.into(),
 				region_begin: sale.region_begin + config.region_length,
 				region_end: sale.region_end + config.region_length,
 				ideal_cores_sold: 0,
diff --git a/substrate/frame/broker/src/dispatchable_impls.rs b/substrate/frame/broker/src/dispatchable_impls.rs
index 45a0a514c307adaeb8be65f514e6c46251210d06..79c1a1f79796330a7377f06ef5f1a62045eb2848 100644
--- a/substrate/frame/broker/src/dispatchable_impls.rs
+++ b/substrate/frame/broker/src/dispatchable_impls.rs
@@ -70,7 +70,10 @@ impl<T: Config> Pallet<T> {
 		Ok(())
 	}
 
-	pub(crate) fn do_start_sales(price: BalanceOf<T>, extra_cores: CoreIndex) -> DispatchResult {
+	pub(crate) fn do_start_sales(
+		end_price: BalanceOf<T>,
+		extra_cores: CoreIndex,
+	) -> DispatchResult {
 		let config = Configuration::<T>::get().ok_or(Error::<T>::Uninitialized)?;
 
 		// Determine the core count
@@ -93,7 +96,7 @@ impl<T: Config> Pallet<T> {
 		let old_sale = SaleInfoRecord {
 			sale_start: now,
 			leadin_length: Zero::zero(),
-			price,
+			end_price,
 			sellout_price: None,
 			region_begin: commit_timeslice,
 			region_end: commit_timeslice.saturating_add(config.region_length),
@@ -102,7 +105,7 @@ impl<T: Config> Pallet<T> {
 			cores_offered: 0,
 			cores_sold: 0,
 		};
-		Self::deposit_event(Event::<T>::SalesStarted { price, core_count });
+		Self::deposit_event(Event::<T>::SalesStarted { price: end_price, core_count });
 		Self::rotate_sale(old_sale, &config, &status);
 		Status::<T>::put(&status);
 		Ok(())
@@ -121,12 +124,8 @@ impl<T: Config> Pallet<T> {
 		let price = Self::sale_price(&sale, now);
 		ensure!(price_limit >= price, Error::<T>::Overpriced);
 
-		Self::charge(&who, price)?;
-		let core = sale.first_core.saturating_add(sale.cores_sold);
-		sale.cores_sold.saturating_inc();
-		if sale.cores_sold <= sale.ideal_cores_sold || sale.sellout_price.is_none() {
-			sale.sellout_price = Some(price);
-		}
+		let core = Self::purchase_core(&who, price, &mut sale)?;
+
 		SaleInfo::<T>::put(&sale);
 		let id =
 			Self::issue(core, sale.region_begin, sale.region_end, Some(who.clone()), Some(price));
@@ -135,7 +134,7 @@ impl<T: Config> Pallet<T> {
 		Ok(id)
 	}
 
-	/// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the
+	/// Must be called on a core in `PotentialRenewals` whose value is a timeslice equal to the
 	/// current sale status's `region_end`.
 	pub(crate) fn do_renew(who: T::AccountId, core: CoreIndex) -> Result<CoreIndex, DispatchError> {
 		let config = Configuration::<T>::get().ok_or(Error::<T>::Uninitialized)?;
@@ -143,14 +142,15 @@ impl<T: Config> Pallet<T> {
 		let mut sale = SaleInfo::<T>::get().ok_or(Error::<T>::NoSales)?;
 		Self::ensure_cores_for_sale(&status, &sale)?;
 
-		let renewal_id = AllowedRenewalId { core, when: sale.region_begin };
-		let record = AllowedRenewals::<T>::get(renewal_id).ok_or(Error::<T>::NotAllowed)?;
+		let renewal_id = PotentialRenewalId { core, when: sale.region_begin };
+		let record = PotentialRenewals::<T>::get(renewal_id).ok_or(Error::<T>::NotAllowed)?;
 		let workload =
 			record.completion.drain_complete().ok_or(Error::<T>::IncompleteAssignment)?;
 
 		let old_core = core;
-		let core = sale.first_core.saturating_add(sale.cores_sold);
-		Self::charge(&who, record.price)?;
+
+		let core = Self::purchase_core(&who, record.price, &mut sale)?;
+
 		Self::deposit_event(Event::Renewed {
 			who,
 			old_core,
@@ -161,19 +161,24 @@ impl<T: Config> Pallet<T> {
 			workload: workload.clone(),
 		});
 
-		sale.cores_sold.saturating_inc();
-
 		Workplan::<T>::insert((sale.region_begin, core), &workload);
 
 		let begin = sale.region_end;
 		let price_cap = record.price + config.renewal_bump * record.price;
 		let now = frame_system::Pallet::<T>::block_number();
 		let price = Self::sale_price(&sale, now).min(price_cap);
-		let new_record = AllowedRenewalRecord { price, completion: Complete(workload) };
-		AllowedRenewals::<T>::remove(renewal_id);
-		AllowedRenewals::<T>::insert(AllowedRenewalId { core, when: begin }, &new_record);
+		log::debug!(
+			"Renew with: sale price: {:?}, price cap: {:?}, old price: {:?}",
+			price,
+			price_cap,
+			record.price
+		);
+		let new_record = PotentialRenewalRecord { price, completion: Complete(workload) };
+		PotentialRenewals::<T>::remove(renewal_id);
+		PotentialRenewals::<T>::insert(PotentialRenewalId { core, when: begin }, &new_record);
 		SaleInfo::<T>::put(&sale);
 		if let Some(workload) = new_record.completion.drain_complete() {
+			log::debug!("Recording renewable price for next run: {:?}", price);
 			Self::deposit_event(Event::Renewable { core, price, begin, workload });
 		}
 		Ok(core)
@@ -281,17 +286,19 @@ impl<T: Config> Pallet<T> {
 			let duration = region.end.saturating_sub(region_id.begin);
 			if duration == config.region_length && finality == Finality::Final {
 				if let Some(price) = region.paid {
-					let renewal_id = AllowedRenewalId { core: region_id.core, when: region.end };
-					let assigned = match AllowedRenewals::<T>::get(renewal_id) {
-						Some(AllowedRenewalRecord { completion: Partial(w), price: p })
+					let renewal_id = PotentialRenewalId { core: region_id.core, when: region.end };
+					let assigned = match PotentialRenewals::<T>::get(renewal_id) {
+						Some(PotentialRenewalRecord { completion: Partial(w), price: p })
 							if price == p =>
 							w,
 						_ => CoreMask::void(),
 					} | region_id.mask;
 					let workload =
 						if assigned.is_complete() { Complete(workplan) } else { Partial(assigned) };
-					let record = AllowedRenewalRecord { price, completion: workload };
-					AllowedRenewals::<T>::insert(&renewal_id, &record);
+					let record = PotentialRenewalRecord { price, completion: workload };
+					// Note: This entry alone does not yet actually allow renewals (the completion
+					// status has to be complete for `do_renew` to accept it).
+					PotentialRenewals::<T>::insert(&renewal_id, &record);
 					if let Some(workload) = record.completion.drain_complete() {
 						Self::deposit_event(Event::Renewable {
 							core: region_id.core,
@@ -444,10 +451,10 @@ impl<T: Config> Pallet<T> {
 	pub(crate) fn do_drop_renewal(core: CoreIndex, when: Timeslice) -> DispatchResult {
 		let status = Status::<T>::get().ok_or(Error::<T>::Uninitialized)?;
 		ensure!(status.last_committed_timeslice >= when, Error::<T>::StillValid);
-		let id = AllowedRenewalId { core, when };
-		ensure!(AllowedRenewals::<T>::contains_key(id), Error::<T>::UnknownRenewal);
-		AllowedRenewals::<T>::remove(id);
-		Self::deposit_event(Event::AllowedRenewalDropped { core, when });
+		let id = PotentialRenewalId { core, when };
+		ensure!(PotentialRenewals::<T>::contains_key(id), Error::<T>::UnknownRenewal);
+		PotentialRenewals::<T>::remove(id);
+		Self::deposit_event(Event::PotentialRenewalDropped { core, when });
 		Ok(())
 	}
 
diff --git a/substrate/frame/broker/src/lib.rs b/substrate/frame/broker/src/lib.rs
index d59c4c9c6b24e4e576580715378a32b48f61eb91..0774c02e1cf10e7360c89dfc6c1dc11f28b563ac 100644
--- a/substrate/frame/broker/src/lib.rs
+++ b/substrate/frame/broker/src/lib.rs
@@ -65,7 +65,7 @@ pub mod pallet {
 	use sp_runtime::traits::{Convert, ConvertBack};
 	use sp_std::vec::Vec;
 
-	const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+	const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
 
 	#[pallet::pallet]
 	#[pallet::storage_version(STORAGE_VERSION)]
@@ -92,7 +92,7 @@ pub mod pallet {
 		type Coretime: CoretimeInterface;
 
 		/// The algorithm to determine the next price on the basis of market performance.
-		type PriceAdapter: AdaptPrice;
+		type PriceAdapter: AdaptPrice<BalanceOf<Self>>;
 
 		/// Reversible conversion from local balance to Relay-chain balance. This will typically be
 		/// the `Identity`, but provided just in case the chains use different representations.
@@ -136,10 +136,12 @@ pub mod pallet {
 	#[pallet::storage]
 	pub type SaleInfo<T> = StorageValue<_, SaleInfoRecordOf<T>, OptionQuery>;
 
-	/// Records of allowed renewals.
+	/// Records of potential renewals.
+	///
+	/// Renewals will only actually be allowed if `CompletionStatus` is actually `Complete`.
 	#[pallet::storage]
-	pub type AllowedRenewals<T> =
-		StorageMap<_, Twox64Concat, AllowedRenewalId, AllowedRenewalRecordOf<T>, OptionQuery>;
+	pub type PotentialRenewals<T> =
+		StorageMap<_, Twox64Concat, PotentialRenewalId, PotentialRenewalRecordOf<T>, OptionQuery>;
 
 	/// The current (unassigned or provisionally assigend) Regions.
 	#[pallet::storage]
@@ -290,14 +292,13 @@ pub mod pallet {
 			/// The price of Bulk Coretime at the beginning of the Leadin Period.
 			start_price: BalanceOf<T>,
 			/// The price of Bulk Coretime after the Leadin Period.
-			regular_price: BalanceOf<T>,
+			end_price: BalanceOf<T>,
 			/// The first timeslice of the Regions which are being sold in this sale.
 			region_begin: Timeslice,
 			/// The timeslice on which the Regions which are being sold in the sale terminate.
 			/// (i.e. One after the last timeslice which the Regions control.)
 			region_end: Timeslice,
-			/// The number of cores we want to sell, ideally. Selling this amount would result in
-			/// no change to the price for the next sale.
+			/// The number of cores we want to sell, ideally.
 			ideal_cores_sold: CoreIndex,
 			/// Number of cores which are/have been offered for sale.
 			cores_offered: CoreIndex,
@@ -413,7 +414,7 @@ pub mod pallet {
 			assignment: Vec<(CoreAssignment, PartsOf57600)>,
 		},
 		/// Some historical Instantaneous Core Pool payment record has been dropped.
-		AllowedRenewalDropped {
+		PotentialRenewalDropped {
 			/// The timeslice whose renewal is no longer available.
 			when: Timeslice,
 			/// The core whose workload is no longer available to be renewed for `when`.
@@ -558,7 +559,7 @@ pub mod pallet {
 		/// Begin the Bulk Coretime sales rotation.
 		///
 		/// - `origin`: Must be Root or pass `AdminOrigin`.
-		/// - `initial_price`: The price of Bulk Coretime in the first sale.
+		/// - `end_price`: The price after the leadin period of Bulk Coretime in the first sale.
 		/// - `extra_cores`: Number of extra cores that should be requested on top of the cores
 		///   required for `Reservations` and `Leases`.
 		///
@@ -570,11 +571,11 @@ pub mod pallet {
 		))]
 		pub fn start_sales(
 			origin: OriginFor<T>,
-			initial_price: BalanceOf<T>,
+			end_price: BalanceOf<T>,
 			extra_cores: CoreIndex,
 		) -> DispatchResultWithPostInfo {
 			T::AdminOrigin::ensure_origin_or_root(origin)?;
-			Self::do_start_sales(initial_price, extra_cores)?;
+			Self::do_start_sales(end_price, extra_cores)?;
 			Ok(Pays::No.into())
 		}
 
diff --git a/substrate/frame/broker/src/migration.rs b/substrate/frame/broker/src/migration.rs
index 95aa28250a628e8352f6e4852a5588cbdad2a5e8..f354e447fe84eba4df56d02e82c69519ba67cf7d 100644
--- a/substrate/frame/broker/src/migration.rs
+++ b/substrate/frame/broker/src/migration.rs
@@ -77,6 +77,57 @@ mod v1 {
 	}
 }
 
+mod v2 {
+	use super::*;
+	use frame_support::{
+		pallet_prelude::{OptionQuery, Twox64Concat},
+		storage_alias,
+	};
+
+	#[storage_alias]
+	pub type AllowedRenewals<T: Config> = StorageMap<
+		Pallet<T>,
+		Twox64Concat,
+		PotentialRenewalId,
+		PotentialRenewalRecordOf<T>,
+		OptionQuery,
+	>;
+
+	pub struct MigrateToV2Impl<T>(PhantomData<T>);
+
+	impl<T: Config> UncheckedOnRuntimeUpgrade for MigrateToV2Impl<T> {
+		fn on_runtime_upgrade() -> frame_support::weights::Weight {
+			let mut count = 0;
+			for (renewal_id, renewal) in AllowedRenewals::<T>::drain() {
+				PotentialRenewals::<T>::insert(renewal_id, renewal);
+				count += 1;
+			}
+
+			log::info!(
+				target: LOG_TARGET,
+				"Storage migration v2 for pallet-broker finished.",
+			);
+
+			// calculate and return migration weights
+			T::DbWeight::get().reads_writes(count as u64 + 1, count as u64 + 1)
+		}
+
+		#[cfg(feature = "try-runtime")]
+		fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
+			Ok((AllowedRenewals::<T>::iter_keys().count() as u32).encode())
+		}
+
+		#[cfg(feature = "try-runtime")]
+		fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
+			let old_count = u32::decode(&mut &state[..]).expect("Known good");
+			let new_count = PotentialRenewals::<T>::iter_values().count() as u32;
+
+			ensure!(old_count == new_count, "Renewal count should not change");
+			Ok(())
+		}
+	}
+}
+
 /// Migrate the pallet storage from `0` to `1`.
 pub type MigrateV0ToV1<T> = frame_support::migrations::VersionedMigration<
 	0,
@@ -85,3 +136,11 @@ pub type MigrateV0ToV1<T> = frame_support::migrations::VersionedMigration<
 	Pallet<T>,
 	<T as frame_system::Config>::DbWeight,
 >;
+
+pub type MigrateV1ToV2<T> = frame_support::migrations::VersionedMigration<
+	1,
+	2,
+	v2::MigrateToV2Impl<T>,
+	Pallet<T>,
+	<T as frame_system::Config>::DbWeight,
+>;
diff --git a/substrate/frame/broker/src/mock.rs b/substrate/frame/broker/src/mock.rs
index 6219b4eff1b457294c9f3656e4be145c3639e2e0..6fff6aa10080c5a888ba35b4c3aeb1d180f9361b 100644
--- a/substrate/frame/broker/src/mock.rs
+++ b/substrate/frame/broker/src/mock.rs
@@ -199,7 +199,7 @@ impl crate::Config for Test {
 	type WeightInfo = ();
 	type PalletId = TestBrokerId;
 	type AdminOrigin = EnsureOneOrRoot;
-	type PriceAdapter = Linear;
+	type PriceAdapter = CenterTargetPrice<BalanceOf<Self>>;
 }
 
 pub fn advance_to(b: u64) {
@@ -255,6 +255,10 @@ impl TestExt {
 		Self(new_config())
 	}
 
+	pub fn new_with_config(config: ConfigRecordOf<Test>) -> Self {
+		Self(config)
+	}
+
 	pub fn advance_notice(mut self, advance_notice: Timeslice) -> Self {
 		self.0.advance_notice = advance_notice as u64;
 		self
diff --git a/substrate/frame/broker/src/tests.rs b/substrate/frame/broker/src/tests.rs
index f929f0d50dcfaf3d8e7e77d07e260d54c75b1a27..e953afd6dc3c8818338d810d0c9d9d37c0b742af 100644
--- a/substrate/frame/broker/src/tests.rs
+++ b/substrate/frame/broker/src/tests.rs
@@ -25,7 +25,7 @@ use frame_support::{
 };
 use frame_system::RawOrigin::Root;
 use pretty_assertions::assert_eq;
-use sp_runtime::{traits::Get, TokenError};
+use sp_runtime::{traits::Get, Perbill, TokenError};
 use CoreAssignment::*;
 use CoretimeTraceItem::*;
 use Finality::*;
@@ -78,9 +78,9 @@ fn drop_renewal_works() {
 		let e = Error::<Test>::StillValid;
 		assert_noop!(Broker::do_drop_renewal(region.core, region.begin + 3), e);
 		advance_to(12);
-		assert_eq!(AllowedRenewals::<Test>::iter().count(), 1);
+		assert_eq!(PotentialRenewals::<Test>::iter().count(), 1);
 		assert_ok!(Broker::do_drop_renewal(region.core, region.begin + 3));
-		assert_eq!(AllowedRenewals::<Test>::iter().count(), 0);
+		assert_eq!(PotentialRenewals::<Test>::iter().count(), 0);
 		let e = Error::<Test>::UnknownRenewal;
 		assert_noop!(Broker::do_drop_renewal(region.core, region.begin + 3), e);
 	});
@@ -361,22 +361,91 @@ fn migration_works() {
 
 #[test]
 fn renewal_works() {
-	TestExt::new().endow(1, 1000).execute_with(|| {
+	let b = 100_000;
+	TestExt::new().endow(1, b).execute_with(move || {
 		assert_ok!(Broker::do_start_sales(100, 1));
 		advance_to(2);
 		let region = Broker::do_purchase(1, u64::max_value()).unwrap();
-		assert_eq!(balance(1), 900);
+		assert_eq!(balance(1), 99_900);
 		assert_ok!(Broker::do_assign(region, None, 1001, Final));
 		// Should now be renewable.
 		advance_to(6);
 		assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::<Test>::TooEarly);
 		let core = Broker::do_renew(1, region.core).unwrap();
-		assert_eq!(balance(1), 800);
+		assert_eq!(balance(1), 99_800);
 		advance_to(8);
 		assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::<Test>::SoldOut);
 		advance_to(12);
 		assert_ok!(Broker::do_renew(1, core));
-		assert_eq!(balance(1), 690);
+		assert_eq!(balance(1), 99_690);
+	});
+}
+
+#[test]
+/// Renewals have to affect price as well. Otherwise a market where everything is a renewal would
+/// not work. Renewals happening in the leadin or after are effectively competing with the open
+/// market and it makes sense to adjust the price to what was paid here. Assuming all renewals were
+/// done in the interlude and only normal sales happen in the leadin, renewals will have no effect
+/// on price. If there are no cores left for sale on the open markent, renewals will affect price
+/// even in the interlude, making sure renewal prices stay in the range of the open market.
+fn renewals_affect_price() {
+	sp_tracing::try_init_simple();
+	let b = 100_000;
+	let config = ConfigRecord {
+		advance_notice: 2,
+		interlude_length: 10,
+		leadin_length: 20,
+		ideal_bulk_proportion: Perbill::from_percent(100),
+		limit_cores_offered: None,
+		// Region length is in time slices (2 blocks):
+		region_length: 20,
+		renewal_bump: Perbill::from_percent(10),
+		contribution_timeout: 5,
+	};
+	TestExt::new_with_config(config).endow(1, b).execute_with(|| {
+		let price = 910;
+		assert_ok!(Broker::do_start_sales(10, 1));
+		advance_to(11);
+		let region = Broker::do_purchase(1, u64::max_value()).unwrap();
+		// Price is lower, because already one block in:
+		let b = b - price;
+		assert_eq!(balance(1), b);
+		assert_ok!(Broker::do_assign(region, None, 1001, Final));
+		advance_to(40);
+		assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::<Test>::TooEarly);
+		let core = Broker::do_renew(1, region.core).unwrap();
+		// First renewal has same price as initial purchase.
+		let b = b - price;
+		assert_eq!(balance(1), b);
+		advance_to(51);
+		assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::<Test>::SoldOut);
+		advance_to(81);
+		assert_ok!(Broker::do_renew(1, core));
+		// Renewal bump in effect
+		let price = price + Perbill::from_percent(10) * price;
+		let b = b - price;
+		assert_eq!(balance(1), b);
+
+		// Move after interlude and leadin - should reduce price.
+		advance_to(159);
+		Broker::do_renew(1, region.core).unwrap();
+		let price = price + Perbill::from_percent(10) * price;
+		let b = b - price;
+		assert_eq!(balance(1), b);
+
+		advance_to(161);
+		// Should have the reduced price now:
+		Broker::do_renew(1, region.core).unwrap();
+		let price = 100;
+		let b = b - price;
+		assert_eq!(balance(1), b);
+
+		// Price should be bumped normally again:
+		advance_to(201);
+		Broker::do_renew(1, region.core).unwrap();
+		let price = 110;
+		let b = b - price;
+		assert_eq!(balance(1), b);
 	});
 }
 
@@ -916,7 +985,8 @@ fn short_leases_are_cleaned() {
 
 #[test]
 fn leases_can_be_renewed() {
-	TestExt::new().endow(1, 1000).execute_with(|| {
+	let initial_balance = 100_000;
+	TestExt::new().endow(1, initial_balance).execute_with(|| {
 		// Timeslice period is 2.
 		//
 		// Sale 1 starts at block 7, Sale 2 starts at 13.
@@ -927,13 +997,13 @@ fn leases_can_be_renewed() {
 		// Start the sales with only one core for this lease.
 		assert_ok!(Broker::do_start_sales(100, 0));
 
-		// Advance to sale period 1, we should get an AllowedRenewal for task 2001 for the next
+		// Advance to sale period 1, we should get an PotentialRenewal for task 2001 for the next
 		// sale.
 		advance_sale_period();
 		assert_eq!(
-			AllowedRenewals::<Test>::get(AllowedRenewalId { core: 0, when: 10 }),
-			Some(AllowedRenewalRecord {
-				price: 100,
+			PotentialRenewals::<Test>::get(PotentialRenewalId { core: 0, when: 10 }),
+			Some(PotentialRenewalRecord {
+				price: 1000,
 				completion: CompletionStatus::Complete(
 					vec![ScheduleItem { mask: CoreMask::complete(), assignment: Task(2001) }]
 						.try_into()
@@ -947,8 +1017,8 @@ fn leases_can_be_renewed() {
 		// Advance to sale period 2, where we can renew.
 		advance_sale_period();
 		assert_ok!(Broker::do_renew(1, 0));
-		// We renew for the base price of the previous sale period.
-		assert_eq!(balance(1), 900);
+		// We renew for the price of the previous sale period.
+		assert_eq!(balance(1), initial_balance - 1000);
 
 		// We just renewed for this period.
 		advance_sale_period();
@@ -1023,14 +1093,14 @@ fn short_leases_cannot_be_renewed() {
 		// The lease is removed.
 		assert_eq!(Leases::<Test>::get().len(), 0);
 
-		// We should have got an entry in AllowedRenewals, but we don't because rotate_sale
+		// We should have got an entry in PotentialRenewals, but we don't because rotate_sale
 		// schedules leases a period in advance. This renewal should be in the period after next
 		// because while bootstrapping our way into the sale periods, we give everything a lease for
 		// period 1, so they can renew for period 2. So we have a core until the end of period 1,
 		// but we are not marked as able to renew because we expired before sale period 1 starts.
 		//
 		// This should be fixed.
-		assert_eq!(AllowedRenewals::<Test>::get(AllowedRenewalId { core: 0, when: 10 }), None);
+		assert_eq!(PotentialRenewals::<Test>::get(PotentialRenewalId { core: 0, when: 10 }), None);
 		// And the lease has been removed from storage.
 		assert_eq!(Leases::<Test>::get().len(), 0);
 
@@ -1102,7 +1172,7 @@ fn purchase_requires_valid_status_and_sale_info() {
 		let mut dummy_sale = SaleInfoRecord {
 			sale_start: 0,
 			leadin_length: 0,
-			price: 200,
+			end_price: 200,
 			sellout_price: None,
 			region_begin: 0,
 			region_end: 3,
@@ -1144,7 +1214,7 @@ fn renewal_requires_valid_status_and_sale_info() {
 		let mut dummy_sale = SaleInfoRecord {
 			sale_start: 0,
 			leadin_length: 0,
-			price: 200,
+			end_price: 200,
 			sellout_price: None,
 			region_begin: 0,
 			region_end: 3,
@@ -1163,11 +1233,11 @@ fn renewal_requires_valid_status_and_sale_info() {
 		assert_ok!(Broker::do_start_sales(200, 1));
 		assert_noop!(Broker::do_renew(1, 1), Error::<Test>::NotAllowed);
 
-		let record = AllowedRenewalRecord {
+		let record = PotentialRenewalRecord {
 			price: 100,
 			completion: CompletionStatus::Partial(CoreMask::from_chunk(0, 20)),
 		};
-		AllowedRenewals::<Test>::insert(AllowedRenewalId { core: 1, when: 4 }, &record);
+		PotentialRenewals::<Test>::insert(PotentialRenewalId { core: 1, when: 4 }, &record);
 		assert_noop!(Broker::do_renew(1, 1), Error::<Test>::IncompleteAssignment);
 	});
 }
@@ -1274,7 +1344,7 @@ fn config_works() {
 /// Ensure that a lease that ended before `start_sales` was called can be renewed.
 #[test]
 fn renewal_works_leases_ended_before_start_sales() {
-	TestExt::new().endow(1, 1000).execute_with(|| {
+	TestExt::new().endow(1, 100_000).execute_with(|| {
 		let config = Configuration::<Test>::get().unwrap();
 
 		// This lease is ended before `start_stales` was called.
@@ -1304,7 +1374,7 @@ fn renewal_works_leases_ended_before_start_sales() {
 		let new_core = Broker::do_renew(1, 0).unwrap();
 		// Renewing the active lease doesn't work.
 		assert_noop!(Broker::do_renew(1, 1), Error::<Test>::SoldOut);
-		assert_eq!(balance(1), 900);
+		assert_eq!(balance(1), 99000);
 
 		// This intializes the third sale and the period 2.
 		advance_sale_period();
@@ -1312,7 +1382,7 @@ fn renewal_works_leases_ended_before_start_sales() {
 
 		// Renewing the active lease doesn't work.
 		assert_noop!(Broker::do_renew(1, 0), Error::<Test>::SoldOut);
-		assert_eq!(balance(1), 800);
+		assert_eq!(balance(1), 98900);
 
 		// All leases should have ended
 		assert!(Leases::<Test>::get().is_empty());
@@ -1324,7 +1394,7 @@ fn renewal_works_leases_ended_before_start_sales() {
 		assert_eq!(0, Broker::do_renew(1, new_core).unwrap());
 		// Renew the task 2.
 		assert_eq!(1, Broker::do_renew(1, 0).unwrap());
-		assert_eq!(balance(1), 600);
+		assert_eq!(balance(1), 98790);
 
 		// This intializes the fifth sale and the period 4.
 		advance_sale_period();
diff --git a/substrate/frame/broker/src/tick_impls.rs b/substrate/frame/broker/src/tick_impls.rs
index 04e9a65bf8f67b11ef66edf7268eda74e336e65d..20637cf7b903cf73fb5d9bfe08e70013303bcb1a 100644
--- a/substrate/frame/broker/src/tick_impls.rs
+++ b/substrate/frame/broker/src/tick_impls.rs
@@ -17,10 +17,7 @@
 
 use super::*;
 use frame_support::{pallet_prelude::*, weights::WeightMeter};
-use sp_arithmetic::{
-	traits::{One, SaturatedConversion, Saturating, Zero},
-	FixedPointNumber,
-};
+use sp_arithmetic::traits::{One, SaturatedConversion, Saturating, Zero};
 use sp_runtime::traits::ConvertBack;
 use sp_std::{vec, vec::Vec};
 use CompletionStatus::Complete;
@@ -163,31 +160,13 @@ impl<T: Config> Pallet<T> {
 		InstaPoolIo::<T>::mutate(old_sale.region_end, |r| r.system.saturating_reduce(old_pooled));
 
 		// Calculate the start price for the upcoming sale.
-		let price = {
-			let offered = old_sale.cores_offered;
-			let ideal = old_sale.ideal_cores_sold;
-			let sold = old_sale.cores_sold;
-
-			let maybe_purchase_price = if offered == 0 {
-				// No cores offered for sale - no purchase price.
-				None
-			} else if sold >= ideal {
-				// Sold more than the ideal amount. We should look for the last purchase price
-				// before the sell-out. If there was no purchase at all, then we avoid having a
-				// price here so that we make no alterations to it (since otherwise we would
-				// increase it).
-				old_sale.sellout_price
-			} else {
-				// Sold less than the ideal - we fall back to the regular price.
-				Some(old_sale.price)
-			};
-			if let Some(purchase_price) = maybe_purchase_price {
-				T::PriceAdapter::adapt_price(sold.min(offered), ideal, offered)
-					.saturating_mul_int(purchase_price)
-			} else {
-				old_sale.price
-			}
-		};
+		let new_prices = T::PriceAdapter::adapt_price(SalePerformance::from_sale(&old_sale));
+
+		log::debug!(
+			"Rotated sale, new prices: {:?}, {:?}",
+			new_prices.end_price,
+			new_prices.target_price
+		);
 
 		// Set workload for the reserved (system, probably) workloads.
 		let region_begin = old_sale.region_end;
@@ -220,12 +199,15 @@ impl<T: Config> Pallet<T> {
 			let expire = until < region_end;
 			if expire {
 				// last time for this one - make it renewable in the next sale.
-				let renewal_id = AllowedRenewalId { core: first_core, when: region_end };
-				let record = AllowedRenewalRecord { price, completion: Complete(schedule) };
-				AllowedRenewals::<T>::insert(renewal_id, &record);
+				let renewal_id = PotentialRenewalId { core: first_core, when: region_end };
+				let record = PotentialRenewalRecord {
+					price: new_prices.target_price,
+					completion: Complete(schedule),
+				};
+				PotentialRenewals::<T>::insert(renewal_id, &record);
 				Self::deposit_event(Event::Renewable {
 					core: first_core,
-					price,
+					price: new_prices.target_price,
 					begin: region_end,
 					workload: record.completion.drain_complete().unwrap_or_default(),
 				});
@@ -244,12 +226,19 @@ impl<T: Config> Pallet<T> {
 		let sale_start = now.saturating_add(config.interlude_length);
 		let leadin_length = config.leadin_length;
 		let ideal_cores_sold = (config.ideal_bulk_proportion * cores_offered as u32) as u16;
+		let sellout_price = if cores_offered > 0 {
+			// No core sold -> price was too high -> we have to adjust downwards.
+			Some(new_prices.end_price)
+		} else {
+			None
+		};
+
 		// Update SaleInfo
 		let new_sale = SaleInfoRecord {
 			sale_start,
 			leadin_length,
-			price,
-			sellout_price: None,
+			end_price: new_prices.end_price,
+			sellout_price,
 			region_begin,
 			region_end,
 			first_core,
@@ -257,12 +246,13 @@ impl<T: Config> Pallet<T> {
 			cores_offered,
 			cores_sold: 0,
 		};
+
 		SaleInfo::<T>::put(&new_sale);
 		Self::deposit_event(Event::SaleInitialized {
 			sale_start,
 			leadin_length,
 			start_price: Self::sale_price(&new_sale, now),
-			regular_price: price,
+			end_price: new_prices.end_price,
 			region_begin,
 			region_end,
 			ideal_cores_sold,
diff --git a/substrate/frame/broker/src/types.rs b/substrate/frame/broker/src/types.rs
index f2cae9a41ad480b1e4608a4d556b10d166282c1d..885cac9a5c23d47add53ce4e2eff02da49d3cdc9 100644
--- a/substrate/frame/broker/src/types.rs
+++ b/substrate/frame/broker/src/types.rs
@@ -152,25 +152,28 @@ impl CompletionStatus {
 	}
 }
 
-/// The identity of a possible Core workload renewal.
+/// The identity of a possibly renewable Core workload.
 #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
-pub struct AllowedRenewalId {
+pub struct PotentialRenewalId {
 	/// The core whose workload at the sale ending with `when` may be renewed to begin at `when`.
 	pub core: CoreIndex,
 	/// The point in time that the renewable workload on `core` ends and a fresh renewal may begin.
 	pub when: Timeslice,
 }
 
-/// A record of an allowed renewal.
+/// A record of a potential renewal.
+///
+/// The renewal will only actually be allowed if `CompletionStatus` is `Complete` at the time of
+/// renewal.
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
-pub struct AllowedRenewalRecord<Balance> {
+pub struct PotentialRenewalRecord<Balance> {
 	/// The price for which the next renewal can be made.
 	pub price: Balance,
 	/// The workload which will be scheduled on the Core in the case a renewal is made, or if
 	/// incomplete, then the parts of the core which have been scheduled.
 	pub completion: CompletionStatus,
 }
-pub type AllowedRenewalRecordOf<T> = AllowedRenewalRecord<BalanceOf<T>>;
+pub type PotentialRenewalRecordOf<T> = PotentialRenewalRecord<BalanceOf<T>>;
 
 /// General status of the system.
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
@@ -211,7 +214,7 @@ pub struct SaleInfoRecord<Balance, BlockNumber> {
 	/// The length in blocks of the Leadin Period (where the price is decreasing).
 	pub leadin_length: BlockNumber,
 	/// The price of Bulk Coretime after the Leadin Period.
-	pub price: Balance,
+	pub end_price: Balance,
 	/// The first timeslice of the Regions which are being sold in this sale.
 	pub region_begin: Timeslice,
 	/// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One
@@ -225,8 +228,9 @@ pub struct SaleInfoRecord<Balance, BlockNumber> {
 	/// The index of the first core which is for sale. Core of Regions which are sold have
 	/// incrementing indices from this.
 	pub first_core: CoreIndex,
-	/// The latest price at which Bulk Coretime was purchased until surpassing the ideal number of
-	/// cores were sold.
+	/// The price at which cores have been sold out.
+	///
+	/// Will only be `None` if no core was offered for sale.
 	pub sellout_price: Option<Balance>,
 	/// Number of cores which have been sold; never more than cores_offered.
 	pub cores_sold: CoreIndex,
@@ -263,8 +267,11 @@ pub struct ConfigRecord<BlockNumber, RelayBlockNumber> {
 	pub leadin_length: BlockNumber,
 	/// The length in timeslices of Regions which are up for sale in forthcoming sales.
 	pub region_length: Timeslice,
-	/// The proportion of cores available for sale which should be sold in order for the price
-	/// to remain the same in the next sale.
+	/// The proportion of cores available for sale which should be sold.
+	///
+	/// If more cores are sold than this, then further sales will no longer be considered in
+	/// determining the sellout price. In other words the sellout price will be the last price
+	/// paid, without going over this limit.
 	pub ideal_bulk_proportion: Perbill,
 	/// An artificial limit to the number of cores which are allowed to be sold. If `Some` then
 	/// no more cores will be sold than this.
diff --git a/substrate/frame/broker/src/utility_impls.rs b/substrate/frame/broker/src/utility_impls.rs
index 4163817a8b584bd949210aff383398ff50b95d58..9cceb7f970a9f55bf8a9420937b1f8d2c7826479 100644
--- a/substrate/frame/broker/src/utility_impls.rs
+++ b/substrate/frame/broker/src/utility_impls.rs
@@ -63,7 +63,7 @@ impl<T: Config> Pallet<T> {
 	pub fn sale_price(sale: &SaleInfoRecordOf<T>, now: BlockNumberFor<T>) -> BalanceOf<T> {
 		let num = now.saturating_sub(sale.sale_start).min(sale.leadin_length).saturated_into();
 		let through = FixedU64::from_rational(num, sale.leadin_length.saturated_into());
-		T::PriceAdapter::leadin_factor_at(through).saturating_mul_int(sale.price)
+		T::PriceAdapter::leadin_factor_at(through).saturating_mul_int(sale.end_price)
 	}
 
 	pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
@@ -72,6 +72,25 @@ impl<T: Config> Pallet<T> {
 		Ok(())
 	}
 
+	/// Buy a core at the specified price (price is to be determined by the caller).
+	///
+	/// Note: It is the responsibility of the caller to write back the changed `SaleInfoRecordOf` to
+	/// storage.
+	pub(crate) fn purchase_core(
+		who: &T::AccountId,
+		price: BalanceOf<T>,
+		sale: &mut SaleInfoRecordOf<T>,
+	) -> Result<CoreIndex, DispatchError> {
+		Self::charge(who, price)?;
+		log::debug!("Purchased core at: {:?}", price);
+		let core = sale.first_core.saturating_add(sale.cores_sold);
+		sale.cores_sold.saturating_inc();
+		if sale.cores_sold <= sale.ideal_cores_sold || sale.sellout_price.is_none() {
+			sale.sellout_price = Some(price);
+		}
+		Ok(core)
+	}
+
 	pub fn issue(
 		core: CoreIndex,
 		begin: Timeslice,
diff --git a/substrate/frame/broker/src/weights.rs b/substrate/frame/broker/src/weights.rs
index 2aa1c282a41d8a98e6a0a824e5eaa150922b2356..d9d9d348e47e9db76731b41fd65086c689fc86f0 100644
--- a/substrate/frame/broker/src/weights.rs
+++ b/substrate/frame/broker/src/weights.rs
@@ -18,27 +18,25 @@
 //! Autogenerated weights for `pallet_broker`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2024-04-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-05-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-anb7yjbi-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-vicqj8em-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
 
 // Executed Command:
-// ./target/production/substrate-node
+// target/production/substrate-node
 // benchmark
 // pallet
-// --chain=dev
 // --steps=50
 // --repeat=20
-// --pallet=pallet_broker
-// --no-storage-info
-// --no-median-slopes
-// --no-min-squares
 // --extrinsic=*
 // --wasm-execution=compiled
 // --heap-pages=4096
-// --output=./substrate/frame/broker/src/weights.rs
+// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
+// --pallet=pallet_broker
+// --chain=dev
 // --header=./substrate/HEADER-APACHE2
+// --output=./substrate/frame/broker/src/weights.rs
 // --template=./substrate/.maintain/frame-weight-template.hbs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
@@ -90,8 +88,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_624_000 picoseconds.
-		Weight::from_parts(2_804_000, 0)
+		// Minimum execution time: 1_945_000 picoseconds.
+		Weight::from_parts(2_142_000, 0)
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Reservations` (r:1 w:1)
@@ -100,8 +98,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `5016`
 		//  Estimated: `7496`
-		// Minimum execution time: 18_451_000 picoseconds.
-		Weight::from_parts(18_853_000, 7496)
+		// Minimum execution time: 16_274_000 picoseconds.
+		Weight::from_parts(16_828_000, 7496)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -111,8 +109,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `6218`
 		//  Estimated: `7496`
-		// Minimum execution time: 16_899_000 picoseconds.
-		Weight::from_parts(17_645_000, 7496)
+		// Minimum execution time: 15_080_000 picoseconds.
+		Weight::from_parts(15_874_000, 7496)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -122,19 +120,19 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `239`
 		//  Estimated: `1526`
-		// Minimum execution time: 10_239_000 picoseconds.
-		Weight::from_parts(10_754_000, 1526)
+		// Minimum execution time: 8_761_000 picoseconds.
+		Weight::from_parts(9_203_000, 1526)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Configuration` (r:1 w:0)
 	/// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::InstaPoolIo` (r:3 w:3)
-	/// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::Reservations` (r:1 w:0)
-	/// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Leases` (r:1 w:1)
 	/// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::Reservations` (r:1 w:0)
+	/// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::InstaPoolIo` (r:3 w:3)
+	/// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::SaleInfo` (r:0 w:1)
 	/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Status` (r:0 w:1)
@@ -146,12 +144,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `6330`
 		//  Estimated: `8499`
-		// Minimum execution time: 51_250_000 picoseconds.
-		Weight::from_parts(54_643_012, 8499)
-			// Standard Error: 147
-			.saturating_add(Weight::from_parts(18, 0).saturating_mul(n.into()))
+		// Minimum execution time: 26_057_000 picoseconds.
+		Weight::from_parts(46_673_357, 8499)
+			// Standard Error: 456
+			.saturating_add(Weight::from_parts(2_677, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(6_u64))
-			.saturating_add(T::DbWeight::get().writes(16_u64))
+			.saturating_add(T::DbWeight::get().writes(15_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
@@ -162,13 +160,13 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `System::Digest` (r:1 w:0)
 	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
 	/// Storage: `Broker::Regions` (r:0 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn purchase() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `635`
-		//  Estimated: `2120`
-		// Minimum execution time: 43_660_000 picoseconds.
-		Weight::from_parts(45_543_000, 2120)
+		//  Measured:  `651`
+		//  Estimated: `2136`
+		// Minimum execution time: 40_907_000 picoseconds.
+		Weight::from_parts(42_566_000, 2136)
 			.saturating_add(T::DbWeight::get().reads(4_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
@@ -178,8 +176,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::SaleInfo` (r:1 w:1)
 	/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:2)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:2)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	/// Storage: `Authorship::Author` (r:1 w:0)
 	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
 	/// Storage: `System::Digest` (r:1 w:0)
@@ -188,43 +186,43 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	fn renew() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `753`
+		//  Measured:  `769`
 		//  Estimated: `4698`
-		// Minimum execution time: 63_122_000 picoseconds.
-		Weight::from_parts(64_366_000, 4698)
+		// Minimum execution time: 65_209_000 picoseconds.
+		Weight::from_parts(68_604_000, 4698)
 			.saturating_add(T::DbWeight::get().reads(6_u64))
 			.saturating_add(T::DbWeight::get().writes(4_u64))
 	}
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn transfer() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `495`
-		//  Estimated: `3550`
-		// Minimum execution time: 17_552_000 picoseconds.
-		Weight::from_parts(18_251_000, 3550)
+		//  Measured:  `496`
+		//  Estimated: `3551`
+		// Minimum execution time: 15_860_000 picoseconds.
+		Weight::from_parts(16_393_000, 3551)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Regions` (r:1 w:2)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn partition() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `495`
-		//  Estimated: `3550`
-		// Minimum execution time: 18_551_000 picoseconds.
-		Weight::from_parts(19_727_000, 3550)
+		//  Measured:  `496`
+		//  Estimated: `3551`
+		// Minimum execution time: 17_651_000 picoseconds.
+		Weight::from_parts(18_088_000, 3551)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
 	/// Storage: `Broker::Regions` (r:1 w:3)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn interlace() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `495`
-		//  Estimated: `3550`
-		// Minimum execution time: 20_636_000 picoseconds.
-		Weight::from_parts(21_060_000, 3550)
+		//  Measured:  `496`
+		//  Estimated: `3551`
+		// Minimum execution time: 18_576_000 picoseconds.
+		Weight::from_parts(19_810_000, 3551)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
@@ -233,22 +231,22 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Workplan` (r:1 w:1)
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	fn assign() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `740`
+		//  Measured:  `741`
 		//  Estimated: `4681`
-		// Minimum execution time: 32_394_000 picoseconds.
-		Weight::from_parts(33_324_000, 4681)
+		// Minimum execution time: 31_015_000 picoseconds.
+		Weight::from_parts(31_932_000, 4681)
 			.saturating_add(T::DbWeight::get().reads(4_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Workplan` (r:1 w:1)
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::InstaPoolIo` (r:2 w:2)
@@ -257,10 +255,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
 	fn pool() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `775`
+		//  Measured:  `776`
 		//  Estimated: `5996`
-		// Minimum execution time: 38_128_000 picoseconds.
-		Weight::from_parts(39_274_000, 5996)
+		// Minimum execution time: 36_473_000 picoseconds.
+		Weight::from_parts(37_382_000, 5996)
 			.saturating_add(T::DbWeight::get().reads(5_u64))
 			.saturating_add(T::DbWeight::get().writes(5_u64))
 	}
@@ -275,10 +273,10 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `859`
 		//  Estimated: `6196 + m * (2520 ±0)`
-		// Minimum execution time: 70_453_000 picoseconds.
-		Weight::from_parts(70_652_822, 6196)
-			// Standard Error: 75_524
-			.saturating_add(Weight::from_parts(2_335_289, 0).saturating_mul(m.into()))
+		// Minimum execution time: 64_957_000 picoseconds.
+		Weight::from_parts(66_024_232, 6196)
+			// Standard Error: 50_170
+			.saturating_add(Weight::from_parts(1_290_632, 0).saturating_mul(m.into()))
 			.saturating_add(T::DbWeight::get().reads(3_u64))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into())))
 			.saturating_add(T::DbWeight::get().writes(5_u64))
@@ -290,21 +288,21 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 43_945_000 picoseconds.
-		Weight::from_parts(45_249_000, 3593)
+		// Minimum execution time: 39_939_000 picoseconds.
+		Weight::from_parts(40_788_000, 3593)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn drop_region() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `603`
-		//  Estimated: `3550`
-		// Minimum execution time: 30_680_000 picoseconds.
-		Weight::from_parts(32_995_000, 3550)
+		//  Measured:  `604`
+		//  Estimated: `3551`
+		// Minimum execution time: 31_709_000 picoseconds.
+		Weight::from_parts(37_559_000, 3551)
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -318,8 +316,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `601`
 		//  Estimated: `3533`
-		// Minimum execution time: 48_053_000 picoseconds.
-		Weight::from_parts(51_364_000, 3533)
+		// Minimum execution time: 42_895_000 picoseconds.
+		Weight::from_parts(53_945_000, 3533)
 			.saturating_add(T::DbWeight::get().reads(3_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -335,21 +333,21 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `995`
 		//  Estimated: `3593`
-		// Minimum execution time: 57_372_000 picoseconds.
-		Weight::from_parts(59_466_000, 3593)
+		// Minimum execution time: 50_770_000 picoseconds.
+		Weight::from_parts(63_117_000, 3593)
 			.saturating_add(T::DbWeight::get().reads(4_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:1)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:1)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	fn drop_renewal() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `661`
 		//  Estimated: `4698`
-		// Minimum execution time: 27_768_000 picoseconds.
-		Weight::from_parts(29_000_000, 4698)
+		// Minimum execution time: 33_396_000 picoseconds.
+		Weight::from_parts(36_247_000, 4698)
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -358,20 +356,18 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 4_588_000 picoseconds.
-		Weight::from_parts(5_201_705, 0)
+		// Minimum execution time: 3_625_000 picoseconds.
+		Weight::from_parts(4_011_396, 0)
 	}
 	/// Storage: `Broker::CoreCountInbox` (r:1 w:1)
 	/// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[0, 1000]`.
-	fn process_core_count(n: u32, ) -> Weight {
+	fn process_core_count(_n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `404`
 		//  Estimated: `1487`
-		// Minimum execution time: 6_889_000 picoseconds.
-		Weight::from_parts(7_380_363, 1487)
-			// Standard Error: 21
-			.saturating_add(Weight::from_parts(63, 0).saturating_mul(n.into()))
+		// Minimum execution time: 6_217_000 picoseconds.
+		Weight::from_parts(6_608_394, 1487)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -389,8 +385,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `972`
 		//  Estimated: `4437`
-		// Minimum execution time: 50_156_000 picoseconds.
-		Weight::from_parts(51_610_000, 4437)
+		// Minimum execution time: 46_853_000 picoseconds.
+		Weight::from_parts(47_740_000, 4437)
 			.saturating_add(T::DbWeight::get().reads(5_u64))
 			.saturating_add(T::DbWeight::get().writes(3_u64))
 	}
@@ -405,14 +401,12 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	/// Storage: `Broker::Workplan` (r:0 w:10)
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[0, 1000]`.
-	fn rotate_sale(n: u32, ) -> Weight {
+	fn rotate_sale(_n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `6281`
 		//  Estimated: `8499`
-		// Minimum execution time: 38_246_000 picoseconds.
-		Weight::from_parts(40_008_850, 8499)
-			// Standard Error: 94
-			.saturating_add(Weight::from_parts(964, 0).saturating_mul(n.into()))
+		// Minimum execution time: 34_240_000 picoseconds.
+		Weight::from_parts(35_910_175, 8499)
 			.saturating_add(T::DbWeight::get().reads(5_u64))
 			.saturating_add(T::DbWeight::get().writes(15_u64))
 	}
@@ -424,8 +418,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `180`
 		//  Estimated: `3493`
-		// Minimum execution time: 7_962_000 picoseconds.
-		Weight::from_parts(8_313_000, 3493)
+		// Minimum execution time: 7_083_000 picoseconds.
+		Weight::from_parts(7_336_000, 3493)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -437,8 +431,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `1423`
 		//  Estimated: `4681`
-		// Minimum execution time: 17_457_000 picoseconds.
-		Weight::from_parts(18_387_000, 4681)
+		// Minimum execution time: 15_029_000 picoseconds.
+		Weight::from_parts(15_567_000, 4681)
 			.saturating_add(T::DbWeight::get().reads(2_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
@@ -446,8 +440,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 133_000 picoseconds.
-		Weight::from_parts(149_000, 0)
+		// Minimum execution time: 123_000 picoseconds.
+		Weight::from_parts(136_000, 0)
 	}
 	/// Storage: `Broker::CoreCountInbox` (r:0 w:1)
 	/// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`)
@@ -455,8 +449,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_407_000 picoseconds.
-		Weight::from_parts(2_634_000, 0)
+		// Minimum execution time: 1_775_000 picoseconds.
+		Weight::from_parts(1_911_000, 0)
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:1)
@@ -471,8 +465,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `603`
 		//  Estimated: `4068`
-		// Minimum execution time: 13_043_000 picoseconds.
-		Weight::from_parts(13_541_000, 4068)
+		// Minimum execution time: 11_859_000 picoseconds.
+		Weight::from_parts(12_214_000, 4068)
 			.saturating_add(T::DbWeight::get().reads(4_u64))
 			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
@@ -482,8 +476,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `239`
 		//  Estimated: `1526`
-		// Minimum execution time: 6_606_000 picoseconds.
-		Weight::from_parts(6_964_000, 1526)
+		// Minimum execution time: 5_864_000 picoseconds.
+		Weight::from_parts(6_231_000, 1526)
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
@@ -497,8 +491,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_624_000 picoseconds.
-		Weight::from_parts(2_804_000, 0)
+		// Minimum execution time: 1_945_000 picoseconds.
+		Weight::from_parts(2_142_000, 0)
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Reservations` (r:1 w:1)
@@ -507,8 +501,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `5016`
 		//  Estimated: `7496`
-		// Minimum execution time: 18_451_000 picoseconds.
-		Weight::from_parts(18_853_000, 7496)
+		// Minimum execution time: 16_274_000 picoseconds.
+		Weight::from_parts(16_828_000, 7496)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -518,8 +512,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `6218`
 		//  Estimated: `7496`
-		// Minimum execution time: 16_899_000 picoseconds.
-		Weight::from_parts(17_645_000, 7496)
+		// Minimum execution time: 15_080_000 picoseconds.
+		Weight::from_parts(15_874_000, 7496)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -529,19 +523,19 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `239`
 		//  Estimated: `1526`
-		// Minimum execution time: 10_239_000 picoseconds.
-		Weight::from_parts(10_754_000, 1526)
+		// Minimum execution time: 8_761_000 picoseconds.
+		Weight::from_parts(9_203_000, 1526)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Configuration` (r:1 w:0)
 	/// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::InstaPoolIo` (r:3 w:3)
-	/// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::Reservations` (r:1 w:0)
-	/// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Leases` (r:1 w:1)
 	/// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::Reservations` (r:1 w:0)
+	/// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::InstaPoolIo` (r:3 w:3)
+	/// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::SaleInfo` (r:0 w:1)
 	/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Status` (r:0 w:1)
@@ -553,12 +547,12 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `6330`
 		//  Estimated: `8499`
-		// Minimum execution time: 51_250_000 picoseconds.
-		Weight::from_parts(54_643_012, 8499)
-			// Standard Error: 147
-			.saturating_add(Weight::from_parts(18, 0).saturating_mul(n.into()))
+		// Minimum execution time: 26_057_000 picoseconds.
+		Weight::from_parts(46_673_357, 8499)
+			// Standard Error: 456
+			.saturating_add(Weight::from_parts(2_677, 0).saturating_mul(n.into()))
 			.saturating_add(RocksDbWeight::get().reads(6_u64))
-			.saturating_add(RocksDbWeight::get().writes(16_u64))
+			.saturating_add(RocksDbWeight::get().writes(15_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
@@ -569,13 +563,13 @@ impl WeightInfo for () {
 	/// Storage: `System::Digest` (r:1 w:0)
 	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
 	/// Storage: `Broker::Regions` (r:0 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn purchase() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `635`
-		//  Estimated: `2120`
-		// Minimum execution time: 43_660_000 picoseconds.
-		Weight::from_parts(45_543_000, 2120)
+		//  Measured:  `651`
+		//  Estimated: `2136`
+		// Minimum execution time: 40_907_000 picoseconds.
+		Weight::from_parts(42_566_000, 2136)
 			.saturating_add(RocksDbWeight::get().reads(4_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
@@ -585,8 +579,8 @@ impl WeightInfo for () {
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::SaleInfo` (r:1 w:1)
 	/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:2)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:2)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	/// Storage: `Authorship::Author` (r:1 w:0)
 	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
 	/// Storage: `System::Digest` (r:1 w:0)
@@ -595,43 +589,43 @@ impl WeightInfo for () {
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	fn renew() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `753`
+		//  Measured:  `769`
 		//  Estimated: `4698`
-		// Minimum execution time: 63_122_000 picoseconds.
-		Weight::from_parts(64_366_000, 4698)
+		// Minimum execution time: 65_209_000 picoseconds.
+		Weight::from_parts(68_604_000, 4698)
 			.saturating_add(RocksDbWeight::get().reads(6_u64))
 			.saturating_add(RocksDbWeight::get().writes(4_u64))
 	}
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn transfer() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `495`
-		//  Estimated: `3550`
-		// Minimum execution time: 17_552_000 picoseconds.
-		Weight::from_parts(18_251_000, 3550)
+		//  Measured:  `496`
+		//  Estimated: `3551`
+		// Minimum execution time: 15_860_000 picoseconds.
+		Weight::from_parts(16_393_000, 3551)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Regions` (r:1 w:2)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn partition() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `495`
-		//  Estimated: `3550`
-		// Minimum execution time: 18_551_000 picoseconds.
-		Weight::from_parts(19_727_000, 3550)
+		//  Measured:  `496`
+		//  Estimated: `3551`
+		// Minimum execution time: 17_651_000 picoseconds.
+		Weight::from_parts(18_088_000, 3551)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
 	/// Storage: `Broker::Regions` (r:1 w:3)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn interlace() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `495`
-		//  Estimated: `3550`
-		// Minimum execution time: 20_636_000 picoseconds.
-		Weight::from_parts(21_060_000, 3550)
+		//  Measured:  `496`
+		//  Estimated: `3551`
+		// Minimum execution time: 18_576_000 picoseconds.
+		Weight::from_parts(19_810_000, 3551)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
@@ -640,22 +634,22 @@ impl WeightInfo for () {
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Workplan` (r:1 w:1)
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	fn assign() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `740`
+		//  Measured:  `741`
 		//  Estimated: `4681`
-		// Minimum execution time: 32_394_000 picoseconds.
-		Weight::from_parts(33_324_000, 4681)
+		// Minimum execution time: 31_015_000 picoseconds.
+		Weight::from_parts(31_932_000, 4681)
 			.saturating_add(RocksDbWeight::get().reads(4_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Workplan` (r:1 w:1)
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::InstaPoolIo` (r:2 w:2)
@@ -664,10 +658,10 @@ impl WeightInfo for () {
 	/// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`)
 	fn pool() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `775`
+		//  Measured:  `776`
 		//  Estimated: `5996`
-		// Minimum execution time: 38_128_000 picoseconds.
-		Weight::from_parts(39_274_000, 5996)
+		// Minimum execution time: 36_473_000 picoseconds.
+		Weight::from_parts(37_382_000, 5996)
 			.saturating_add(RocksDbWeight::get().reads(5_u64))
 			.saturating_add(RocksDbWeight::get().writes(5_u64))
 	}
@@ -682,10 +676,10 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `859`
 		//  Estimated: `6196 + m * (2520 ±0)`
-		// Minimum execution time: 70_453_000 picoseconds.
-		Weight::from_parts(70_652_822, 6196)
-			// Standard Error: 75_524
-			.saturating_add(Weight::from_parts(2_335_289, 0).saturating_mul(m.into()))
+		// Minimum execution time: 64_957_000 picoseconds.
+		Weight::from_parts(66_024_232, 6196)
+			// Standard Error: 50_170
+			.saturating_add(Weight::from_parts(1_290_632, 0).saturating_mul(m.into()))
 			.saturating_add(RocksDbWeight::get().reads(3_u64))
 			.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into())))
 			.saturating_add(RocksDbWeight::get().writes(5_u64))
@@ -697,21 +691,21 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 43_945_000 picoseconds.
-		Weight::from_parts(45_249_000, 3593)
+		// Minimum execution time: 39_939_000 picoseconds.
+		Weight::from_parts(40_788_000, 3593)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
 	/// Storage: `Broker::Regions` (r:1 w:1)
-	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
+	/// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(86), added: 2561, mode: `MaxEncodedLen`)
 	fn drop_region() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `603`
-		//  Estimated: `3550`
-		// Minimum execution time: 30_680_000 picoseconds.
-		Weight::from_parts(32_995_000, 3550)
+		//  Measured:  `604`
+		//  Estimated: `3551`
+		// Minimum execution time: 31_709_000 picoseconds.
+		Weight::from_parts(37_559_000, 3551)
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -725,8 +719,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `601`
 		//  Estimated: `3533`
-		// Minimum execution time: 48_053_000 picoseconds.
-		Weight::from_parts(51_364_000, 3533)
+		// Minimum execution time: 42_895_000 picoseconds.
+		Weight::from_parts(53_945_000, 3533)
 			.saturating_add(RocksDbWeight::get().reads(3_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -742,21 +736,21 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `995`
 		//  Estimated: `3593`
-		// Minimum execution time: 57_372_000 picoseconds.
-		Weight::from_parts(59_466_000, 3593)
+		// Minimum execution time: 50_770_000 picoseconds.
+		Weight::from_parts(63_117_000, 3593)
 			.saturating_add(RocksDbWeight::get().reads(4_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:0)
 	/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
-	/// Storage: `Broker::AllowedRenewals` (r:1 w:1)
-	/// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
+	/// Storage: `Broker::PotentialRenewals` (r:1 w:1)
+	/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
 	fn drop_renewal() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `661`
 		//  Estimated: `4698`
-		// Minimum execution time: 27_768_000 picoseconds.
-		Weight::from_parts(29_000_000, 4698)
+		// Minimum execution time: 33_396_000 picoseconds.
+		Weight::from_parts(36_247_000, 4698)
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -765,20 +759,18 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 4_588_000 picoseconds.
-		Weight::from_parts(5_201_705, 0)
+		// Minimum execution time: 3_625_000 picoseconds.
+		Weight::from_parts(4_011_396, 0)
 	}
 	/// Storage: `Broker::CoreCountInbox` (r:1 w:1)
 	/// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[0, 1000]`.
-	fn process_core_count(n: u32, ) -> Weight {
+	fn process_core_count(_n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `404`
 		//  Estimated: `1487`
-		// Minimum execution time: 6_889_000 picoseconds.
-		Weight::from_parts(7_380_363, 1487)
-			// Standard Error: 21
-			.saturating_add(Weight::from_parts(63, 0).saturating_mul(n.into()))
+		// Minimum execution time: 6_217_000 picoseconds.
+		Weight::from_parts(6_608_394, 1487)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -796,8 +788,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `972`
 		//  Estimated: `4437`
-		// Minimum execution time: 50_156_000 picoseconds.
-		Weight::from_parts(51_610_000, 4437)
+		// Minimum execution time: 46_853_000 picoseconds.
+		Weight::from_parts(47_740_000, 4437)
 			.saturating_add(RocksDbWeight::get().reads(5_u64))
 			.saturating_add(RocksDbWeight::get().writes(3_u64))
 	}
@@ -812,14 +804,12 @@ impl WeightInfo for () {
 	/// Storage: `Broker::Workplan` (r:0 w:10)
 	/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[0, 1000]`.
-	fn rotate_sale(n: u32, ) -> Weight {
+	fn rotate_sale(_n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `6281`
 		//  Estimated: `8499`
-		// Minimum execution time: 38_246_000 picoseconds.
-		Weight::from_parts(40_008_850, 8499)
-			// Standard Error: 94
-			.saturating_add(Weight::from_parts(964, 0).saturating_mul(n.into()))
+		// Minimum execution time: 34_240_000 picoseconds.
+		Weight::from_parts(35_910_175, 8499)
 			.saturating_add(RocksDbWeight::get().reads(5_u64))
 			.saturating_add(RocksDbWeight::get().writes(15_u64))
 	}
@@ -831,8 +821,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `180`
 		//  Estimated: `3493`
-		// Minimum execution time: 7_962_000 picoseconds.
-		Weight::from_parts(8_313_000, 3493)
+		// Minimum execution time: 7_083_000 picoseconds.
+		Weight::from_parts(7_336_000, 3493)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
@@ -844,8 +834,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `1423`
 		//  Estimated: `4681`
-		// Minimum execution time: 17_457_000 picoseconds.
-		Weight::from_parts(18_387_000, 4681)
+		// Minimum execution time: 15_029_000 picoseconds.
+		Weight::from_parts(15_567_000, 4681)
 			.saturating_add(RocksDbWeight::get().reads(2_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
@@ -853,8 +843,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 133_000 picoseconds.
-		Weight::from_parts(149_000, 0)
+		// Minimum execution time: 123_000 picoseconds.
+		Weight::from_parts(136_000, 0)
 	}
 	/// Storage: `Broker::CoreCountInbox` (r:0 w:1)
 	/// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`)
@@ -862,8 +852,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_407_000 picoseconds.
-		Weight::from_parts(2_634_000, 0)
+		// Minimum execution time: 1_775_000 picoseconds.
+		Weight::from_parts(1_911_000, 0)
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
 	/// Storage: `Broker::Status` (r:1 w:1)
@@ -878,8 +868,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `603`
 		//  Estimated: `4068`
-		// Minimum execution time: 13_043_000 picoseconds.
-		Weight::from_parts(13_541_000, 4068)
+		// Minimum execution time: 11_859_000 picoseconds.
+		Weight::from_parts(12_214_000, 4068)
 			.saturating_add(RocksDbWeight::get().reads(4_u64))
 			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
@@ -889,8 +879,8 @@ impl WeightInfo for () {
 		// Proof Size summary in bytes:
 		//  Measured:  `239`
 		//  Estimated: `1526`
-		// Minimum execution time: 6_606_000 picoseconds.
-		Weight::from_parts(6_964_000, 1526)
+		// Minimum execution time: 5_864_000 picoseconds.
+		Weight::from_parts(6_231_000, 1526)
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}