withdraw(address target) pays out the entire contract balance with Solidity’s transfer(), which:
Forwards only 2 300 gas → reverts for most multisig / module wallets.
Has become fragile after EIP-1884; even EOAs wrapped in smart-accounts can fail.
Lacks target != address(0) guard — ETH can be burned.
Result: Festival revenue can be stuck or burned, blocking withdrawals until a contract upgrade or redeploy.
Likelihood:
Organizers typically route funds to Gnosis Safes or payment-splitter contracts that need >2 300 gas → call reverts.
Impact:
ETH locked in FestivalPass. Operational disruption during event. Potential permanent loss if zero address supplied.
The PoC spins up an ExpensiveReceiver whose receive() deliberately uses > 2 300 gas. When withdraw() attempts to pay this address the call reverts, proving that the current transfer()based implementation can lock funds.
Switching to a low-level call forwards all remaining gas, checks success, and blocks the zero-address. This makes withdrawals compatible with multisigs and smart-account wallets and removes the 2 300 gas fragility.
Owner/admin is trusted / Zero address check - Informational
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.