Category: Coding Mistakes
Missing gas charge on memo
in native_nft_transfer
High Severity
High Impact
High Likelihood
Description
The native implementation native_nft_transfer
function in cosmos.rs does not charge gas for the memo
argument.
Impact
In a DOS attack, an attacker can create a transaction with a large memo
field and spam the network with transactions that do not pay the full, appropriate gas fees.
Recommendations
Add the following line to the native_nft_transfer
function in cosmos.rs:
fn native_nft_transfer(
context: &mut SafeNativeContext,
ty_args: Vec<Type>,
mut arguments: VecDeque<Value>,
) -> SafeNativeResult<SmallVec<[Value; 1]>> {
let gas_params = &context.native_gas_params.initia_stdlib.cosmos.nft_transfer;
context.charge(gas_params.base)?;
debug_assert!(ty_args.is_empty());
debug_assert!(arguments.len() == 10);
let memo = safely_pop_arg!(arguments, Vector).to_vec_u8()?;
+ context.charge(gas_params.per_byte * NumBytes::new(memo.len() as u64))?;
let timeout_timestamp = safely_pop_arg!(arguments, u64);
let revision_height = safely_pop_arg!(arguments, u64);
let revision_number = safely_pop_arg!(arguments, u64);
let source_channel = safely_pop_arg!(arguments, Vector).to_vec_u8()?;
context.charge(gas_params.per_byte * NumBytes::new(source_channel.len() as u64))?;
// [...]
}