go-ethereum/XDCxlending/order_processor_test.go

549 lines
14 KiB
Go

package XDCxlending
import (
"math/big"
"reflect"
"testing"
"github.com/XinFinOrg/XDPoSChain/XDCx"
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/node"
)
func Test_getCancelFeeV1(t *testing.T) {
type CancelFeeArg struct {
collateralTokenDecimal *big.Int
collateralPrice *big.Int
borrowFeeRate *big.Int
order *lendingstate.LendingItem
}
tests := []struct {
name string
args CancelFeeArg
want *big.Int
}{
// zero fee test: LEND
{
"zero fee getCancelFeeV1: LEND",
CancelFeeArg{
collateralTokenDecimal: common.Big1,
collateralPrice: common.Big1,
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
Quantity: new(big.Int).SetUint64(10000),
Side: tradingstate.Ask,
},
},
common.Big0,
},
// zero fee test: BORROW
{
"zero fee getCancelFeeV1: BORROW",
CancelFeeArg{
collateralTokenDecimal: common.Big1,
collateralPrice: common.Big1,
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
Quantity: new(big.Int).SetUint64(10000),
Side: tradingstate.Bid,
},
},
common.Big0,
},
// test getCancelFee: LEND
{
"test getCancelFeeV1:: LEND",
CancelFeeArg{
collateralTokenDecimal: common.Big1,
collateralPrice: common.Big1,
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
Quantity: new(big.Int).SetUint64(10000),
Side: tradingstate.Ask,
},
},
common.Big3,
},
// test getCancelFee:: BORROW
{
"test getCancelFeeV1:: BORROW",
CancelFeeArg{
collateralTokenDecimal: common.Big1,
collateralPrice: common.Big1,
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
Quantity: new(big.Int).SetUint64(10000),
Side: tradingstate.Bid,
},
},
common.Big3,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := getCancelFeeV1(tt.args.collateralTokenDecimal, tt.args.collateralPrice, tt.args.borrowFeeRate, tt.args.order); !reflect.DeepEqual(got, tt.want) {
t.Errorf("getCancelFeeV1() = %v, want %v", got, tt.want)
}
})
}
}
func Test_getCancelFee(t *testing.T) {
stack, err := node.New(&node.DefaultConfig)
if err != nil {
t.Fatalf("could not create new node: %v", err)
}
XDCx := XDCx.New(stack, &XDCx.DefaultConfig)
defer stack.Close()
db := rawdb.NewMemoryDatabase()
stateCache := tradingstate.NewDatabase(db)
tradingStateDb, _ := tradingstate.New(types.EmptyRootHash, stateCache)
testTokenA := common.HexToAddress("0x1200000000000000000000000000000000000002")
testTokenB := common.HexToAddress("0x1300000000000000000000000000000000000003")
// set decimal
// tokenA has decimal 10^18
XDCx.SetTokenDecimal(testTokenA, common.BasePrice)
// tokenB has decimal 10^8
XDCx.SetTokenDecimal(testTokenB, new(big.Int).Exp(big.NewInt(10), big.NewInt(8), nil))
// set tokenAPrice = 1 XDC
tradingStateDb.SetMediumPriceBeforeEpoch(tradingstate.GetTradingOrderBookHash(testTokenA, common.XDCNativeAddressBinary), common.BasePrice)
// set tokenBPrice = 1 XDC
tradingStateDb.SetMediumPriceBeforeEpoch(tradingstate.GetTradingOrderBookHash(testTokenB, common.XDCNativeAddressBinary), common.BasePrice)
l := New(stack, XDCx)
type CancelFeeArg struct {
borrowFeeRate *big.Int
order *lendingstate.LendingItem
}
tests := []struct {
name string
args CancelFeeArg
want *big.Int
}{
// LENDING TOKEN: testTokenA
// COLLATERAL TOKEN: XDC
// zero fee test: LEND
{
"TokenA/XDCzero fee test: LEND",
CancelFeeArg{
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
LendingToken: testTokenA,
CollateralToken: common.XDCNativeAddressBinary,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Investing,
},
},
common.Big0,
},
// zero fee test: BORROW
{
"TokenA/XDC zero fee test: BORROW",
CancelFeeArg{
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
LendingToken: testTokenA,
CollateralToken: common.XDCNativeAddressBinary,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Borrowing,
},
},
common.Big0,
},
// test getCancelFee: LEND
{
"TokenA/XDC test getCancelFee:: LEND",
CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
LendingToken: testTokenA,
CollateralToken: common.XDCNativeAddressBinary,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Investing,
},
},
common.RelayerLendingCancelFee,
},
// test getCancelFee:: BORROW
{
"TokenA/XDC test getCancelFee:: BORROW",
CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
LendingToken: testTokenA,
CollateralToken: common.XDCNativeAddressBinary,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Borrowing,
},
},
common.RelayerLendingCancelFee,
},
// LENDING TOKEN: XDC
// COLLATERAL TOKEN: testTokenA
// zero fee test: LEND
{
"XDC/TokenA zero fee test: LEND",
CancelFeeArg{
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
LendingToken: common.XDCNativeAddressBinary,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Investing,
},
},
common.Big0,
},
// zero fee test: BORROW
{
"XDC/TokenA zero fee test: BORROW",
CancelFeeArg{
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
LendingToken: common.XDCNativeAddressBinary,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Borrowing,
},
},
common.Big0,
},
// test getCancelFee: LEND
{
"XDC/TokenA test getCancelFee:: LEND",
CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
LendingToken: common.XDCNativeAddressBinary,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Investing,
},
},
common.RelayerLendingCancelFee,
},
// test getCancelFee:: BORROW
{
"XDC/TokenA test getCancelFee:: BORROW",
CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
LendingToken: common.XDCNativeAddressBinary,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Borrowing,
},
},
common.RelayerLendingCancelFee,
},
// LENDING TOKEN: testTokenB
// COLLATERAL TOKEN: testTokenA
// zero fee test: LEND
{
"TokenB/TokenA zero fee test: LEND",
CancelFeeArg{
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
LendingToken: testTokenB,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Investing,
},
},
common.Big0,
},
// zero fee test: BORROW
{
"TokenB/TokenA zero fee test: BORROW",
CancelFeeArg{
borrowFeeRate: common.Big0,
order: &lendingstate.LendingItem{
LendingToken: testTokenB,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Borrowing,
},
},
common.Big0,
},
// test getCancelFee: LEND
{
"TokenB/TokenA test getCancelFee:: LEND",
CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
LendingToken: testTokenB,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Investing,
},
},
new(big.Int).Exp(big.NewInt(10), big.NewInt(5), nil),
},
// test getCancelFee:: BORROW
{
"TokenB/TokenA test getCancelFee:: BORROW",
CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(30), // 30/10000= 0.3%
order: &lendingstate.LendingItem{
LendingToken: testTokenB,
CollateralToken: testTokenA,
Quantity: new(big.Int).SetUint64(10000),
Side: lendingstate.Borrowing,
},
},
common.RelayerLendingCancelFee,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got, _ := l.getCancelFee(nil, nil, tradingStateDb, tt.args.order, tt.args.borrowFeeRate); !reflect.DeepEqual(got, tt.want) {
t.Errorf("getCancelFee() = %v, want %v", got, tt.want)
}
})
}
// testcase: can't get price of token in XDC
testTokenC := common.HexToAddress("0x1400000000000000000000000000000000000004")
XDCx.SetTokenDecimal(testTokenC, big.NewInt(1))
tokenCOrder := CancelFeeArg{
borrowFeeRate: new(big.Int).SetUint64(100), // 100/10000= 1%
order: &lendingstate.LendingItem{
Quantity: new(big.Int).SetUint64(10000),
CollateralToken: testTokenC,
LendingToken: testTokenA,
Side: lendingstate.Borrowing,
},
}
if fee, _ := l.getCancelFee(nil, nil, tradingStateDb, tokenCOrder.order, tokenCOrder.borrowFeeRate); fee != nil && fee.Sign() != 0 {
t.Errorf("getCancelFee() = %v, want %v", fee, common.Big0)
}
}
func TestGetLendQuantity(t *testing.T) {
depositRate := big.NewInt(150)
lendQuantity := new(big.Int).Mul(big.NewInt(1000), common.BasePrice)
collateralLocked, _ := new(big.Int).SetString("1000000000000000000000", 10) // 1000
collateralLocked = new(big.Int).Mul(big.NewInt(150), collateralLocked)
collateralLocked = new(big.Int).Div(collateralLocked, big.NewInt(100))
type GetLendQuantityArg struct {
takerSide string
collateralTokenDecimal *big.Int
depositRate *big.Int
collateralPrice *big.Int
takerBalance *big.Int
makerBalance *big.Int
quantityToLend *big.Int
}
tests := []struct {
name string
args GetLendQuantityArg
lendQuantity *big.Int
rejectMaker bool
}{
{
"taker: BORROW, takerBalance = 0, reject taker, makerBalance = 0",
GetLendQuantityArg{
lendingstate.Borrowing,
common.BasePrice,
depositRate,
common.BasePrice,
common.Big0,
common.Big0,
lendQuantity,
},
common.Big0,
false,
},
{
"taker: BORROW, takerBalance = 0, reject taker, makerBalance > 0",
GetLendQuantityArg{
lendingstate.Borrowing,
common.BasePrice,
depositRate,
common.BasePrice,
common.Big0,
lendQuantity,
lendQuantity,
},
common.Big0,
false,
},
{
"taker: BORROW, takerBalance not enough, reject partial of taker",
GetLendQuantityArg{
lendingstate.Borrowing,
common.BasePrice,
depositRate,
common.BasePrice,
new(big.Int).Rsh(collateralLocked, 1), // 1/2
lendQuantity,
lendQuantity,
},
new(big.Int).Rsh(lendQuantity, 1),
false,
},
{
"taker: BORROW, makerBalance = 0, reject maker",
GetLendQuantityArg{
lendingstate.Borrowing,
common.BasePrice,
depositRate,
common.BasePrice,
new(big.Int).Rsh(collateralLocked, 1),
common.Big0,
lendQuantity,
},
common.Big0,
true,
},
{
"taker: BORROW, makerBalance not enough, reject partial of maker",
GetLendQuantityArg{
lendingstate.Borrowing,
common.BasePrice,
depositRate,
common.BasePrice,
collateralLocked,
new(big.Int).Rsh(lendQuantity, 1),
lendQuantity,
},
new(big.Int).Rsh(lendQuantity, 1),
true,
},
{
"taker: BORROW, don't reject",
GetLendQuantityArg{
lendingstate.Borrowing,
common.BasePrice,
depositRate,
common.BasePrice,
collateralLocked,
lendQuantity,
lendQuantity,
},
lendQuantity,
false,
},
{
"taker: INVEST, makerBalance = 0, reject maker",
GetLendQuantityArg{
lendingstate.Investing,
common.BasePrice,
depositRate,
common.BasePrice,
new(big.Int).Rsh(collateralLocked, 1),
common.Big0,
lendQuantity,
},
common.Big0,
true,
},
{
"taker: INVEST, takerBalance not enough, reject partial of taker",
GetLendQuantityArg{
lendingstate.Investing,
common.BasePrice,
depositRate,
common.BasePrice,
new(big.Int).Rsh(lendQuantity, 1), // 1/2
collateralLocked,
lendQuantity,
},
new(big.Int).Rsh(lendQuantity, 1),
false,
},
{
"taker: INVEST, makerBalance = 0, reject maker",
GetLendQuantityArg{
lendingstate.Investing,
common.BasePrice,
depositRate,
common.BasePrice,
common.Big0,
new(big.Int).Rsh(collateralLocked, 1),
lendQuantity,
},
common.Big0,
false,
},
{
"taker: INVEST, makerBalance is enough, takerBalance = 0 -> reject taker",
GetLendQuantityArg{
lendingstate.Investing,
common.BasePrice,
depositRate,
common.BasePrice,
common.Big0,
collateralLocked,
lendQuantity,
},
common.Big0,
false,
},
{
"taker: INVEST, makerBalance not enough, reject partial of maker",
GetLendQuantityArg{
lendingstate.Investing,
common.BasePrice,
depositRate,
common.BasePrice,
collateralLocked,
new(big.Int).Rsh(collateralLocked, 1),
lendQuantity,
},
new(big.Int).Rsh(lendQuantity, 1),
true,
},
{
"taker: INVEST, don't reject",
GetLendQuantityArg{
lendingstate.Investing,
common.BasePrice,
depositRate,
common.BasePrice,
lendQuantity,
collateralLocked,
lendQuantity,
},
lendQuantity,
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := GetLendQuantity(tt.args.takerSide, tt.args.collateralTokenDecimal, tt.args.depositRate, tt.args.collateralPrice, tt.args.takerBalance, tt.args.makerBalance, tt.args.quantityToLend)
if !reflect.DeepEqual(got, tt.lendQuantity) {
t.Errorf("GetLendQuantity() got = %v, want %v", got, tt.lendQuantity)
}
if got1 != tt.rejectMaker {
t.Errorf("GetLendQuantity() got1 = %v, want %v", got1, tt.rejectMaker)
}
})
}
}