Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Rewards pallet #867

Merged
merged 69 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
3f7dd29
Merge branch 'main' of github.com:tangle-network/tangle into feat/evm…
1xstj Dec 10, 2024
b7644b8
chore : switch to asset-id evm
1xstj Dec 10, 2024
ce7effe
cleanup
1xstj Dec 11, 2024
cf47bec
bump subxt
1xstj Dec 11, 2024
663f374
clean slate
1xstj Dec 12, 2024
f65f735
Merge branch 'main' of github.com:tangle-network/tangle into feat/evm…
1xstj Dec 12, 2024
5a677c8
use common exports
1xstj Dec 12, 2024
5e53247
use common exports
1xstj Dec 12, 2024
87181bb
wip
1xstj Dec 12, 2024
fadb9f6
wip
1xstj Dec 13, 2024
4d6b596
wip
1xstj Dec 13, 2024
c214aca
fix compile
1xstj Dec 13, 2024
a704da2
cleanup
1xstj Dec 13, 2024
6b51c97
compiling
1xstj Dec 14, 2024
4cc8780
precompiles fixes
1xstj Dec 16, 2024
b1719ee
Merge branch 'main' of github.com:tangle-network/tangle into feat/evm…
1xstj Dec 16, 2024
4a2a2a8
runtimes building
1xstj Dec 16, 2024
35f9394
update mocks
1xstj Dec 16, 2024
42a56fe
cleanup tests
1xstj Dec 16, 2024
145ff94
update js types
1xstj Dec 16, 2024
0c400ac
update subxt
1xstj Dec 16, 2024
c179e4c
cleanup clippy
1xstj Dec 16, 2024
8c58a05
use nightly fmt
1xstj Dec 16, 2024
130955c
use stable fmt
1xstj Dec 16, 2024
59b2375
cleanup clippy
1xstj Dec 16, 2024
f59c794
cleanup tests
1xstj Dec 16, 2024
0e72e74
cleanup tests
1xstj Dec 16, 2024
ec34241
cleanup fmt
1xstj Dec 16, 2024
99c6b08
more tests passing
1xstj Dec 17, 2024
eeb5487
cleanup clippy
1xstj Dec 17, 2024
44500a5
clipyy fixes
1xstj Dec 17, 2024
b2815d3
cleanup clippy
1xstj Dec 17, 2024
e7c6dbe
import oracle pallet
1xstj Dec 17, 2024
ebe8b6a
update traits
1xstj Dec 17, 2024
7adf9e6
update precompile
1xstj Dec 17, 2024
c9754bb
cleanup mock
1xstj Dec 17, 2024
6956d90
Merge branch 'main' of github.com:tangle-network/tangle into oracle-p…
1xstj Dec 18, 2024
fce9401
fix
1xstj Dec 18, 2024
eca9612
updates to tests
1xstj Dec 19, 2024
4e75299
base pallet
1xstj Dec 19, 2024
a8c87b5
wip
1xstj Dec 24, 2024
3fed390
wip tests and benchmarks
1xstj Dec 30, 2024
65d1058
Merge branch 'main' of github.com:tangle-network/tangle into rewards-…
1xstj Dec 30, 2024
7ac3dec
cleanup clippy
1xstj Dec 30, 2024
5ddb1c3
fmt
1xstj Dec 30, 2024
aa379fc
more tests and fuzzing
1xstj Dec 31, 2024
827f61a
Merge branch 'main' of github.com:tangle-network/tangle into rewards-…
1xstj Jan 1, 2025
7ab3e6f
wip
1xstj Jan 1, 2025
1cf02ea
add precompile and fuzzer
1xstj Jan 2, 2025
5e332e9
more cleanup and tests
1xstj Jan 2, 2025
c7c3ddf
cleanup clippy
1xstj Jan 2, 2025
4293c90
add back apy calc
1xstj Jan 2, 2025
4bb3ebe
refactor and simplify
1xstj Jan 6, 2025
99926e5
refactoring
1xstj Jan 6, 2025
17c818a
refactoring test limits
1xstj Jan 6, 2025
839a23f
cleanup
1xstj Jan 6, 2025
0328576
Merge branch 'main' of github.com:tangle-network/tangle into rewards-…
1xstj Jan 6, 2025
b19caef
update tests and benchmarks
1xstj Jan 6, 2025
fbf90e0
rearrange flow
1xstj Jan 7, 2025
1b5b6c3
refactor control flow
1xstj Jan 7, 2025
6e611fd
wip tests
1xstj Jan 7, 2025
71bdc5d
wip tests
1xstj Jan 7, 2025
d8768dd
tests passing
1xstj Jan 7, 2025
d5d8d67
rewards e2e cleanup
1xstj Jan 7, 2025
3c60882
Merge branch 'main' of github.com:tangle-network/tangle into rewards-…
1xstj Jan 7, 2025
90a0ff6
cleanup
1xstj Jan 7, 2025
6748232
update tests
1xstj Jan 7, 2025
f346f64
cleanup clippy
1xstj Jan 7, 2025
8e11728
Merge branch 'main' into rewards-pallet
drewstone Jan 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion Cargo.lock

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

12 changes: 11 additions & 1 deletion pallets/multi-asset-delegation/fuzzer/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,17 @@ fn random_calls<R: Rng>(
};
[
join_operators_call(&mut rng, operator_origin.clone(), &operator),
(mad::Call::delegate { operator, asset_id, amount, blueprint_selection }, origin),
(
mad::Call::delegate {
operator,
asset_id,
amount,
blueprint_selection,
lock_multiplier: None,
},
origin,
),
// TODO : Add fuzzing with lock_multiplier
]
.to_vec()
},
Expand Down
66 changes: 64 additions & 2 deletions pallets/multi-asset-delegation/src/functions/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@
// along with Tangle. If not, see <http://www.gnu.org/licenses/>.
use super::*;
use crate::{types::*, Pallet};
use frame_support::BoundedVec;
use frame_support::{
ensure,
pallet_prelude::DispatchResult,
traits::{fungibles::Mutate, tokens::Preservation, Get},
};
use frame_system::pallet_prelude::BlockNumberFor;
use sp_runtime::{
traits::{CheckedSub, Zero},
DispatchError, Percent,
};
use sp_std::vec;
use sp_std::vec::Vec;
use tangle_primitives::types::rewards::LockMultiplier;
use tangle_primitives::{
services::{Asset, EvmAddressMapping},
BlueprintId,
Expand All @@ -51,6 +55,7 @@ impl<T: Config> Pallet<T> {
asset_id: Asset<T::AssetId>,
amount: BalanceOf<T>,
blueprint_selection: DelegatorBlueprintSelection<T::MaxDelegatorBlueprints>,
lock_multiplier: Option<LockMultiplier>,
) -> DispatchResult {
Delegators::<T>::try_mutate(&who, |maybe_metadata| {
let metadata = maybe_metadata.as_mut().ok_or(Error::<T>::NotDelegator)?;
Expand All @@ -74,12 +79,32 @@ impl<T: Config> Pallet<T> {
{
delegation.amount += amount;
} else {
let now = frame_system::Pallet::<T>::block_number();
let now_as_u32: u32 =
now.try_into().map_err(|_| Error::<T>::MaxDelegationsExceeded)?; // TODO : Can be improved
let locks = if let Some(lock_multiplier) = lock_multiplier {
let expiry_block: BlockNumberFor<T> = lock_multiplier
.expiry_block_number::<T>(now_as_u32)
.try_into()
.map_err(|_| Error::<T>::MaxDelegationsExceeded)?;
let bounded_vec = BoundedVec::try_from(vec![LockInfo {
amount,
lock_multiplier,
expiry_block,
}])
.map_err(|_| Error::<T>::MaxDelegationsExceeded)?;
Some(bounded_vec)
} else {
None
};

// Create the new delegation
let new_delegation = BondInfoDelegator {
operator: operator.clone(),
amount,
asset_id,
blueprint_selection,
locks,
};

// Create a mutable copy of delegations
Expand All @@ -102,7 +127,25 @@ impl<T: Config> Pallet<T> {
);

// Create and push the new delegation bond
let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id };
let now = frame_system::Pallet::<T>::block_number();
let now_as_u32: u32 =
now.try_into().map_err(|_| Error::<T>::MaxDelegationsExceeded)?; // TODO : Can be improved
let locks = if let Some(lock_multiplier) = lock_multiplier {
let expiry_block: BlockNumberFor<T> = lock_multiplier
.expiry_block_number::<T>(now_as_u32)
.try_into()
.map_err(|_| Error::<T>::MaxDelegationsExceeded)?;
let bounded_vec = BoundedVec::try_from(vec![LockInfo {
amount,
lock_multiplier,
expiry_block,
}])
.map_err(|_| Error::<T>::MaxDelegationsExceeded)?;
Some(bounded_vec)
} else {
None
};
let delegation = DelegatorBond { delegator: who.clone(), amount, asset_id, locks };

let mut delegations = operator_metadata.delegations.clone();

Expand Down Expand Up @@ -166,6 +209,19 @@ impl<T: Config> Pallet<T> {
let delegation = &mut metadata.delegations[delegation_index];
ensure!(delegation.amount >= amount, Error::<T>::InsufficientBalance);

// ensure the locks are not violated
let now = frame_system::Pallet::<T>::block_number();
if let Some(locks) = &delegation.locks {
// lets filter only active locks
let active_locks =
locks.iter().filter(|lock| lock.expiry_block > now).collect::<Vec<_>>();
let total_locks =
active_locks.iter().fold(0_u32.into(), |acc, lock| acc + lock.amount);
if total_locks != Zero::zero() {
ensure!(amount < total_locks, Error::<T>::LockViolation);
}
}

delegation.amount -= amount;

// Create the unstake request
Expand Down Expand Up @@ -312,7 +368,12 @@ impl<T: Config> Pallet<T> {
delegation.amount += amount;
} else {
delegations
.try_push(DelegatorBond { delegator: who.clone(), amount, asset_id })
.try_push(DelegatorBond {
delegator: who.clone(),
amount,
asset_id,
locks: Default::default(),
})
.map_err(|_| Error::<T>::MaxDelegationsExceeded)?;

// Increase the delegation count only when a new delegation is added
Expand Down Expand Up @@ -340,6 +401,7 @@ impl<T: Config> Pallet<T> {
amount: unstake_request.amount,
asset_id: unstake_request.asset_id,
blueprint_selection: unstake_request.blueprint_selection,
locks: Default::default(), // should be able to unstake only if locks didnt exist
})
.map_err(|_| Error::<T>::MaxDelegationsExceeded)?;
}
Expand Down
5 changes: 5 additions & 0 deletions pallets/multi-asset-delegation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub mod pallet {
use sp_core::H160;
use sp_runtime::traits::{MaybeSerializeDeserialize, Member, Zero};
use sp_std::{collections::btree_map::BTreeMap, fmt::Debug, prelude::*, vec::Vec};
use tangle_primitives::types::rewards::LockMultiplier;
use tangle_primitives::{services::Asset, traits::ServiceManager, BlueprintId, RoundIndex};

/// Configure the pallet by specifying the parameters and types on which it depends.
Expand Down Expand Up @@ -430,6 +431,8 @@ pub mod pallet {
EVMAbiEncode,
/// EVM decode error
EVMAbiDecode,
/// Cannot unstake with locks
LockViolation,
}

/// Hooks for the pallet.
Expand Down Expand Up @@ -607,6 +610,7 @@ pub mod pallet {
asset_id: Asset<T::AssetId>,
amount: BalanceOf<T>,
blueprint_selection: DelegatorBlueprintSelection<T::MaxDelegatorBlueprints>,
lock_multiplier: Option<LockMultiplier>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
Self::process_delegate(
Expand All @@ -615,6 +619,7 @@ pub mod pallet {
asset_id,
amount,
blueprint_selection,
lock_multiplier,
)?;
Self::deposit_event(Event::Delegated { who, operator, asset_id, amount });
Ok(())
Expand Down
Loading
Loading