From 956cb65a6ced56eebb4226c038dc6985006d172a Mon Sep 17 00:00:00 2001 From: chimp1984 Date: Tue, 7 Apr 2020 13:15:25 -0500 Subject: [PATCH] Add BuyerVerifiesDonationAddress task Buyer was not verifying if the donation address is either the default DAO param address or the recent one changed by DAO voting. We do not support past DAO param addresses to avoid that past addresses receive funds. --- .../trade/protocol/BuyerAsMakerProtocol.java | 2 + .../trade/protocol/BuyerAsTakerProtocol.java | 2 + .../buyer/BuyerVerifiesDonationAddress.java | 80 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java index 3234d6d109..7bb9f25cd1 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsMakerProtocol.java @@ -38,6 +38,7 @@ import bisq.core.trade.protocol.tasks.buyer.BuyerSetupPayoutTxListener; import bisq.core.trade.protocol.tasks.buyer.BuyerSignPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDelayedPayoutTx; +import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDonationAddress; import bisq.core.trade.protocol.tasks.buyer_as_maker.BuyerAsMakerCreatesAndSignsDepositTx; import bisq.core.trade.protocol.tasks.buyer_as_maker.BuyerAsMakerSendsInputsForDepositTxResponse; import bisq.core.trade.protocol.tasks.maker.MakerCreateAndSignContract; @@ -154,6 +155,7 @@ public class BuyerAsMakerProtocol extends TradeProtocol implements BuyerProtocol errorMessage -> handleTaskRunnerFault(tradeMessage, errorMessage)); taskRunner.addTasks( BuyerProcessDelayedPayoutTxSignatureRequest.class, + BuyerVerifiesDonationAddress.class, BuyerSignsDelayedPayoutTx.class, BuyerSendsDelayedPayoutTxSignatureResponse.class ); diff --git a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java index fd7d3292d2..c9e41e669a 100644 --- a/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java +++ b/core/src/main/java/bisq/core/trade/protocol/BuyerAsTakerProtocol.java @@ -40,6 +40,7 @@ import bisq.core.trade.protocol.tasks.buyer.BuyerSetupPayoutTxListener; import bisq.core.trade.protocol.tasks.buyer.BuyerSignPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx; import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDelayedPayoutTx; +import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesDonationAddress; import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerCreatesDepositTxInputs; import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSendsDepositTxMessage; import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSignsDepositTx; @@ -177,6 +178,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol errorMessage -> handleTaskRunnerFault(tradeMessage, errorMessage)); taskRunner.addTasks( BuyerProcessDelayedPayoutTxSignatureRequest.class, + BuyerVerifiesDonationAddress.class, BuyerSignsDelayedPayoutTx.class, BuyerSendsDelayedPayoutTxSignatureResponse.class ); diff --git a/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java new file mode 100644 index 0000000000..c9c19ae3d5 --- /dev/null +++ b/core/src/main/java/bisq/core/trade/protocol/tasks/buyer/BuyerVerifiesDonationAddress.java @@ -0,0 +1,80 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.trade.protocol.tasks.buyer; + +import bisq.core.dao.governance.param.Param; +import bisq.core.trade.Trade; +import bisq.core.trade.protocol.tasks.TradeTask; + +import bisq.common.taskrunner.TaskRunner; + +import org.bitcoinj.core.Address; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionOutput; + +import lombok.extern.slf4j.Slf4j; + +import static com.google.common.base.Preconditions.checkNotNull; + +@Slf4j +public class BuyerVerifiesDonationAddress extends TradeTask { + @SuppressWarnings({"unused"}) + public BuyerVerifiesDonationAddress(TaskRunner taskHandler, Trade trade) { + super(taskHandler, trade); + } + + @Override + protected void run() { + try { + runInterceptHook(); + + Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx(), "preparedDelayedPayoutTx must not be null"); + + // Get most recent donation address. + // We do not support past DAO param addresses to avoid that those receive funds (no bond set up anymore). + // Users who have not synced the DAO cannot trade. + String recentDonationAddressString = processModel.getDaoFacade().getParamValue(Param.RECIPIENT_BTC_ADDRESS); + + // In case the seller has deactivated the DAO the default address will be used. + String defaultDonationAddressString = Param.RECIPIENT_BTC_ADDRESS.getDefaultValue(); + + TransactionOutput output = preparedDelayedPayoutTx.getOutput(0); + NetworkParameters params = processModel.getBtcWalletService().getParams(); + Address address = output.getAddressFromP2PKHScript(params); + if (address == null) { + // The donation address can be as well be a multisig address. + address = output.getAddressFromP2SH(params); + checkNotNull(address, "address must not be null"); + } + + String addressAsString = address.toString(); + if (recentDonationAddressString.equals(addressAsString) || + defaultDonationAddressString.equals(addressAsString)) { + complete(); + } else { + failed("Sellers donation address not recognized." + + "\nAddress used by BTC seller: " + addressAsString + + "\nRecent donation address:" + recentDonationAddressString + + "\nDefault donation address: " + defaultDonationAddressString); + } + } catch (Throwable t) { + failed(t); + } + } +}