simplewallet: reject donations when not on mainnet
What changed, and why it matters
This change stops the Monero command-line wallet's built-in 'donate' command from working on test networks. Previously, the wallet tried to convert the official donation address to a testnet/stagenet equivalent, which could send real-looking donations to an address the user did not expect. Now it simply refuses to donate unless you are on the main Monero network.
No immediate action beyond applying the patch is needed. Users who previously ran 'donate' on testnet/stagenet should be aware that any funds sent to the converted address are likely unrecoverable. Consider documenting this behavior change in release notes.
Security signals we found
Funds-loss risk from address nettype mismatch
Removal of automatic address conversion for alternate networks
Hardcoded mainnet donation address used unconditionally
Evidence from the diff
The patch removes address-conversion logic in simple_wallet::donate() for non-MAINNET networks. Before, on testnet/stagenet the code parsed the hardcoded MONERO_DONATION_ADDR (a mainnet address), re-encoded it for the current nettype, and sent funds there. That conversion produces a valid address for the alternate network, but not one controlled by the Monero Project, so any coins sent via the donate command on a test network would be unrecoverable by the intended recipient. The new code rejects the command outright on non-mainnet networks.
Changed components
src/simplewallet/simplewallet.cppsimple_wallet::donate()CLI wallet donation commandInspect captured patch +4 / −18
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 066c1d1..5f43da3 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -7427,28 +7427,14 @@ bool simple_wallet::donate(const std::vector<std::string> &args_)
return true;
}
// push back address, amount
- std::string address_str;
if (m_wallet->nettype() != cryptonote::MAINNET)
{
- // if not mainnet, convert donation address string to the relevant network type
- address_parse_info info;
- if (!cryptonote::get_account_address_from_str(info, cryptonote::MAINNET, MONERO_DONATION_ADDR))
- {
- fail_msg_writer() << tr("Failed to parse donation address: ") << MONERO_DONATION_ADDR;
- return true;
- }
- address_str = cryptonote::get_account_address_as_str(m_wallet->nettype(), info.is_subaddress, info.address);
- }
- else
- {
- address_str = MONERO_DONATION_ADDR;
+ fail_msg_writer() << tr("Donations are supported on mainnet only.");
+ return true;
}
- local_args.push_back(address_str);
+ local_args.push_back(MONERO_DONATION_ADDR);
local_args.push_back(amount_str);
- if (m_wallet->nettype() == cryptonote::MAINNET)
- message_writer() << (boost::format(tr("Donating %s %s to The Monero Project (donate.getmonero.org or %s).")) % amount_str % cryptonote::get_unit(cryptonote::get_default_decimal_point()) % MONERO_DONATION_ADDR).str();
- else
- message_writer() << (boost::format(tr("Donating %s %s to %s.")) % amount_str % cryptonote::get_unit(cryptonote::get_default_decimal_point()) % address_str).str();
+ message_writer() << (boost::format(tr("Donating %s %s to The Monero Project (donate.getmonero.org or %s).")) % amount_str % cryptonote::get_unit(cryptonote::get_default_decimal_point()) % MONERO_DONATION_ADDR).str();
transfer(local_args);
return true;
}
Why this scored 32/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.