Skip to content

Commit

Permalink
feat: setup pallet skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
marcuspang committed Aug 3, 2024
1 parent ce6938a commit 58e6c3f
Show file tree
Hide file tree
Showing 5 changed files with 440 additions and 8 deletions.
25 changes: 21 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ members = [
"substrate/frame/nomination-pools/test-transfer-stake",
"substrate/frame/offences",
"substrate/frame/offences/benchmarking",
"substrate/frame/optimistic-funding",
"substrate/frame/paged-list",
"substrate/frame/paged-list/fuzzer",
"substrate/frame/parameters",
Expand Down Expand Up @@ -940,6 +941,7 @@ pallet-nomination-pools-benchmarking = { path = "substrate/frame/nomination-pool
pallet-nomination-pools-runtime-api = { path = "substrate/frame/nomination-pools/runtime-api", default-features = false }
pallet-offences = { path = "substrate/frame/offences", default-features = false }
pallet-offences-benchmarking = { path = "substrate/frame/offences/benchmarking", default-features = false }
pallet-optimistic-funding = { path = "substrate/frame/optimistic-funding", default-features = false }
pallet-paged-list = { path = "substrate/frame/paged-list", default-features = false }
pallet-parachain-template = { path = "templates/parachain/pallets/template", default-features = false }
pallet-parameters = { path = "substrate/frame/parameters", default-features = false }
Expand Down
49 changes: 49 additions & 0 deletions substrate/frame/optimistic-funding/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[package]
name = "pallet-optimistic-funding"
version = "0.1.0"
description = "FRAME pallet that allows for optimistic funding of a whitelisted projects"
authors.workspace = true
homepage.workspace = true
edition.workspace = true
license = "Apache-2.0"
repository.workspace = true

[lints]
workspace = true

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { features = ["derive"], workspace = true }
docify = { workspace = true }
scale-info = { features = ["derive"], workspace = true }
serde = { optional = true, workspace = true, default-features = true }

frame-benchmarking = { optional = true, workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }

sp-runtime = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }

[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = ["frame-support/try-runtime", "frame-system/try-runtime"]
212 changes: 212 additions & 0 deletions substrate/frame/optimistic-funding/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
#![cfg_attr(not(feature = "std"), no_std)]

use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{pallet_prelude::*, traits::fungible, Parameter};
use frame_system::pallet_prelude::*;
use sp_runtime::{traits::Member, DispatchResult, RuntimeDebug};

pub use pallet::*;

pub type BalanceOf<T> = <<T as Config>::NativeBalance as fungible::Inspect<
<T as frame_system::Config>::AccountId,
>>::Balance;

#[derive(Encode, Decode, Clone, PartialEq, MaxEncodedLen, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct ProjectVote<T: pallet::Config> {
amount: BalanceOf<T>,
conviction: T::Conviction,
voted_at: BlockNumberFor<T>,
is_fund: bool,
}

#[derive(Encode, Decode, Clone, PartialEq, MaxEncodedLen, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct ProjectInfo<T: pallet::Config> {
whitelisted_block: BlockNumberFor<T>,
last_claimed_block: BlockNumberFor<T>,
unclaimed_reward: BalanceOf<T>,
total_votes: u32,
}

#[frame_support::pallet]
pub mod pallet {
use super::*;

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

type NativeBalance: fungible::Inspect<Self::AccountId>
+ fungible::Mutate<Self::AccountId>
+ fungible::hold::Inspect<Self::AccountId>
+ fungible::hold::Mutate<Self::AccountId, Reason = Self::RuntimeHoldReason>
+ fungible::freeze::Inspect<Self::AccountId>
+ fungible::freeze::Mutate<Self::AccountId>;

type Conviction: Parameter + Member + MaxEncodedLen + Decode + Encode;

type BlockNumber: Parameter + Member + MaxEncodedLen + Decode + Encode;

type RuntimeHoldReason: From<HoldReason>;

/// The origin that can add new projects to the whitelist.
type WhitelistProjectOrigin: EnsureOrigin<Self::RuntimeOrigin>;

/// The type used to identify projects.
type ProjectId: Parameter + Member + MaxEncodedLen;

/// The account which will be funding the whitelisted projects.
#[pallet::constant]
type TreasuryAccountId: Get<Self::AccountId>;

/// The minimum duration for which votes are locked.
#[pallet::constant]
type VoteLockingPeriod: Get<BlockNumberFor<Self>>;

/// The period after which votes must be renewed.
#[pallet::constant]
type VoteRenewalPeriod: Get<BlockNumberFor<Self>>;

/// The number of blocks between funding periods.
#[pallet::constant]
type FundingPeriod: Get<BlockNumberFor<Self>>;

/// The maximum number of projects that can be whitelisted.
#[pallet::constant]
type MaxProjects: Get<u32>;
}

/// A reason for placing a hold on funds.
#[pallet::composite_enum]
pub enum HoldReason {}

/// List of whitelisted projects to be funded.
#[pallet::storage]
pub type WhitelistedProjects<T: Config> =
StorageValue<_, BoundedVec<ProjectInfo<T>, T::MaxProjects>, ValueQuery>;

/// Votes for projects.
#[pallet::storage]
pub type Votes<T: Config> = StorageDoubleMap<
_,
Blake2_128Concat,
T::AccountId,
Blake2_128Concat,
T::ProjectId,
ProjectVote<T>,
>;

/// The starting block number of the current voting period.
#[pallet::storage]
pub type CurrentVotingPeriodStartingBlock<T: Config> =
StorageValue<_, BlockNumberFor<T>, ValueQuery>;

#[pallet::event]
pub enum Event<T: Config> {}

#[pallet::error]
pub enum Error<T> {}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(n: BlockNumberFor<T>) -> Weight {
// check if current block is the start of a new voting period

// distribute rewards for the previous voting period by updating project info

0.into()
}
}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(0)]
pub fn vote_project(
origin: OriginFor<T>,
project_id: T::ProjectId,
amount: BalanceOf<T>,
conviction: T::Conviction,
is_fund: bool,
) -> DispatchResult {
// check if project_id is valid

// set the vote data

// try to hold user funds based on conviction
// if user has voted before, update hold amount instead

Ok(())
}

#[pallet::call_index(1)]
#[pallet::weight(0)]
pub fn remove_vote(
origin: OriginFor<T>,
project_id: T::ProjectId,
amount: BalanceOf<T>,
) -> DispatchResult {
// check if project_id is valid

// set the vote data

// try to release `amount` from the user's hold

Ok(())
}

#[pallet::call_index(2)]
#[pallet::weight(0)]
pub fn whitelist_project(origin: OriginFor<T>, project_id: T::ProjectId) -> DispatchResult {
// check origin is whitelist origin

// ensure project has not been whitelisted before

// add to project list

Ok(())
}

#[pallet::call_index(3)]
#[pallet::weight(0)]
pub fn remove_whitelist_project(
origin: OriginFor<T>,
project_id: T::ProjectId,
) -> DispatchResult {
// check origin is whitelist origin

// ensure project has been whitelisted before

// remove from project list

Ok(())
}

#[pallet::call_index(4)]
#[pallet::weight(0)]
pub fn claim_reward(
origin: OriginFor<T>,
project_id: T::ProjectId,
amount: BalanceOf<T>,
) -> DispatchResult {
// check origin is project id

// ensure project is whitelisted
// current block > project.whitelisted_block

// ensure project has not claimed in the previous voting period
// current block > project.last_claimed_block
// current block < project.last_claimed_block + voting_period

// update project info

// release funds for project

Ok(())
}
}
}
Loading

0 comments on commit 58e6c3f

Please sign in to comment.