From 3b8c7a75b1b43ae6cc92e4b148b703b75858f312 Mon Sep 17 00:00:00 2001 From: MrBlackGhostt Date: Wed, 17 Jun 2026 17:54:01 +0530 Subject: [PATCH] docs: explain cast and vault reload safety checks in handle_withdraw --- Cargo.lock | 65 +++++++++++++++++++------ programs/drift/src/instructions/user.rs | 2 + programs/drift/src/math/casting.rs | 9 ++++ 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 737704d4ba..7ad752d969 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aead" @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.9", "once_cell", @@ -51,12 +51,12 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.9", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -1177,13 +1177,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -1192,7 +1204,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -1201,7 +1213,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.12", ] [[package]] @@ -1412,9 +1424,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libsecp256k1" @@ -1978,6 +1990,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "radium" version = "0.7.0" @@ -2466,7 +2484,7 @@ version = "1.16.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7077f6495ccc313dff49c3e3f3ed03e49058258bae7fee77ac29ba0a474ba82" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.12", "blake3", "block-buffer 0.10.4", "bs58 0.4.0", @@ -3152,6 +3170,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.90" @@ -3349,6 +3376,12 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "without-alloc" version = "0.2.1" @@ -3369,18 +3402,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", diff --git a/programs/drift/src/instructions/user.rs b/programs/drift/src/instructions/user.rs index c696c9ea6c..e30501f794 100644 --- a/programs/drift/src/instructions/user.rs +++ b/programs/drift/src/instructions/user.rs @@ -1032,6 +1032,8 @@ pub fn handle_withdraw<'c: 'info, 'info>( // reload the spot market vault balance so it's up-to-date ctx.accounts.spot_market_vault.reload()?; + // Verify that the vault's on-chain token balance matches the protocol's internal ledger. + // If the vault has fewer tokens than expected, it indicates insolvency or a double-spend attempt, and aborts. math::spot_withdraw::validate_spot_market_vault_amount( &spot_market, ctx.accounts.spot_market_vault.amount, diff --git a/programs/drift/src/math/casting.rs b/programs/drift/src/math/casting.rs index 3fe39ae977..5a8d561e27 100644 --- a/programs/drift/src/math/casting.rs +++ b/programs/drift/src/math/casting.rs @@ -4,6 +4,15 @@ use crate::msg; use std::convert::TryInto; use std::panic::Location; +/// A helper trait for safe type casting in the Drift protocol. +/// +/// Rust does not perform implicit type casting, and standard `as` casting +/// (e.g., `x as u64`) can cause silent truncation or overflows if the value +/// is too large or negative. +/// +/// This trait utilizes `try_into()` to safely convert types. If the conversion +/// fails, it logs the exact file and line number of the failure using `#[track_caller]` +/// and returns a `CastingFailure` error instead of panicking. pub trait Cast: Sized { #[track_caller] #[inline(always)]