diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 169768243b5a47435e0a2157a8999dafcf9d6609..4ec0fa275b4feb7288f227cf584760c39067c0b1 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	// implementation changes and behavior does not, then leave spec_version as
 	// is and increment impl_version.
 	spec_version: 244,
-	impl_version: 1,
+	impl_version: 2,
 	apis: RUNTIME_API_VERSIONS,
 	transaction_version: 1,
 };
diff --git a/substrate/primitives/arithmetic/src/fixed64.rs b/substrate/primitives/arithmetic/src/fixed64.rs
index af4dbf34e293b3d47e23760c2de87cbe5be18a28..63a69e66e7c9d6363e1c9eeba7b6c9e4c31b3164 100644
--- a/substrate/primitives/arithmetic/src/fixed64.rs
+++ b/substrate/primitives/arithmetic/src/fixed64.rs
@@ -113,7 +113,10 @@ impl Saturating for Fixed64 {
 	}
 
 	fn saturating_mul(self, rhs: Self) -> Self {
-		Self(self.0.saturating_mul(rhs.0) / DIV)
+		let a = self.0 as i128;
+		let b = rhs.0 as i128;
+		let res = a * b / DIV as i128;
+		Self(res.saturated_into())
 	}
 
 	fn saturating_sub(self, rhs: Self) -> Self {
@@ -121,7 +124,22 @@ impl Saturating for Fixed64 {
 	}
 
 	fn saturating_pow(self, exp: usize) -> Self {
-		Self(self.0.saturating_pow(exp as u32))
+		if exp == 0 {
+			return Self::from_natural(1);
+		}
+
+		let exp = exp as u64;
+		let msb_pos = 64 - exp.leading_zeros();
+
+		let mut result = Self::from_natural(1);
+		let mut pow_val = self;
+		for i in 0..msb_pos {
+			if ((1 << i) & exp) > 0 {
+				result = result.saturating_mul(pow_val);
+			}
+			pow_val = pow_val.saturating_mul(pow_val);
+		}
+		result
 	}
 }
 
@@ -333,4 +351,32 @@ mod tests {
 		let b = Fixed64::from_rational(1, 100);
 		assert_eq!(a.checked_div(&b), Some(Fixed64::from_rational(120, 1)));
 	}
+
+	#[test]
+	fn saturating_mul_should_work() {
+		assert_eq!(Fixed64::from_natural(100).saturating_mul(Fixed64::from_natural(100)), Fixed64::from_natural(10000));
+	}
+
+	#[test]
+	fn saturating_pow_should_work() {
+		assert_eq!(Fixed64::from_natural(2).saturating_pow(0), Fixed64::from_natural(1));
+		assert_eq!(Fixed64::from_natural(2).saturating_pow(1), Fixed64::from_natural(2));
+		assert_eq!(Fixed64::from_natural(2).saturating_pow(2), Fixed64::from_natural(4));
+		assert_eq!(Fixed64::from_natural(2).saturating_pow(3), Fixed64::from_natural(8));
+		assert_eq!(Fixed64::from_natural(2).saturating_pow(20), Fixed64::from_natural(1048576));
+
+		assert_eq!(Fixed64::from_natural(1).saturating_pow(1000), Fixed64::from_natural(1));
+		assert_eq!(Fixed64::from_natural(-1).saturating_pow(1000), Fixed64::from_natural(1));
+		assert_eq!(Fixed64::from_natural(-1).saturating_pow(1001), Fixed64::from_natural(-1));
+		assert_eq!(Fixed64::from_natural(1).saturating_pow(usize::max_value()), Fixed64::from_natural(1));
+		assert_eq!(Fixed64::from_natural(-1).saturating_pow(usize::max_value()), Fixed64::from_natural(-1));
+		assert_eq!(Fixed64::from_natural(-1).saturating_pow(usize::max_value() - 1), Fixed64::from_natural(1));
+
+		assert_eq!(Fixed64::from_natural(309).saturating_pow(4), Fixed64::from_natural(9_116_621_361));
+		assert_eq!(Fixed64::from_natural(309).saturating_pow(5), Fixed64::from_parts(i64::max_value()));
+
+		assert_eq!(Fixed64::from_natural(1).saturating_pow(usize::max_value()), Fixed64::from_natural(1));
+		assert_eq!(Fixed64::from_natural(0).saturating_pow(usize::max_value()), Fixed64::from_natural(0));
+		assert_eq!(Fixed64::from_natural(2).saturating_pow(usize::max_value()), Fixed64::from_parts(i64::max_value()));
+	}
 }