Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ packages:
interfaces:
PeginQuoteRepository:
PegoutQuoteRepository:
PegConfiguration:
github.com/rsksmart/liquidity-provider-server/internal/entities/blockchain:
interfaces:
BitcoinWallet:
Expand Down
38 changes: 36 additions & 2 deletions internal/entities/quote/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"github.com/rsksmart/liquidity-provider-server/internal/entities"
"github.com/rsksmart/liquidity-provider-server/internal/entities/utils"
log "github.com/sirupsen/logrus"
"math/big"
)

type AcceptedQuote struct {
Expand Down Expand Up @@ -44,6 +46,38 @@ func ValidateQuoteHash(hash string) error {
}

func CalculateCallFee(amount *entities.Wei, config PegConfiguration) *entities.Wei {
// TODO implement in GBI-2528
return entities.NewWei(100000000000)
result := new(entities.Wei)

percentageFee := calculatePercentageFee(amount, config.GetFeePercentage())
result.Add(percentageFee, config.GetFixedFee())

log.Debugf("Percentage fee: %v%% of %v = %v", config.GetFeePercentage(), amount, percentageFee)
log.Debugf("Fixed fee: %v", config.GetFixedFee())
log.Debugf("Call fee: %v + %v = %v", percentageFee, config.GetFixedFee(), result)
return result
}

func calculatePercentageFee(amount *entities.Wei, percentage *utils.BigFloat) *entities.Wei {
const scale = 1000 // the scale needs to have at least as many zeros as the amount of decimals we want to support in the percentage
amountAsRat := new(big.Rat).SetInt(amount.AsBigInt())
floatPercentage, _ := percentage.Native().Float64()

percentageAsFraction := new(big.Rat).SetFrac(
big.NewInt(int64(floatPercentage*scale)), // Scale to avoid precision loss
big.NewInt(100*scale),
)
percentageFee := new(big.Rat).Mul(amountAsRat, percentageAsFraction)

remainder := new(big.Int)
result, _ := new(big.Int).QuoRem(
percentageFee.Num(),
percentageFee.Denom(),
remainder,
)

// if remainder is more than half denominator round up
if new(big.Int).Mul(remainder, big.NewInt(2)).Cmp(percentageFee.Denom()) >= 0 {
result.Add(result, big.NewInt(1))
}
return entities.NewBigWei(result)
}
81 changes: 81 additions & 0 deletions internal/entities/quote/common_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package quote_test

import (
"github.com/rsksmart/liquidity-provider-server/internal/entities"
"github.com/rsksmart/liquidity-provider-server/internal/entities/utils"
"github.com/rsksmart/liquidity-provider-server/test/mocks"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"testing"

"github.com/rsksmart/liquidity-provider-server/internal/entities/quote"
Expand Down Expand Up @@ -48,3 +53,79 @@ func TestValidateQuoteHash(t *testing.T) {
})
}
}

// nolint:funlen
func TestCalculateCallFee(t *testing.T) {
type testArgs struct {
amount *entities.Wei
feePercentage *utils.BigFloat
fixedFee *entities.Wei
result *entities.Wei
}
testCases := []testArgs{
{
amount: entities.NewWei(5000000000000000),
feePercentage: utils.NewBigFloat64(0),
fixedFee: entities.NewWei(100000000000000),
result: entities.NewWei(100000000000000),
},
{
amount: entities.NewWei(5000000000000000),
feePercentage: utils.NewBigFloat64(0.33),
fixedFee: entities.NewWei(0),
result: entities.NewWei(16500000000000),
},
{
amount: entities.NewWei(5000000000000000),
feePercentage: utils.NewBigFloat64(0),
fixedFee: entities.NewWei(0),
result: entities.NewWei(0),
},
{
amount: entities.NewWei(5000000000000000),
feePercentage: utils.NewBigFloat64(5.12),
fixedFee: entities.NewWei(123456789),
result: entities.NewWei(256000123456789),
},
{
amount: entities.NewWei(7777777777777777789),
feePercentage: utils.NewBigFloat64(77.33),
fixedFee: entities.NewWei(0),
result: entities.NewWei(6014555555555555564),
},
{
amount: entities.NewWei(7777777777777777789),
feePercentage: utils.NewBigFloat64(77.44),
fixedFee: entities.NewWei(0),
result: entities.NewWei(6023111111111111120),
},
{
amount: entities.NewWei(7777777777777777789),
feePercentage: utils.NewBigFloat64(77.41),
fixedFee: entities.NewWei(0),
result: entities.NewWei(6020777777777777786),
},
{
amount: entities.NewWei(7777777777777777789),
feePercentage: utils.NewBigFloat64(77.86),
fixedFee: entities.NewWei(0),
result: entities.NewWei(6055777777777777787),
},
{
amount: entities.NewWei(7777777777777777789),
feePercentage: utils.NewBigFloat64(77.7),
fixedFee: entities.NewWei(1110000031224),
result: entities.NewWei(6043334443333364566),
},
}
log.SetLevel(log.DebugLevel)
for _, tt := range testCases {
config := &mocks.PegConfigurationMock{}
config.EXPECT().GetFeePercentage().Return(tt.feePercentage)
config.EXPECT().GetFixedFee().Return(tt.fixedFee)

result := quote.CalculateCallFee(tt.amount, config)
assert.Equal(t, tt.result, result, "Expected %v, got %v", tt.result, result)
config.AssertExpectations(t)
}
}
2 changes: 1 addition & 1 deletion internal/entities/quote/pegin_quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type CreatedPeginQuote struct {

type PeginCreationData struct {
GasPrice *entities.Wei `json:"gasPrice" bson:"gas_price" validate:"required"`
FeePercentage *utils.BigFloat `json:"percentageFee" bson:"percentage_fee" validate:"required"`
FeePercentage *utils.BigFloat `json:"feePercentage" bson:"percentage_fee" validate:"required"`
FixedFee *entities.Wei `json:"fixedFee" bson:"fixed_fee" validate:"required"`
}

Expand Down
2 changes: 1 addition & 1 deletion internal/entities/quote/pegout_quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type CreatedPegoutQuote struct {

type PegoutCreationData struct {
FeeRate *utils.BigFloat `json:"feeRate" bson:"fee_rate" validate:"required"`
FeePercentage *utils.BigFloat `json:"percentageFee" bson:"percentage_fee" validate:"required"`
FeePercentage *utils.BigFloat `json:"feePercentage" bson:"percentage_fee" validate:"required"`
GasPrice *entities.Wei `json:"gasPrice" bson:"gas_price" validate:"required"`
FixedFee *entities.Wei `json:"fixedFee" bson:"fixed_fee" validate:"required"`
}
Expand Down
4 changes: 1 addition & 3 deletions internal/usecases/pegin/get_pegin_quote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ func TestGetQuoteUseCase_Run(t *testing.T) {
quoteMatchFunction := mock.MatchedBy(func(q quote.PeginQuote) bool {
return q.FedBtcAddress == fedAddress && q.LbcAddress == lbcAddress && q.LpRskAddress == lpRskAddress &&
q.BtcRefundAddress == blockchain.BitcoinTestnetP2PKHZeroAddress && q.RskRefundAddress == userRskAddress && q.LpBtcAddress == lpBtcAddress &&
// TODO update expected value in GBI-2528
/* q.CallFee.Cmp(config.FixedFee) == 0 && */
q.PenaltyFee.Cmp(config.PenaltyFee) == 0 && q.ContractAddress == userRskAddress &&
q.PenaltyFee.Cmp(config.PenaltyFee) == 0 && q.ContractAddress == userRskAddress && q.CallFee.Cmp(entities.NewWei(163)) == 0 &&
q.Data == hex.EncodeToString(quoteData) && q.GasLimit == uint32(gasLimit.Uint64()) && q.Value.Cmp(quoteValue) == 0 &&
q.Nonce > 0 && q.TimeForDeposit == config.TimeForDeposit && q.LpCallTime == config.CallTime && q.Confirmations == 10 &&
q.CallOnRegister == false && q.GasFee.Cmp(entities.NewWei(10000)) == 0 && q.ProductFeeAmount == 0
Expand Down
2 changes: 1 addition & 1 deletion internal/usecases/pegout/get_pegout_quote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestGetQuoteUseCase_Run(t *testing.T) {
assert.Equal(t, toAddress, result.PegoutQuote.DepositAddress)
assert.Equal(t, toAddress, result.PegoutQuote.BtcRefundAddress)
assert.Equal(t, entities.NewWei(1000000000000000000), result.PegoutQuote.Value)
// assert.Equal(t, entities.NewWei(200), result.PegoutQuote.CallFee) // TODO update expected value in GBI-2528
assert.Equal(t, entities.NewWei(15500000000000200), result.PegoutQuote.CallFee)
assert.Equal(t, uint64(20), result.PegoutQuote.PenaltyFee)
assert.Equal(t, "0x1234", result.PegoutQuote.LbcAddress)
assert.NotEmpty(t, result.PegoutQuote.Nonce)
Expand Down
177 changes: 177 additions & 0 deletions test/mocks/peg_configuration_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading