mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-14 11:26:24 +00:00
Merge pull request #61 from Reckless-Satoshi/upgrade-fee-structure
Upgrade fee structure
This commit is contained in:
commit
9b9b4eaa15
@ -49,10 +49,15 @@ NETWORK = 'testnet'
|
|||||||
NODE_ALIAS = '🤖RoboSats⚡(RoboDevs)'
|
NODE_ALIAS = '🤖RoboSats⚡(RoboDevs)'
|
||||||
NODE_ID = '033b58d7......'
|
NODE_ID = '033b58d7......'
|
||||||
|
|
||||||
# Trade fee in percentage %
|
# Total trade fee as fraction
|
||||||
FEE = 0.002
|
FEE = 0.002
|
||||||
# Bond size in percentage %
|
# Maker/taker fee split. As seen in https://bisq.wiki/Trading_fees . It is implicit that TAKER_FEE_SPLIT = (1 - MAKER_FEE_SPLIT)
|
||||||
|
# Shall incentivize order making
|
||||||
|
MAKER_FEE_SPLIT=0.125
|
||||||
|
|
||||||
|
# Default bond size as fraction
|
||||||
BOND_SIZE = 0.01
|
BOND_SIZE = 0.01
|
||||||
|
|
||||||
# Time out penalty for canceling takers in SECONDS
|
# Time out penalty for canceling takers in SECONDS
|
||||||
PENALTY_TIMEOUT = 60
|
PENALTY_TIMEOUT = 60
|
||||||
# Time between routing attempts of buyer invoice in MINUTES
|
# Time between routing attempts of buyer invoice in MINUTES
|
||||||
|
@ -11,6 +11,8 @@ import math
|
|||||||
import ast
|
import ast
|
||||||
|
|
||||||
FEE = float(config("FEE"))
|
FEE = float(config("FEE"))
|
||||||
|
MAKER_FEE_SPLIT = float(config("MAKER_FEE_SPLIT"))
|
||||||
|
|
||||||
BOND_SIZE = float(config("BOND_SIZE"))
|
BOND_SIZE = float(config("BOND_SIZE"))
|
||||||
ESCROW_USERNAME = config("ESCROW_USERNAME")
|
ESCROW_USERNAME = config("ESCROW_USERNAME")
|
||||||
PENALTY_TIMEOUT = int(config("PENALTY_TIMEOUT"))
|
PENALTY_TIMEOUT = int(config("PENALTY_TIMEOUT"))
|
||||||
@ -375,12 +377,35 @@ class Logics:
|
|||||||
"""Computes buyer invoice amount. Uses order.last_satoshis,
|
"""Computes buyer invoice amount. Uses order.last_satoshis,
|
||||||
that is the final trade amount set at Taker Bond time"""
|
that is the final trade amount set at Taker Bond time"""
|
||||||
|
|
||||||
|
if user == order.maker:
|
||||||
|
fee_fraction = FEE * MAKER_FEE_SPLIT
|
||||||
|
elif user == order.taker:
|
||||||
|
fee_fraction = FEE * (1 - MAKER_FEE_SPLIT)
|
||||||
|
|
||||||
|
fee_sats = order.last_satoshis * fee_fraction
|
||||||
|
|
||||||
if cls.is_buyer(order, user):
|
if cls.is_buyer(order, user):
|
||||||
invoice_amount = int(order.last_satoshis *
|
invoice_amount = round(order.last_satoshis - fee_sats) # Trading fee to buyer is charged here.
|
||||||
(1 - FEE)) # Trading FEE is charged here.
|
|
||||||
|
|
||||||
return True, {"invoice_amount": invoice_amount}
|
return True, {"invoice_amount": invoice_amount}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def escrow_amount(cls, order, user):
|
||||||
|
"""Computes escrow invoice amount. Uses order.last_satoshis,
|
||||||
|
that is the final trade amount set at Taker Bond time"""
|
||||||
|
|
||||||
|
if user == order.maker:
|
||||||
|
fee_fraction = FEE * MAKER_FEE_SPLIT
|
||||||
|
elif user == order.taker:
|
||||||
|
fee_fraction = FEE * (1 - MAKER_FEE_SPLIT)
|
||||||
|
|
||||||
|
fee_sats = order.last_satoshis * fee_fraction
|
||||||
|
|
||||||
|
if cls.is_seller(order, user):
|
||||||
|
escrow_amount = round(order.last_satoshis + fee_sats) # Trading fee to seller is charged here.
|
||||||
|
|
||||||
|
return True, {"escrow_amount": escrow_amount}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_invoice(cls, order, user, invoice):
|
def update_invoice(cls, order, user, invoice):
|
||||||
|
|
||||||
@ -852,8 +877,7 @@ class Logics:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# If there was no taker_bond object yet, generate one
|
# If there was no taker_bond object yet, generate one
|
||||||
escrow_satoshis = (order.last_satoshis
|
escrow_satoshis = cls.escrow_amount(order, user)[1]["escrow_amount"] # Amount was fixed when taker bond was locked, fee applied here
|
||||||
) # Amount was fixed when taker bond was locked
|
|
||||||
description = f"RoboSats - Escrow amount for '{str(order)}' - It WILL FREEZE IN YOUR WALLET. It will be released to the buyer once you confirm you received the fiat. It will automatically return if buyer does not confirm the payment."
|
description = f"RoboSats - Escrow amount for '{str(order)}' - It WILL FREEZE IN YOUR WALLET. It will be released to the buyer once you confirm you received the fiat. It will automatically return if buyer does not confirm the payment."
|
||||||
|
|
||||||
# Gen hold Invoice
|
# Gen hold Invoice
|
||||||
|
@ -28,7 +28,6 @@ from django.conf import settings
|
|||||||
from decouple import config
|
from decouple import config
|
||||||
|
|
||||||
EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE"))
|
EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE"))
|
||||||
FEE = float(config("FEE"))
|
|
||||||
RETRY_TIME = int(config("RETRY_TIME"))
|
RETRY_TIME = int(config("RETRY_TIME"))
|
||||||
|
|
||||||
avatar_path = Path(settings.AVATAR_ROOT)
|
avatar_path = Path(settings.AVATAR_ROOT)
|
||||||
@ -247,7 +246,8 @@ class OrderView(viewsets.ViewSet):
|
|||||||
LNPayment.Status.LOCKED):
|
LNPayment.Status.LOCKED):
|
||||||
# Seller sees the amount he sends
|
# Seller sees the amount he sends
|
||||||
if data["is_seller"]:
|
if data["is_seller"]:
|
||||||
data["trade_satoshis"] = order.last_satoshis
|
data["trade_satoshis"] = Logics.escrow_amount(
|
||||||
|
order, request.user)[1]["escrow_amount"]
|
||||||
# Buyer sees the amount he receives
|
# Buyer sees the amount he receives
|
||||||
elif data["is_buyer"]:
|
elif data["is_buyer"]:
|
||||||
data["trade_satoshis"] = Logics.payout_amount(
|
data["trade_satoshis"] = Logics.payout_amount(
|
||||||
@ -335,7 +335,7 @@ class OrderView(viewsets.ViewSet):
|
|||||||
if order.payout.status == LNPayment.Status.EXPIRE:
|
if order.payout.status == LNPayment.Status.EXPIRE:
|
||||||
data["invoice_expired"] = True
|
data["invoice_expired"] = True
|
||||||
# Add invoice amount once again if invoice was expired.
|
# Add invoice amount once again if invoice was expired.
|
||||||
data["invoice_amount"] = int(order.last_satoshis * (1 - FEE))
|
data["invoice_amount"] = Logics.payout_amount(order,request.user)[1]["invoice_amount"]
|
||||||
|
|
||||||
return Response(data, status.HTTP_200_OK)
|
return Response(data, status.HTTP_200_OK)
|
||||||
|
|
||||||
@ -676,7 +676,8 @@ class InfoView(ListAPIView):
|
|||||||
context["node_alias"] = config("NODE_ALIAS")
|
context["node_alias"] = config("NODE_ALIAS")
|
||||||
context["node_id"] = config("NODE_ID")
|
context["node_id"] = config("NODE_ID")
|
||||||
context["network"] = config("NETWORK")
|
context["network"] = config("NETWORK")
|
||||||
context["fee"] = FEE
|
context["maker_fee"] = float(config("FEE"))*float(config("MAKER_FEE_SPLIT"))
|
||||||
|
context["taker_fee"] = float(config("FEE"))*(1 - float(config("MAKER_FEE_SPLIT")))
|
||||||
context["bond_size"] = float(config("BOND_SIZE"))
|
context["bond_size"] = float(config("BOND_SIZE"))
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
context["nickname"] = request.user.username
|
context["nickname"] = request.user.username
|
||||||
|
@ -39,7 +39,8 @@ export default class BottomBar extends Component {
|
|||||||
num_public_buy_orders: 0,
|
num_public_buy_orders: 0,
|
||||||
num_public_sell_orders: 0,
|
num_public_sell_orders: 0,
|
||||||
active_robots_today: 0,
|
active_robots_today: 0,
|
||||||
fee: 0,
|
maker_fee: 0,
|
||||||
|
taker_fee: 0,
|
||||||
today_avg_nonkyc_btc_premium: 0,
|
today_avg_nonkyc_btc_premium: 0,
|
||||||
today_volume: 0,
|
today_volume: 0,
|
||||||
lifetime_volume: 0,
|
lifetime_volume: 0,
|
||||||
@ -294,6 +295,7 @@ bottomBarDesktop =()=>{
|
|||||||
<this.StatsDialog/>
|
<this.StatsDialog/>
|
||||||
<this.CommunityDialog/>
|
<this.CommunityDialog/>
|
||||||
<this.dialogProfile/>
|
<this.dialogProfile/>
|
||||||
|
<this.exchangeSummaryDialog/>
|
||||||
<Grid container xs={12}>
|
<Grid container xs={12}>
|
||||||
|
|
||||||
<Grid item xs={1.9}>
|
<Grid item xs={1.9}>
|
||||||
@ -321,7 +323,7 @@ bottomBarDesktop =()=>{
|
|||||||
<Grid item xs={1.9}>
|
<Grid item xs={1.9}>
|
||||||
<ListItem className="bottomItem">
|
<ListItem className="bottomItem">
|
||||||
<ListItemIcon size="small">
|
<ListItemIcon size="small">
|
||||||
<InventoryIcon/>
|
<IconButton onClick={this.handleClickOpenExchangeSummary}><InventoryIcon/></IconButton>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{fontSize: '14px'}}
|
||||||
@ -334,7 +336,7 @@ bottomBarDesktop =()=>{
|
|||||||
<Grid item xs={1.9}>
|
<Grid item xs={1.9}>
|
||||||
<ListItem className="bottomItem">
|
<ListItem className="bottomItem">
|
||||||
<ListItemIcon size="small">
|
<ListItemIcon size="small">
|
||||||
<SellIcon/>
|
<IconButton onClick={this.handleClickOpenExchangeSummary}><SellIcon/></IconButton>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{fontSize: '14px'}}
|
||||||
@ -347,7 +349,7 @@ bottomBarDesktop =()=>{
|
|||||||
<Grid item xs={1.9}>
|
<Grid item xs={1.9}>
|
||||||
<ListItem className="bottomItem">
|
<ListItem className="bottomItem">
|
||||||
<ListItemIcon size="small">
|
<ListItemIcon size="small">
|
||||||
<SmartToyIcon/>
|
<IconButton onClick={this.handleClickOpenExchangeSummary}><SmartToyIcon/></IconButton>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{fontSize: '14px'}}
|
||||||
@ -360,7 +362,7 @@ bottomBarDesktop =()=>{
|
|||||||
<Grid item xs={1.9}>
|
<Grid item xs={1.9}>
|
||||||
<ListItem className="bottomItem">
|
<ListItem className="bottomItem">
|
||||||
<ListItemIcon size="small">
|
<ListItemIcon size="small">
|
||||||
<PriceChangeIcon/>
|
<IconButton onClick={this.handleClickOpenExchangeSummary}><PriceChangeIcon/></IconButton>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{fontSize: '14px'}}
|
||||||
@ -373,12 +375,12 @@ bottomBarDesktop =()=>{
|
|||||||
<Grid item xs={1.5}>
|
<Grid item xs={1.5}>
|
||||||
<ListItem className="bottomItem">
|
<ListItem className="bottomItem">
|
||||||
<ListItemIcon size="small">
|
<ListItemIcon size="small">
|
||||||
<PercentIcon/>
|
< IconButton onClick={this.handleClickOpenExchangeSummary}><PercentIcon/></IconButton>
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{fontSize: '14px'}}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{fontSize: '12px'}}
|
||||||
primary={this.state.fee*100+"% (buyer)"}
|
primary={(this.state.maker_fee + this.state.taker_fee)*100}
|
||||||
secondary="Trade Fee" />
|
secondary="Trade Fee" />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -428,7 +430,7 @@ bottomBarDesktop =()=>{
|
|||||||
this.setState({openExchangeSummary: false});
|
this.setState({openExchangeSummary: false});
|
||||||
};
|
};
|
||||||
|
|
||||||
exchangeSummaryDialogPhone =() =>{
|
exchangeSummaryDialog =() =>{
|
||||||
return(
|
return(
|
||||||
<Dialog
|
<Dialog
|
||||||
open={this.state.openExchangeSummary}
|
open={this.state.openExchangeSummary}
|
||||||
@ -495,7 +497,7 @@ bottomBarDesktop =()=>{
|
|||||||
primaryTypographyProps={{fontSize: '14px'}}
|
primaryTypographyProps={{fontSize: '14px'}}
|
||||||
secondaryTypographyProps={{fontSize: '12px'}}
|
secondaryTypographyProps={{fontSize: '12px'}}
|
||||||
secondary="Trading fees">
|
secondary="Trading fees">
|
||||||
{this.state.fee*100}% <small>(buyer)</small> | 0.0% <small>(seller)</small>
|
{(this.state.maker_fee*100).toFixed(3)}% <small>(maker)</small> | {(this.state.taker_fee*100).toFixed(3)}% <small>(taker)</small>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
@ -510,7 +512,7 @@ bottomBarPhone =()=>{
|
|||||||
<Paper elevation={6} style={{height:40}}>
|
<Paper elevation={6} style={{height:40}}>
|
||||||
<this.StatsDialog/>
|
<this.StatsDialog/>
|
||||||
<this.CommunityDialog/>
|
<this.CommunityDialog/>
|
||||||
<this.exchangeSummaryDialogPhone/>
|
<this.exchangeSummaryDialog/>
|
||||||
<this.dialogProfile/>
|
<this.dialogProfile/>
|
||||||
<Grid container xs={12}>
|
<Grid container xs={12}>
|
||||||
|
|
||||||
|
@ -920,6 +920,8 @@ handleRatingRobosatsChange=(e)=>{
|
|||||||
style: {textAlign:"center"}
|
style: {textAlign:"center"}
|
||||||
}}
|
}}
|
||||||
multiline
|
multiline
|
||||||
|
minRows={4}
|
||||||
|
maxRows={8}
|
||||||
onChange={this.handleInputInvoiceChanged}
|
onChange={this.handleInputInvoiceChanged}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user