Fix bug with checking for dust in transfers

This commit is contained in:
Paul Hauner 2019-05-23 16:52:20 +10:00
parent 13f78342c3
commit 29792c56d5
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
2 changed files with 19 additions and 7 deletions

View File

@ -398,7 +398,12 @@ pub enum TransferInvalid {
/// min_deposit_amount` /// min_deposit_amount`
/// ///
/// (resulting_amount, min_deposit_amount) /// (resulting_amount, min_deposit_amount)
InvalidResultingFromBalance(u64, u64), SenderDust(u64, u64),
/// This transfer would result in the `transfer.to` account to have `0 < balance <
/// min_deposit_amount`
///
/// (resulting_amount, min_deposit_amount)
RecipientDust(u64, u64),
/// The state slot does not match `transfer.slot`. /// The state slot does not match `transfer.slot`.
/// ///
/// (state_slot, transfer_slot) /// (state_slot, transfer_slot)

View File

@ -44,12 +44,16 @@ fn verify_transfer_parametric<T: EthSpec>(
spec: &ChainSpec, spec: &ChainSpec,
time_independent_only: bool, time_independent_only: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Load the sender balance from state.
let sender_balance = *state let sender_balance = *state
.balances .balances
.get(transfer.sender as usize) .get(transfer.sender as usize)
.ok_or_else(|| Error::Invalid(Invalid::FromValidatorUnknown(transfer.sender)))?; .ok_or_else(|| Error::Invalid(Invalid::FromValidatorUnknown(transfer.sender)))?;
let recipient_balance = *state
.balances
.get(transfer.recipient as usize)
.ok_or_else(|| Error::Invalid(Invalid::FromValidatorUnknown(transfer.recipient)))?;
// Safely determine `amount + fee`. // Safely determine `amount + fee`.
let total_amount = transfer let total_amount = transfer
.amount .amount
@ -62,16 +66,19 @@ fn verify_transfer_parametric<T: EthSpec>(
Invalid::FromBalanceInsufficient(transfer.amount, sender_balance) Invalid::FromBalanceInsufficient(transfer.amount, sender_balance)
); );
// Verify balances are not "dust" (i.e., greater than zero but less than the minimum deposit // Verify sender balance will not be "dust" (i.e., greater than zero but less than the minimum deposit
// amount). // amount).
verify!( verify!(
time_independent_only time_independent_only
|| (sender_balance == total_amount) || (sender_balance == total_amount)
|| (sender_balance >= (total_amount + spec.min_deposit_amount)), || (sender_balance >= (total_amount + spec.min_deposit_amount)),
Invalid::InvalidResultingFromBalance( Invalid::SenderDust(sender_balance - total_amount, spec.min_deposit_amount)
sender_balance - total_amount, );
spec.min_deposit_amount
) // Verify the recipient balance will not be dust.
verify!(
time_independent_only || ((recipient_balance + transfer.amount) >= spec.min_deposit_amount),
Invalid::RecipientDust(sender_balance - total_amount, spec.min_deposit_amount)
); );
// If loosely enforcing `transfer.slot`, ensure the slot is not in the past. Otherwise, ensure // If loosely enforcing `transfer.slot`, ensure the slot is not in the past. Otherwise, ensure