diff --git a/Cargo.lock b/Cargo.lock
index 90c768c..0e53472 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7138,6 +7138,25 @@ dependencies = [
"sp-runtime",
]
+[[package]]
+name = "pallet-rewards"
+version = "0.1.0"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "log",
+ "order-primitives",
+ "pallet-balances",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "smallvec",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+]
+
[[package]]
name = "pallet-root-testing"
version = "4.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 0165bfb..9414045 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -165,3 +165,4 @@ pallet-market = { path = "./pallets/market", default-features = false }
pallet-orders = { path = "./pallets/orders", default-features = false }
pallet-processor = { path = "./pallets/processor", default-features = false }
pallet-regions = { path = "./pallets/regions", default-features = false }
+pallet-rewards = { path = "./pallets/rewards", default-features = false }
diff --git a/pallets/rewards/Cargo.toml b/pallets/rewards/Cargo.toml
new file mode 100644
index 0000000..60c2905
--- /dev/null
+++ b/pallets/rewards/Cargo.toml
@@ -0,0 +1,51 @@
+[package]
+name = "pallet-rewards"
+authors = ["Anonymous"]
+description = "Pallet for processing coretime orders"
+version = "0.1.0"
+license = "GPLv3"
+edition = "2021"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+log = { workspace = true }
+codec = { workspace = true, default-features = false, features = ["derive"] }
+scale-info = { workspace = true, default-features = false, features = ["derive"] }
+
+# Substrate
+frame-benchmarking = { workspace = true, default-features = false, optional = true }
+frame-support = { workspace = true, default-features = false }
+frame-system = { workspace = true, default-features = false }
+sp-io = { workspace = true, default-features = false }
+sp-core = { workspace = true, default-features = false }
+sp-runtime = { workspace = true, default-features = false }
+
+# Local
+order-primitives = { workspace = true, default-features = false }
+
+[dev-dependencies]
+serde = { workspace = true }
+smallvec = { workspace = true }
+pallet-balances = { workspace = true, default-features = false }
+
+[features]
+default = ["std"]
+runtime-benchmarks = [
+ "frame-benchmarking/runtime-benchmarks",
+]
+std = [
+ "log/std",
+ "codec/std",
+ "scale-info/std",
+ "sp-io/std",
+ "sp-core/std",
+ "sp-runtime/std",
+ "frame-benchmarking/std",
+ "frame-support/std",
+ "frame-system/std",
+ "pallet-balances/std",
+ "order-primitives/std",
+]
+try-runtime = ["frame-support/try-runtime"]
diff --git a/pallets/rewards/src/lib.rs b/pallets/rewards/src/lib.rs
new file mode 100644
index 0000000..becbe17
--- /dev/null
+++ b/pallets/rewards/src/lib.rs
@@ -0,0 +1,159 @@
+// This file is part of RegionX.
+//
+// RegionX is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// RegionX is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RegionX. If not, see .
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use frame_support::traits::fungibles;
+use frame_system::WeightInfo;
+use order_primitives::{OrderFactory, OrderId, OrderInspect};
+pub use pallet::*;
+use sp_runtime::traits::Zero;
+
+mod types;
+
+const LOG_TARGET: &str = "runtime::rewards";
+
+pub type BalanceOf = <::Assets as fungibles::Inspect<
+ ::AccountId,
+>>::Balance;
+
+pub type AssetIdOf = <::Assets as fungibles::Inspect<
+ ::AccountId,
+>>::AssetId;
+
+#[frame_support::pallet]
+pub mod pallet {
+ use super::*;
+ use frame_support::{
+ pallet_prelude::*,
+ traits::{fungibles::Inspect, tokens::Balance},
+ };
+ use frame_system::pallet_prelude::*;
+ use types::PrizePoolDetails;
+
+ /// The module configuration trait.
+ #[pallet::config]
+ pub trait Config: frame_system::Config {
+ /// The overarching event type.
+ type RuntimeEvent: From> + IsType<::RuntimeEvent>;
+
+ /// Relay chain balance type
+ type Balance: Balance
+ + Into<>::Balance>
+ + Into;
+
+ /// The type should provide access to assets which can be used as reward.
+ type Assets: Inspect;
+
+ /// Type over which we can access order data.
+ type Orders: OrderInspect + OrderFactory;
+
+ /// Weight Info
+ type WeightInfo: WeightInfo;
+ }
+
+ #[pallet::pallet]
+ pub struct Pallet(_);
+
+ /// Defines the rewards that will be distributed among order contributors if the order is
+ /// fulfilled on time.
+ #[pallet::storage]
+ #[pallet::getter(fn order_rewards)]
+ pub type PrizePools =
+ StorageMap<_, Blake2_128Concat, OrderId, PrizePoolDetails, BalanceOf>>;
+
+ #[pallet::event]
+ #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ pub enum Event {}
+
+ #[pallet::error]
+ #[derive(PartialEq)]
+ pub enum Error {
+ /// The caller submitted an extrinsic which wasn't allowed with their origin.
+ Unallowed,
+ /// The order expired and there is no point in configuring rewards.
+ OrderExpired,
+ /// Order not found.
+ UnknownOrder,
+ /// Rewards can only be configured if there is no existing configuration or if the rewards
+ /// are not yet set and are currently zero.
+ CantConfigure,
+ /// The reward pool of an order was not found.
+ PrizePoolNotFound,
+ /// The asset the user wanted to use for rewards does not exist.
+ AssetNotFound,
+ }
+
+ #[pallet::call]
+ impl Pallet {
+ /// The order creator can configure the asset which will be used for rewarding contributors.
+ #[pallet::call_index(0)]
+ #[pallet::weight(10_000)]
+ pub fn configure_rewards(
+ origin: OriginFor,
+ order_id: OrderId,
+ asset_id: AssetIdOf,
+ ) -> DispatchResult {
+ let caller = ensure_signed(origin)?;
+
+ let order = T::Orders::order(&order_id).ok_or(Error::::UnknownOrder)?;
+
+ ensure!(!T::Orders::order_expired(&order), Error::::OrderExpired);
+ ensure!(order.creator == caller, Error::::Unallowed);
+
+ let maybe_pool = PrizePools::::get(order_id);
+ // Rewards can be reconfigured if the amount is still zero.
+ if let Some(pool) = maybe_pool {
+ ensure!(pool.amount == Zero::zero(), Error::::CantConfigure);
+ }
+
+ ensure!(T::Assets::asset_exists(asset_id.clone()) == true, Error::::AssetNotFound);
+
+ PrizePools::::insert(order_id, PrizePoolDetails { asset_id, amount: Zero::zero() });
+
+ // TODO: deposit event
+ Ok(())
+ }
+
+ /// Add rewards to a reward pool of an order.
+ ///
+ /// The added rewards will be of the configured asset kind.
+ ///
+ /// ## Parameters
+ ///
+ /// - `origin`: Signed origin. Can be called by any account.
+ /// - `order_id`: The order to which the user wants to contribute rewards. There must exist
+ /// a reward pool for the specified order.
+ /// -`amount`: number of tokens the user wants to add to the reward pool.
+ #[pallet::call_index(1)]
+ #[pallet::weight(10_000)]
+ pub fn add_rewards(
+ origin: OriginFor,
+ order_id: OrderId,
+ amount: BalanceOf,
+ ) -> DispatchResult {
+ let _caller = ensure_signed(origin)?;
+
+ let Some(pool) = PrizePools::::get(order_id) else {
+ return Err(Error::::PrizePoolNotFound.into())
+ };
+
+ // TODO: check if user has enough tokens
+ // TODO: contribute to the pool.
+
+ Ok(())
+ }
+ }
+}
diff --git a/pallets/rewards/src/types.rs b/pallets/rewards/src/types.rs
new file mode 100644
index 0000000..3cab3d3
--- /dev/null
+++ b/pallets/rewards/src/types.rs
@@ -0,0 +1,26 @@
+// This file is part of RegionX.
+//
+// RegionX is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// RegionX is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RegionX. If not, see .
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+
+/// Contains reward details of an order.
+#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)]
+pub struct PrizePoolDetails {
+ /// The asset which the contributors will receive,
+ pub asset_id: AssetId,
+ /// Amount of tokens that will be distributed to contributors.
+ pub amount: Balance,
+}