mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-30 18:28:52 -04:00
Add check at offerer for trade price
This commit is contained in:
parent
261a037020
commit
461aa9bd7f
8 changed files with 50 additions and 17 deletions
|
@ -68,7 +68,6 @@ public class ProcessModel implements Model, Serializable {
|
||||||
transient private KeyRing keyRing;
|
transient private KeyRing keyRing;
|
||||||
transient private P2PService p2PService;
|
transient private P2PService p2PService;
|
||||||
|
|
||||||
|
|
||||||
// Mutable
|
// Mutable
|
||||||
public final TradingPeer tradingPeer;
|
public final TradingPeer tradingPeer;
|
||||||
transient private TradeMessage tradeMessage;
|
transient private TradeMessage tradeMessage;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
|
import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
|
||||||
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
|
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.utils.Fiat;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -76,8 +77,27 @@ public class ProcessPayDepositRequest extends TradeTask {
|
||||||
if (payDepositRequest.acceptedArbitratorNodeAddresses.size() < 1)
|
if (payDepositRequest.acceptedArbitratorNodeAddresses.size() < 1)
|
||||||
failed("acceptedArbitratorNames size must be at least 1");
|
failed("acceptedArbitratorNames size must be at least 1");
|
||||||
trade.setArbitratorNodeAddress(checkNotNull(payDepositRequest.arbitratorNodeAddress));
|
trade.setArbitratorNodeAddress(checkNotNull(payDepositRequest.arbitratorNodeAddress));
|
||||||
|
|
||||||
|
long takersTradePrice = payDepositRequest.tradePrice;
|
||||||
|
checkArgument(takersTradePrice > 0);
|
||||||
|
Fiat tradePriceAsFiat = Fiat.valueOf(trade.getOffer().getCurrencyCode(), takersTradePrice);
|
||||||
|
Fiat offerPriceAsFiat = trade.getOffer().getPrice();
|
||||||
|
double factor = (double) takersTradePrice / (double) offerPriceAsFiat.value;
|
||||||
|
// We allow max. 2 % difference between own offer price calculation and takers calculation.
|
||||||
|
// Market price might be different at offerers and takers side so we need a bit of tolerance.
|
||||||
|
// The tolerance will get smaller once we have multiple price feeds avoiding fast price fluctuations
|
||||||
|
// from one provider.
|
||||||
|
if (Math.abs(1 - factor) > 0.02) {
|
||||||
|
String msg = "Takers tradePrice is outside our market price tolerance.\n" +
|
||||||
|
"tradePriceAsFiat=" + tradePriceAsFiat.toFriendlyString() + "\n" +
|
||||||
|
"offerPriceAsFiat=" + offerPriceAsFiat.toFriendlyString();
|
||||||
|
log.warn(msg);
|
||||||
|
failed(msg);
|
||||||
|
}
|
||||||
|
trade.setTradePrice(takersTradePrice);
|
||||||
|
|
||||||
|
|
||||||
checkArgument(payDepositRequest.tradeAmount > 0);
|
checkArgument(payDepositRequest.tradeAmount > 0);
|
||||||
trade.setTradePrice(payDepositRequest.tradePrice);
|
|
||||||
trade.setTradeAmount(Coin.valueOf(payDepositRequest.tradeAmount));
|
trade.setTradeAmount(Coin.valueOf(payDepositRequest.tradeAmount));
|
||||||
|
|
||||||
// update to the latest peer address of our peer if the payDepositRequest is correct
|
// update to the latest peer address of our peer if the payDepositRequest is correct
|
||||||
|
|
|
@ -110,6 +110,7 @@ public final class Preferences implements Persistable {
|
||||||
private double maxPriceDistanceInPercent;
|
private double maxPriceDistanceInPercent;
|
||||||
private boolean useInvertedMarketPrice;
|
private boolean useInvertedMarketPrice;
|
||||||
private boolean useStickyMarketPrice = false;
|
private boolean useStickyMarketPrice = false;
|
||||||
|
private boolean usePercentageBasedPrice = false;
|
||||||
|
|
||||||
// Observable wrappers
|
// Observable wrappers
|
||||||
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
|
||||||
|
@ -162,6 +163,7 @@ public final class Preferences implements Persistable {
|
||||||
// useTorForBitcoinJ = persisted.getUseTorForBitcoinJ();
|
// useTorForBitcoinJ = persisted.getUseTorForBitcoinJ();
|
||||||
useTorForBitcoinJ = false;
|
useTorForBitcoinJ = false;
|
||||||
useStickyMarketPrice = persisted.getUseStickyMarketPrice();
|
useStickyMarketPrice = persisted.getUseStickyMarketPrice();
|
||||||
|
usePercentageBasedPrice = persisted.getUsePercentageBasedPrice();
|
||||||
showOwnOffersInOfferBook = persisted.getShowOwnOffersInOfferBook();
|
showOwnOffersInOfferBook = persisted.getShowOwnOffersInOfferBook();
|
||||||
maxPriceDistanceInPercent = persisted.getMaxPriceDistanceInPercent();
|
maxPriceDistanceInPercent = persisted.getMaxPriceDistanceInPercent();
|
||||||
// Backward compatible to version 0.3.6. Can be removed after a while
|
// Backward compatible to version 0.3.6. Can be removed after a while
|
||||||
|
@ -368,6 +370,12 @@ public final class Preferences implements Persistable {
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUsePercentageBasedPrice(boolean usePercentageBasedPrice) {
|
||||||
|
this.usePercentageBasedPrice = usePercentageBasedPrice;
|
||||||
|
storage.queueUpForSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getter
|
// Getter
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -488,6 +496,10 @@ public final class Preferences implements Persistable {
|
||||||
return useStickyMarketPrice;
|
return useStickyMarketPrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getUsePercentageBasedPrice() {
|
||||||
|
return usePercentageBasedPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Private
|
// Private
|
||||||
|
|
|
@ -76,7 +76,7 @@ import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY;
|
||||||
public class BitsquareApp extends Application {
|
public class BitsquareApp extends Application {
|
||||||
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
|
||||||
|
|
||||||
public static final boolean DEV_MODE = false;
|
public static final boolean DEV_MODE = true;
|
||||||
public static final boolean IS_RELEASE_VERSION = !DEV_MODE && true;
|
public static final boolean IS_RELEASE_VERSION = !DEV_MODE && true;
|
||||||
|
|
||||||
private static Environment env;
|
private static Environment env;
|
||||||
|
|
|
@ -497,7 +497,11 @@ public class MainViewModel implements ViewModel {
|
||||||
setupBtcNumPeersWatcher();
|
setupBtcNumPeersWatcher();
|
||||||
setupP2PNumPeersWatcher();
|
setupP2PNumPeersWatcher();
|
||||||
updateBalance();
|
updateBalance();
|
||||||
|
if (BitsquareApp.DEV_MODE) {
|
||||||
|
preferences.setShowOwnOffersInOfferBook(true);
|
||||||
|
if (user.getPaymentAccounts().isEmpty())
|
||||||
setupDevDummyPaymentAccount();
|
setupDevDummyPaymentAccount();
|
||||||
|
}
|
||||||
setupMarketPriceFeed();
|
setupMarketPriceFeed();
|
||||||
swapPendingOfferFundingEntries();
|
swapPendingOfferFundingEntries();
|
||||||
fillPriceFeedComboBoxItems();
|
fillPriceFeedComboBoxItems();
|
||||||
|
@ -896,7 +900,6 @@ public class MainViewModel implements ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupDevDummyPaymentAccount() {
|
private void setupDevDummyPaymentAccount() {
|
||||||
if (BitsquareApp.DEV_MODE && user.getPaymentAccounts().isEmpty()) {
|
|
||||||
OKPayAccount okPayAccount = new OKPayAccount();
|
OKPayAccount okPayAccount = new OKPayAccount();
|
||||||
okPayAccount.setAccountNr("dummy");
|
okPayAccount.setAccountNr("dummy");
|
||||||
okPayAccount.setAccountName("OKPay dummy");
|
okPayAccount.setAccountName("OKPay dummy");
|
||||||
|
@ -904,4 +907,3 @@ public class MainViewModel implements ViewModel {
|
||||||
user.addPaymentAccount(okPayAccount);
|
user.addPaymentAccount(okPayAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||||
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
|
networkFeeAsCoin = FeePolicy.getFixedTxFeeForTrades();
|
||||||
securityDepositAsCoin = FeePolicy.getSecurityDeposit();
|
securityDepositAsCoin = FeePolicy.getSecurityDeposit();
|
||||||
|
|
||||||
|
usePercentageBasedPrice.set(preferences.getUsePercentageBasedPrice());
|
||||||
|
|
||||||
balanceListener = new BalanceListener(getAddressEntry().getAddress()) {
|
balanceListener = new BalanceListener(getAddressEntry().getAddress()) {
|
||||||
@Override
|
@Override
|
||||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||||
|
@ -282,9 +284,6 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||||
String countryCode = paymentAccount instanceof CountryBasedPaymentAccount ? ((CountryBasedPaymentAccount) paymentAccount).getCountry().code : null;
|
String countryCode = paymentAccount instanceof CountryBasedPaymentAccount ? ((CountryBasedPaymentAccount) paymentAccount).getCountry().code : null;
|
||||||
|
|
||||||
checkNotNull(p2PService.getAddress(), "Address must not be null");
|
checkNotNull(p2PService.getAddress(), "Address must not be null");
|
||||||
log.error("fiatPrice " + fiatPrice);
|
|
||||||
log.error("percentageBasedPrice " + percentageBasedPrice);
|
|
||||||
log.error("usePercentageBasedPrice " + usePercentageBasedPrice.get());
|
|
||||||
return new Offer(offerId,
|
return new Offer(offerId,
|
||||||
p2PService.getAddress(),
|
p2PService.getAddress(),
|
||||||
keyRing.getPubKeyRing(),
|
keyRing.getPubKeyRing(),
|
||||||
|
@ -389,6 +388,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||||
|
|
||||||
public void setUsePercentageBasedPrice(boolean usePercentageBasedPrice) {
|
public void setUsePercentageBasedPrice(boolean usePercentageBasedPrice) {
|
||||||
this.usePercentageBasedPrice.set(usePercentageBasedPrice);
|
this.usePercentageBasedPrice.set(usePercentageBasedPrice);
|
||||||
|
preferences.setUsePercentageBasedPrice(usePercentageBasedPrice);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*boolean isFeeFromFundingTxSufficient() {
|
/*boolean isFeeFromFundingTxSufficient() {
|
||||||
|
|
|
@ -989,7 +989,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
VBox priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
|
VBox priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
|
||||||
|
|
||||||
priceAsPercentageTextField.setPromptText("Enter % value");
|
priceAsPercentageTextField.setPromptText("Enter % value");
|
||||||
priceAsPercentageLabel.setText("% dist.");
|
priceAsPercentageLabel.setText("%");
|
||||||
priceAsPercentageLabel.setStyle("-fx-alignment: center;");
|
priceAsPercentageLabel.setStyle("-fx-alignment: center;");
|
||||||
|
|
||||||
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getValueCurrencyBox(BSResources.get("createOffer.amount.prompt"));
|
Tuple3<HBox, InputTextField, Label> amountValueCurrencyBoxTuple = getValueCurrencyBox(BSResources.get("createOffer.amount.prompt"));
|
||||||
|
|
|
@ -855,7 +855,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
|
priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
|
||||||
|
|
||||||
priceAsPercentageTextField.setPromptText("Enter % value");
|
priceAsPercentageTextField.setPromptText("Enter % value");
|
||||||
priceAsPercentageLabel.setText("% dist.");
|
priceAsPercentageLabel.setText("%");
|
||||||
priceAsPercentageLabel.setStyle("-fx-alignment: center;");
|
priceAsPercentageLabel.setStyle("-fx-alignment: center;");
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue