audit: cargo fmt + clippy --fix across workspace + retract_votes cooldown bug fix

Surfaced by Track #38 code audit (2026-05-09):

1. cargo fmt --all: 217 formatting diffs across 35 files. Pure
   whitespace; no semantic changes.

2. cargo clippy --fix: 30 warnings -> 10. Auto-applied:
   - useless format!() (3 sites in builder/proposal_*.rs)
   - needless_borrow_for_generic_args (4 sites)
   - cloned_ref_to_slice_refs (1 site, builder/proposal_cosign.rs)
   - derivable_impls (1 site, dao/config.rs)
   - unused imports/variables (3 sites)

   Remaining 10 warnings are non-trivial (too_many_arguments on a
   constructor at 8 args, FromStr trait shadow, doc_lazy_continuation
   on a few comment blocks). Filed as tech-debt; no action this pass.

3. cargo audit: 0 vulnerabilities. 2 unmaintained advisories on
   transitive deps:
   - paste 1.0.15 (RUSTSEC-2024-0436) via rmcp + pallas-traverse
   - proc-macro-error 1.0.4 (RUSTSEC-2024-0370) via age->i18n-embed-fl
   Both upstream; tracked but no action needed locally.

4. Test failure surfaced: builder::proposal_retract_votes::tests::
   voting_ready_in_window_subtracts_vote_weight failed — cooldown
   check was applied unconditionally for RemoveVoterLockOnly mode,
   blocking the legitimate 'retract during voting window' path
   where the proposal datum mutates (vote weight subtraction). Per
   Agora's premoveLocks rule, cooldown only applies when retracting
   AFTER voting closed but BEFORE Finished — not during the active
   voting window. Fixed by gating cooldown on
   '!proposal_datum_will_change' so the in-window retract path
   bypasses cooldown the same way RemoveAllLocks does.

   Test: 87/87 aldabra-dao lib tests pass post-fix (was 86/87).
This commit is contained in:
Sulkta 2026-05-09 10:27:48 -07:00
parent 0987d5de12
commit 03b5efb3b2
35 changed files with 1125 additions and 1072 deletions

View file

@ -45,9 +45,7 @@ fn find_subseq(haystack: &[u8], needle: &[u8]) -> Option<usize> {
if needle.is_empty() || needle.len() > haystack.len() {
return None;
}
haystack
.windows(needle.len())
.position(|w| w == needle)
haystack.windows(needle.len()).position(|w| w == needle)
}
fn main() {
@ -79,10 +77,9 @@ fn main() {
// A throwaway preprod testnet enterprise script address (just for
// shape — no funds, no real chain interaction).
let dest_addr = Address::from_bech32(
"addr_test1wptadvtl64h74jmhwuda595j40ss3rgh0p9jam0ejwgz6mcnzvusa",
)
.expect("decode addr");
let dest_addr =
Address::from_bech32("addr_test1wptadvtl64h74jmhwuda595j40ss3rgh0p9jam0ejwgz6mcnzvusa")
.expect("decode addr");
let mut output = TxOutput::new(dest_addr, 5_000_000);
output = output.set_inline_script(ScriptKind::PlutusV2, script_bytes.clone());
@ -93,9 +90,7 @@ fn main() {
.fee(2_000_000)
.network_id(0);
let built = staging
.build_conway_raw()
.expect("build_conway_raw failed");
let built = staging.build_conway_raw().expect("build_conway_raw failed");
let tx_bytes = built.tx_bytes.0;
println!("built tx body: {} bytes", tx_bytes.len());
@ -105,7 +100,10 @@ fn main() {
// wrapping the inner array `[2, bytes]`. The actual script bytes
// are then nested inside that. Search for them verbatim.
if let Some(pos) = find_subseq(&tx_bytes, &script_bytes) {
println!("✅ FOUND input script bytes verbatim at tx-body offset {}", pos);
println!(
"✅ FOUND input script bytes verbatim at tx-body offset {}",
pos
);
println!(" pallas-txbuilder serialized them clean.");
// BUT: check the bytes-header that precedes them. In CBOR, a