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

Fix vote ratio #1048

Merged
merged 2 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 22 additions & 8 deletions integration-tests/bifrost-kusama/src/vtoken_voting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,28 @@ fn vote_works() {
});

Bifrost::execute_with(|| {
use bifrost_kusama_runtime::{RuntimeEvent, RuntimeOrigin, System, VtokenVoting};
use bifrost_kusama_runtime::{
RuntimeEvent, RuntimeOrigin, System, VtokenMinting, VtokenVoting,
};

assert_ok!(Tokens::set_balance(
RuntimeOrigin::root(),
MultiAddress::Id(ALICE.into()),
VKSM,
u64::MAX.into(),
Zero::zero(),
assert_ok!(VtokenMinting::mint(
RuntimeOrigin::signed(ALICE.into()),
KSM,
1_000_000_000_000,
Default::default()
));
assert_eq!(
<Runtime as bifrost_vtoken_voting::Config>::VTokenSupplyProvider::get_token_supply(
KSM
),
Some(1_000_000_000_000)
);
assert_eq!(
<Runtime as bifrost_vtoken_voting::Config>::VTokenSupplyProvider::get_vtoken_supply(
VKSM
),
Some(1_000_000_000_000)
);
let token = CurrencyId::to_token(&vtoken).unwrap();
assert_ok!(XcmInterface::set_xcm_dest_weight_and_fee(
token,
Expand Down Expand Up @@ -137,7 +150,8 @@ fn vote_works() {
who: _,
vtoken: VKSM,
poll_index: 0,
vote: _,
new_vote: _,
delegator_vote: _,
})
)));
System::reset_events();
Expand Down
6 changes: 6 additions & 0 deletions node/primitives/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,9 @@ pub trait DerivativeAccountHandler<CurrencyId, Balance> {
#[cfg(feature = "runtime-benchmarks")]
fn add_delegator(token: CurrencyId, index: DerivativeIndex, who: xcm::v3::MultiLocation);
}

pub trait VTokenSupplyProvider<CurrencyId, Balance> {
fn get_vtoken_supply(vtoken: CurrencyId) -> Option<Balance>;

fn get_token_supply(token: CurrencyId) -> Option<Balance>;
}
15 changes: 14 additions & 1 deletion pallets/flexible-fee/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use frame_system as system;
use frame_system::{EnsureRoot, EnsureSignedBy};
use node_primitives::{
Balance, CurrencyId, DerivativeAccountHandler, DerivativeIndex, ExtraFeeInfo, MessageId,
ParaId, TokenSymbol, VKSM,
ParaId, TokenSymbol, VTokenSupplyProvider, VKSM,
};
use orml_traits::MultiCurrency;
use pallet_xcm::EnsureResponse;
Expand Down Expand Up @@ -501,6 +501,18 @@ impl pallet_xcm::Config for Test {
//************** Salp mock end *****************

// ************** VtokenVoting mock start *****************
pub struct SimpleVTokenSupplyProvider;

impl VTokenSupplyProvider<CurrencyId, Balance> for SimpleVTokenSupplyProvider {
fn get_vtoken_supply(_: CurrencyId) -> Option<Balance> {
Some(u64::MAX.into())
}

fn get_token_supply(_: CurrencyId) -> Option<Balance> {
Some(u64::MAX.into())
}
}

impl bifrost_vtoken_voting::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
Expand All @@ -511,6 +523,7 @@ impl bifrost_vtoken_voting::Config for Test {
type XcmDestWeightAndFee = XcmDestWeightAndFee;
type DerivativeAccount = DerivativeAccount;
type RelaychainBlockNumberProvider = RelaychainDataProvider;
type VTokenSupplyProvider = SimpleVTokenSupplyProvider;
type MaxVotes = ConstU32<256>;
type ParachainId = ParaInfo;
type QueryTimeout = QueryTimeout;
Expand Down
22 changes: 20 additions & 2 deletions pallets/vtoken-minting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ use frame_support::{
};
use frame_system::pallet_prelude::*;
use node_primitives::{
CurrencyId, CurrencyIdConversion, CurrencyIdRegister, RedeemType, SlpOperator, SlpxOperator,
TimeUnit, VtokenMintingInterface, VtokenMintingOperator,
CurrencyId, CurrencyIdConversion, CurrencyIdExt, CurrencyIdRegister, RedeemType, SlpOperator,
SlpxOperator, TimeUnit, VTokenSupplyProvider, VtokenMintingInterface, VtokenMintingOperator,
};
use orml_traits::MultiCurrency;
pub use pallet::*;
Expand Down Expand Up @@ -1648,3 +1648,21 @@ impl<T: Config> VtokenMintingInterface<AccountIdOf<T>, CurrencyIdOf<T>, BalanceO
T::HydradxParachainId::get()
}
}

impl<T: Config> VTokenSupplyProvider<CurrencyIdOf<T>, BalanceOf<T>> for Pallet<T> {
fn get_vtoken_supply(vtoken: CurrencyIdOf<T>) -> Option<BalanceOf<T>> {
if CurrencyId::is_vtoken(&vtoken) {
Some(T::MultiCurrency::total_issuance(vtoken))
} else {
None
}
}

fn get_token_supply(token: CurrencyIdOf<T>) -> Option<BalanceOf<T>> {
if CurrencyId::is_token(&token) {
Some(Self::token_pool(token))
} else {
None
}
}
}
71 changes: 59 additions & 12 deletions pallets/vtoken-voting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use frame_support::{
use frame_system::pallet_prelude::{BlockNumberFor, *};
use node_primitives::{
currency::{VDOT, VKSM},
traits::{DerivativeAccountHandler, XcmDestWeightAndFeeHandler},
traits::{DerivativeAccountHandler, VTokenSupplyProvider, XcmDestWeightAndFeeHandler},
CurrencyId, DerivativeIndex, XcmOperationType,
};
use orml_traits::{MultiCurrency, MultiLockableCurrency};
Expand Down Expand Up @@ -110,6 +110,8 @@ pub mod pallet {

type RelaychainBlockNumberProvider: BlockNumberProvider<BlockNumber = BlockNumberFor<Self>>;

type VTokenSupplyProvider: VTokenSupplyProvider<CurrencyIdOf<Self>, BalanceOf<Self>>;

#[pallet::constant]
type ParachainId: Get<ParaId>;

Expand All @@ -131,7 +133,8 @@ pub mod pallet {
who: AccountIdOf<T>,
vtoken: CurrencyIdOf<T>,
poll_index: PollIndex,
vote: AccountVote<BalanceOf<T>>,
new_vote: AccountVote<BalanceOf<T>>,
delegator_vote: AccountVote<BalanceOf<T>>,
},
Unlocked {
who: AccountIdOf<T>,
Expand Down Expand Up @@ -270,7 +273,7 @@ pub mod pallet {
PollIndex,
DerivativeIndex,
AccountIdOf<T>,
Option<AccountVote<BalanceOf<T>>>,
Option<(AccountVote<BalanceOf<T>>, BalanceOf<T>)>,
),
>;

Expand Down Expand Up @@ -396,8 +399,10 @@ pub mod pallet {
let who = ensure_signed(origin)?;
Self::ensure_vtoken(&vtoken)?;
ensure!(UndecidingTimeout::<T>::contains_key(vtoken), Error::<T>::NoData);
let derivative_index = Self::try_select_derivative_index(vtoken, vote)?;
Self::ensure_no_pending_vote(vtoken, poll_index)?;

let new_vote = Self::compute_new_vote(vtoken, vote)?;
let derivative_index = Self::try_select_derivative_index(vtoken, new_vote)?;
if let Some(d) = VoteDelegatorFor::<T>::get((&who, vtoken, poll_index)) {
ensure!(d == derivative_index, Error::<T>::ChangeDelegator)
}
Expand All @@ -419,7 +424,14 @@ pub mod pallet {
}

// record vote info
let maybe_old_vote = Self::try_vote(&who, vtoken, poll_index, derivative_index, vote)?;
let maybe_old_vote = Self::try_vote(
&who,
vtoken,
poll_index,
derivative_index,
new_vote,
vote.balance(),
)?;

// send XCM message
let delegator_vote =
Expand Down Expand Up @@ -449,7 +461,13 @@ pub mod pallet {
},
)?;

Self::deposit_event(Event::<T>::Voted { who, vtoken, poll_index, vote });
Self::deposit_event(Event::<T>::Voted {
who,
vtoken,
poll_index,
new_vote,
delegator_vote,
});

Ok(())
}
Expand Down Expand Up @@ -644,8 +662,15 @@ pub mod pallet {
// rollback vote
Self::try_remove_vote(&who, vtoken, poll_index, UnvoteScope::Any)?;
Self::update_lock(&who, vtoken, &poll_index)?;
if let Some(old_vote) = maybe_old_vote {
Self::try_vote(&who, vtoken, poll_index, derivative_index, old_vote)?;
if let Some((old_vote, vtoken_balance)) = maybe_old_vote {
Self::try_vote(
&who,
vtoken,
poll_index,
derivative_index,
old_vote,
vtoken_balance,
)?;
}
} else {
if !VoteDelegatorFor::<T>::contains_key((&who, vtoken, poll_index)) {
Expand Down Expand Up @@ -747,7 +772,8 @@ pub mod pallet {
poll_index: PollIndex,
derivative_index: DerivativeIndex,
vote: AccountVote<BalanceOf<T>>,
) -> Result<Option<AccountVote<BalanceOf<T>>>, DispatchError> {
vtoken_balance: BalanceOf<T>,
) -> Result<Option<(AccountVote<BalanceOf<T>>, BalanceOf<T>)>, DispatchError> {
ensure!(
vote.balance() <= T::MultiCurrency::total_balance(vtoken, who),
Error::<T>::InsufficientFunds
Expand All @@ -762,16 +788,20 @@ pub mod pallet {
// Shouldn't be possible to fail, but we handle it gracefully.
tally.remove(votes[i].1).ok_or(ArithmeticError::Underflow)?;
Self::try_sub_delegator_vote(vtoken, votes[i].2, votes[i].1)?;
old_vote = Some(votes[i].1);
old_vote = Some((votes[i].1, votes[i].3));
if let Some(approve) = votes[i].1.as_standard() {
tally.reduce(approve, *delegations);
}
votes[i].1 = vote;
votes[i].2 = derivative_index;
votes[i].3 = vtoken_balance;
},
Err(i) => {
votes
.try_insert(i, (poll_index, vote, derivative_index))
.try_insert(
i,
(poll_index, vote, derivative_index, vtoken_balance),
)
.map_err(|_| Error::<T>::MaxVotesReached)?;
},
}
Expand All @@ -786,7 +816,7 @@ pub mod pallet {
}
// Extend the lock to `balance` (rather than setting it) since we don't know
// what other votes are in place.
Self::extend_lock(&who, vtoken, &poll_index, vote.balance())?;
Self::extend_lock(&who, vtoken, &poll_index, vtoken_balance)?;
Ok(old_vote)
})
})
Expand Down Expand Up @@ -1128,5 +1158,22 @@ pub mod pallet {
}
})
}

fn compute_new_vote(
vtoken: CurrencyIdOf<T>,
vote: AccountVote<BalanceOf<T>>,
) -> Result<AccountVote<BalanceOf<T>>, DispatchError> {
let token = CurrencyId::to_token(&vtoken).map_err(|_| Error::<T>::NoData)?;
let vtoken_supply =
T::VTokenSupplyProvider::get_vtoken_supply(vtoken).ok_or(Error::<T>::NoData)?;
let token_supply =
T::VTokenSupplyProvider::get_token_supply(token).ok_or(Error::<T>::NoData)?;
let mut new_vote = vote;
new_vote
.checked_mul(token_supply)
.and_then(|_| new_vote.checked_div(vtoken_supply))?;

Ok(new_vote)
}
}
}
15 changes: 14 additions & 1 deletion pallets/vtoken-voting/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use frame_system::EnsureRoot;
use node_primitives::{
currency::{KSM, VBNC, VKSM},
traits::XcmDestWeightAndFeeHandler,
CurrencyId, DoNothingRouter, TokenSymbol, XcmOperationType,
CurrencyId, DoNothingRouter, TokenSymbol, VTokenSupplyProvider, XcmOperationType,
};
use pallet_xcm::EnsureResponse;
use sp_core::H256;
Expand Down Expand Up @@ -308,6 +308,18 @@ impl BlockNumberProvider for RelaychainDataProvider {
}
}

pub struct SimpleVTokenSupplyProvider;

impl VTokenSupplyProvider<CurrencyId, Balance> for SimpleVTokenSupplyProvider {
fn get_vtoken_supply(_: CurrencyId) -> Option<Balance> {
Some(u64::MAX.into())
}

fn get_token_supply(_: CurrencyId) -> Option<Balance> {
Some(u64::MAX.into())
}
}

impl vtoken_voting::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
Expand All @@ -318,6 +330,7 @@ impl vtoken_voting::Config for Runtime {
type XcmDestWeightAndFee = XcmDestWeightAndFee;
type DerivativeAccount = DerivativeAccount;
type RelaychainBlockNumberProvider = RelaychainDataProvider;
type VTokenSupplyProvider = SimpleVTokenSupplyProvider;
type MaxVotes = ConstU32<256>;
type ParachainId = ParachainId;
type QueryTimeout = QueryTimeout;
Expand Down
Loading