Skip to content

Commit

Permalink
Prevent the backdating of transparent inputs. Be more liberal and all…
Browse files Browse the repository at this point in the history
…ow the unshielding of unepoched assets in any epoch.
  • Loading branch information
murisi committed Jan 15, 2024
1 parent 9a346cb commit 5d8ed90
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 41 deletions.
20 changes: 8 additions & 12 deletions core/src/ledger/masp_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,6 @@ where
Ok((noterized_inflation, precision))
}

// Safely sum a pair of amounts
#[cfg(any(feature = "wasm-runtime", test))]
fn sum_pair(pair: (token::Amount, token::Amount)) -> Option<token::Amount> {
pair.0.checked_add(pair.1)
}

// This is only enabled when "wasm-runtime" is on, because we're using rayon
#[cfg(any(feature = "wasm-runtime", test))]
/// Update the MASP's allowed conversions
Expand Down Expand Up @@ -341,12 +335,14 @@ where
if denom == MaspDenom::Three {
// The reward for each reward.1 units of the current asset
// is reward.0 units of the reward token
total_reward += sum_pair(
addr_bal * (new_normed_inflation, *normed_inflation),
)
.unwrap_or(token::Amount::max())
.checked_sub(addr_bal)
.unwrap_or_default();
let native_reward =
addr_bal * (new_normed_inflation, *normed_inflation);
total_reward += native_reward
.0
.checked_add(native_reward.1)
.unwrap_or(token::Amount::max())
.checked_sub(addr_bal)
.unwrap_or_default();
// Save the new normed inflation
*normed_inflation = new_normed_inflation;
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1670,15 +1670,15 @@ impl<U: ShieldedUtils + MaybeSend + MaybeSync> ShieldedContext<U> {
} else {
None
};
// This indicates how much more assets need to be sent to the receiver
// This indicates how many more assets need to be sent to the receiver
// in order to satisfy the requested transfer amount.
let mut rem_amount = amount.amount().raw_amount().0;
// If we are sending to a shielded address, we may need the outgoing
// viewing key in the following computations.
let ovk_opt = spending_key.map(|x| x.expsk.ovk);

// Now handle the outputs of this transaction
// Loop through the value balance components and see how they which
// Loop through the value balance components and see which
// ones can be given to the receiver
for ((asset_type, vbal_token, vbal_denom, vbal_epoch), val) in
value_balance.components()
Expand Down
43 changes: 16 additions & 27 deletions shared/src/ledger/native_vp/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,14 @@ where
return Ok(false);
}
match conversion_state.assets.get(&vin.asset_type) {
// Satisfies 2.
// Satisfies 2. Note how the asset's epoch must be equal to
// the present: users must never be allowed to backdate
// transparent inputs to a transaction for they would then
// be able to claim rewards while locking their assets for
// negligible time periods.
Some(((address, denom), asset_epoch, _, _))
if *address == transfer.token
&& *asset_epoch <= epoch =>
&& *asset_epoch == epoch =>
{
total_in_values += token::Amount::from_masp_denominated(
vin.value, *denom,
Expand Down Expand Up @@ -529,8 +533,8 @@ where
match conversion_state.assets.get(&out.asset_type) {
// Satisfies 2.
Some(((address, denom), asset_epoch, _, _))
if address == &transfer.token
&& asset_epoch <= &epoch =>
if *address == transfer.token
&& *asset_epoch <= epoch =>
{
total_out_values +=
token::Amount::from_masp_denominated(
Expand All @@ -539,29 +543,14 @@ where
}
// Maybe the asset type has no attached epoch
None if unepoched_tokens.contains_key(&out.asset_type) => {
let (token, denom) = &unepoched_tokens[&out.asset_type];
// Determine what the asset type would be if it were
// epoched
let epoched_asset_type =
encode_asset_type(Some(epoch), token, *denom)
.wrap_err("unable to create asset type")?;
if conversion_state
.assets
.contains_key(&epoched_asset_type)
{
// If such an epoched asset type is available in the
// conversion tree, then we must reject the
// unepoched variant
tracing::debug!("epoch is missing from asset type");
return Ok(false);
} else {
// Otherwise note the contribution to this
// trransparent input
total_out_values +=
token::Amount::from_masp_denominated(
out.value, *denom,
);
}
let (_token, denom) =
&unepoched_tokens[&out.asset_type];
// Otherwise note the contribution to this
// trransparent input
total_out_values +=
token::Amount::from_masp_denominated(
out.value, *denom,
);
}
// unrecognized asset
_ => return Ok(false),
Expand Down

0 comments on commit 5d8ed90

Please sign in to comment.