fix(security): audit fixes across 9 custom pallets
- pez-rewards: checked arithmetic in parliamentary reward distribution - tiki: saturating_add in get_tiki_score fold, benchmarking cleanup - ping: saturating_add on PingCount - staking-score: saturating_mul on 4 duration multipliers - pez-treasury: proper error on TreasuryStartBlock None, saturating_add on NextReleaseMonth, doc fix 70->75% - messaging: InboxOverflow event on FIFO eviction - token-wrapper: reorder wrap/unwrap operations, add pallet balance pre-check - welati: u64 cast for turnout percentage overflow prevention - presale: fix refund calculation to use net_in_treasury (98%) instead of impossible 99%, update tests
This commit is contained in:
@@ -151,15 +151,16 @@ pub mod pezpallet {
|
||||
)
|
||||
.map_err(|_| Error::<T>::TransferFailed)?;
|
||||
|
||||
// Update total locked
|
||||
// Mint wrapped tokens to user BEFORE updating TotalLocked
|
||||
// If mint fails, the extrinsic reverts (including the transfer above)
|
||||
T::Assets::mint_into(T::WrapperAssetId::get(), &who, amount)
|
||||
.map_err(|_| Error::<T>::MintFailed)?;
|
||||
|
||||
// Update total locked only after both transfer and mint succeeded
|
||||
TotalLocked::<T>::mutate(|total| {
|
||||
*total = total.saturating_add(amount);
|
||||
});
|
||||
|
||||
// Mint wrapped tokens to user
|
||||
T::Assets::mint_into(T::WrapperAssetId::get(), &who, amount)
|
||||
.map_err(|_| Error::<T>::MintFailed)?;
|
||||
|
||||
Self::deposit_event(Event::Wrapped { who, amount });
|
||||
Ok(())
|
||||
}
|
||||
@@ -188,6 +189,10 @@ pub mod pezpallet {
|
||||
let wrapped_balance = T::Assets::balance(T::WrapperAssetId::get(), &who);
|
||||
ensure!(wrapped_balance >= amount, Error::<T>::InsufficientWrappedBalance);
|
||||
|
||||
// Verify pallet has sufficient backing before any state changes
|
||||
let pallet_balance = T::Currency::free_balance(&Self::account_id());
|
||||
ensure!(pallet_balance >= amount, Error::<T>::TransferFailed);
|
||||
|
||||
// Burn wrapped tokens from user
|
||||
T::Assets::burn_from(
|
||||
T::WrapperAssetId::get(),
|
||||
@@ -199,12 +204,8 @@ pub mod pezpallet {
|
||||
)
|
||||
.map_err(|_| Error::<T>::BurnFailed)?;
|
||||
|
||||
// Update total locked
|
||||
TotalLocked::<T>::mutate(|total| {
|
||||
*total = total.saturating_sub(amount);
|
||||
});
|
||||
|
||||
// Transfer native tokens back to user (unlock)
|
||||
// If this fails, the extrinsic reverts (including the burn above)
|
||||
T::Currency::transfer(
|
||||
&Self::account_id(),
|
||||
&who,
|
||||
@@ -213,6 +214,11 @@ pub mod pezpallet {
|
||||
)
|
||||
.map_err(|_| Error::<T>::TransferFailed)?;
|
||||
|
||||
// Update total locked only after both burn and transfer succeeded
|
||||
TotalLocked::<T>::mutate(|total| {
|
||||
*total = total.saturating_sub(amount);
|
||||
});
|
||||
|
||||
Self::deposit_event(Event::Unwrapped { who, amount });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user