Skip to content

Commit

Permalink
Fix vote ratio (#1048)
Browse files Browse the repository at this point in the history
* Fix vote ratio

* Fix vtoken lock balance
  • Loading branch information
ark930 authored Sep 15, 2023
1 parent 93a4f21 commit e7ae241
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 35 deletions.
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

0 comments on commit e7ae241

Please sign in to comment.