Skip to content

Commit

Permalink
Merge pull request #184 from crescent-network/feat/order-source-fee
Browse files Browse the repository at this point in the history
feat: add `order_source_fee_ratio` for order source orders
  • Loading branch information
kingcre authored Aug 23, 2023
2 parents aae4810 + 36fc0ae commit 40d66ec
Show file tree
Hide file tree
Showing 39 changed files with 965 additions and 420 deletions.
3 changes: 2 additions & 1 deletion app/upgrades/mainnet/v5/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func UpgradeHandler(
liquidityKeeper.DeleteOutdatedRequests(ctx)
defaultMakerFeeRate := exchangeParams.Fees.DefaultMakerFeeRate
defaultTakerFeeRate := exchangeParams.Fees.DefaultTakerFeeRate
defaultOrderSourceFeeRatio := exchangeParams.Fees.DefaultOrderSourceFeeRatio
pairs := map[uint64]liquiditytypes.Pair{}
var pairIds []uint64 // For ordered map access
if err := liquidityKeeper.IterateAllPairs(ctx, func(pair liquiditytypes.Pair) (stop bool, err error) {
Expand Down Expand Up @@ -176,7 +177,7 @@ func UpgradeHandler(
// corresponding indexes, too.
market := exchangetypes.NewMarket(
pair.Id, pair.BaseCoinDenom, pair.QuoteCoinDenom,
defaultMakerFeeRate, defaultTakerFeeRate)
defaultMakerFeeRate, defaultTakerFeeRate, defaultOrderSourceFeeRatio)
exchangeKeeper.SetMarket(ctx, market)
exchangeKeeper.SetMarketByDenomsIndex(ctx, market)
exchangeKeeper.SetMarketState(ctx, market.Id, exchangetypes.NewMarketState(pair.LastPrice))
Expand Down
2 changes: 1 addition & 1 deletion client/docs/statik/statik.go

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions client/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11606,6 +11606,12 @@ paths:
type: string
escrow_address:
type: string
maker_fee_rate:
type: string
taker_fee_rate:
type: string
order_source_fee_ratio:
type: string
last_price:
type: string
last_matching_height:
Expand Down Expand Up @@ -11741,6 +11747,12 @@ paths:
type: string
escrow_address:
type: string
maker_fee_rate:
type: string
taker_fee_rate:
type: string
order_source_fee_ratio:
type: string
last_price:
type: string
last_matching_height:
Expand Down Expand Up @@ -12119,6 +12131,8 @@ paths:
type: string
default_taker_fee_rate:
type: string
default_order_source_fee_ratio:
type: string
max_order_lifespan:
type: string
max_order_price_ratio:
Expand Down Expand Up @@ -20078,6 +20092,8 @@ definitions:
type: string
default_taker_fee_rate:
type: string
default_order_source_fee_ratio:
type: string
crescent.exchange.v1beta1.MarketResponse:
type: object
properties:
Expand All @@ -20090,6 +20106,12 @@ definitions:
type: string
escrow_address:
type: string
maker_fee_rate:
type: string
taker_fee_rate:
type: string
order_source_fee_ratio:
type: string
last_price:
type: string
last_matching_height:
Expand Down Expand Up @@ -20200,6 +20222,8 @@ definitions:
type: string
default_taker_fee_rate:
type: string
default_order_source_fee_ratio:
type: string
max_order_lifespan:
type: string
max_order_price_ratio:
Expand Down Expand Up @@ -20230,6 +20254,12 @@ definitions:
type: string
escrow_address:
type: string
maker_fee_rate:
type: string
taker_fee_rate:
type: string
order_source_fee_ratio:
type: string
last_price:
type: string
last_matching_height:
Expand Down Expand Up @@ -20416,6 +20446,12 @@ definitions:
type: string
escrow_address:
type: string
maker_fee_rate:
type: string
taker_fee_rate:
type: string
order_source_fee_ratio:
type: string
last_price:
type: string
last_matching_height:
Expand Down Expand Up @@ -20521,6 +20557,8 @@ definitions:
type: string
default_taker_fee_rate:
type: string
default_order_source_fee_ratio:
type: string
max_order_lifespan:
type: string
max_order_price_ratio:
Expand Down
8 changes: 6 additions & 2 deletions proto/crescent/exchange/v1beta1/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ option go_package = "github.com/crescent-network/crescent/v
option (gogoproto.goproto_getters_all) = false;

message EventCreateMarket {
string creator = 1;
uint64 market_id = 2;
string creator = 1;
string base_denom = 2;
string quote_denom = 3;
uint64 market_id = 4;
}

message EventPlaceLimitOrder {
Expand Down Expand Up @@ -135,4 +137,6 @@ message EventMarketParameterChanged {
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string taker_fee_rate = 3
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string order_source_fee_ratio = 4
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
2 changes: 2 additions & 0 deletions proto/crescent/exchange/v1beta1/exchange.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ message Market {
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string taker_fee_rate = 6
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string order_source_fee_ratio = 7
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}

message MarketState {
Expand Down
2 changes: 2 additions & 0 deletions proto/crescent/exchange/v1beta1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ message Fees {
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string default_taker_fee_rate = 3
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string default_order_source_fee_ratio = 4
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
2 changes: 2 additions & 0 deletions proto/crescent/exchange/v1beta1/proposal.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ message MarketParameterChange {
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string taker_fee_rate = 3
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string order_source_fee_ratio = 4
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
}
18 changes: 12 additions & 6 deletions proto/crescent/exchange/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,16 @@ message QueryOrderBookResponse {
}

message MarketResponse {
uint64 id = 1;
string base_denom = 2;
string quote_denom = 3;
string escrow_address = 4;
string last_price = 5 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec"];
int64 last_matching_height = 6;
uint64 id = 1;
string base_denom = 2;
string quote_denom = 3;
string escrow_address = 4;
string maker_fee_rate = 5
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string taker_fee_rate = 6
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string order_source_fee_ratio = 7
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string last_price = 8 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec"];
int64 last_matching_height = 9;
}
44 changes: 26 additions & 18 deletions x/amm/simulation/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func findMsgCreatePoolParams(r *rand.Rand, accs []simtypes.Account,
if marketState.LastPrice != nil {
price = *marketState.LastPrice
} else {
price = utils.RandomDec(r, utils.ParseDec("0.05"), utils.ParseDec("500"))
price = utils.RandomDec(r, utils.ParseDec("0.1"), utils.ParseDec("10"))
}
msg = types.NewMsgCreatePool(acc.Address, market.Id, price)
return acc, msg, true
Expand All @@ -235,40 +235,48 @@ func findMsgAddLiquidityParams(
for _, pool := range pools {
if spendable.AmountOf(pool.Denom0).GT(sdk.NewInt(100_000000)) &&
spendable.AmountOf(pool.Denom1).GT(sdk.NewInt(100_000000)) {
ts := int32(pool.TickSpacing)
poolState := k.MustGetPoolState(ctx, pool.Id)
var lowerPrice, upperPrice sdk.Dec
if r.Float64() <= 0.2 {
lowerPrice = types.MinPrice
} else if r.Float64() <= 0.5 {
lowerPrice = exchangetypes.PriceAtTick(
exchangetypes.TickAtPrice(
utils.RandomDec(r,
types.AdjustPriceToTickSpacing(
utils.RandomDec(
r,
poolState.CurrentPrice.Mul(utils.ParseDec("0.5")),
poolState.CurrentPrice)) / ts * ts)
poolState.CurrentPrice),
pool.TickSpacing, false))
} else {
lowerPrice = exchangetypes.PriceAtTick(
exchangetypes.TickAtPrice(
utils.RandomDec(r,
types.AdjustPriceToTickSpacing(
utils.RandomDec(
r,
poolState.CurrentPrice,
poolState.CurrentPrice.Mul(utils.ParseDec("1.5")))) / ts * ts)
poolState.CurrentPrice.Mul(utils.ParseDec("1.5"))),
pool.TickSpacing, false))
}
if r.Float64() <= 0.2 {
upperPrice = types.MaxPrice
} else {
upperPrice = exchangetypes.PriceAtTick(
exchangetypes.TickAtPrice(
utils.RandomDec(r,
types.AdjustPriceToTickSpacing(
utils.RandomDec(
r,
lowerPrice.Mul(utils.ParseDec("1.01")),
poolState.CurrentPrice.Mul(utils.ParseDec("3")))) / ts * ts)
poolState.CurrentPrice.Mul(utils.ParseDec("3"))),
pool.TickSpacing, true))
}
liquidity := utils.RandomInt(r, sdk.NewInt(10000), sdk.NewInt(100_000000))
amt0, amt1 := types.AmountsForLiquidity(
utils.DecApproxSqrt(poolState.CurrentPrice),
utils.DecApproxSqrt(lowerPrice),
utils.DecApproxSqrt(upperPrice),
liquidity)
desiredAmt := sdk.NewCoins(sdk.NewCoin(pool.Denom0, amt0), sdk.NewCoin(pool.Denom1, amt1))
if !spendable.IsAllGTE(desiredAmt) {
continue
}
desiredAmt := sdk.NewCoins(
sdk.NewCoin(
pool.Denom0,
utils.RandomInt(r, sdk.NewInt(100), sdk.NewInt(100_000000))),
sdk.NewCoin(
pool.Denom1,
utils.RandomInt(r, sdk.NewInt(100), sdk.NewInt(100_000000))))
msg = types.NewMsgAddLiquidity(
acc.Address, pool.Id, lowerPrice, upperPrice, desiredAmt)
return acc, msg, true
Expand Down
8 changes: 4 additions & 4 deletions x/amm/simulation/operations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (s *SimTestSuite) TestSimulateMsgCreatePool() {
s.Require().Equal(types.ModuleName, msg.Route())
s.Require().Equal("cosmos1dj7jl7a84qaj7566qaa4uxj7d28vvr304204ha", msg.Sender)
s.Require().EqualValues(5, msg.MarketId)
s.Require().Equal("254.938225934828752998", msg.Price.String())
s.AssertEqual(utils.ParseDec("6.585228379443441869"), msg.Price)
}

func (s *SimTestSuite) TestSimulateMsgAddLiquidity() {
Expand Down Expand Up @@ -120,9 +120,9 @@ func (s *SimTestSuite) TestSimulateMsgAddLiquidity() {
s.Require().Equal(types.ModuleName, msg.Route())
s.Require().Equal("cosmos1ea66m0hr892xhmtjzq7s76vq8cdcmnqgewvtsy", msg.Sender)
s.Require().EqualValues(2, msg.PoolId)
s.Require().Equal("144.000000000000000000", msg.LowerPrice.String())
s.Require().Equal("584.000000000000000000", msg.UpperPrice.String())
s.Require().Equal("27329649denom1,57336327denom3", msg.DesiredAmount.String())
s.AssertEqual(utils.ParseDec("144"), msg.LowerPrice)
s.AssertEqual(utils.ParseDec("584.5"), msg.UpperPrice)
s.AssertEqual(utils.ParseCoins("569259denom1,111578257denom3"), msg.DesiredAmount)
}

func (s *SimTestSuite) TestSimulateMsgRemoveLiquidity() {
Expand Down
3 changes: 2 additions & 1 deletion x/amm/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ var (
AllowedTickSpacings = []uint32{1, 5, 10, 50}
// DecMulFactor is multiplied to fee and farming rewards growth variables
// so that small amount of rewards can be handled correctly.
DecMulFactor = sdk.NewDecFromInt(sdk.NewIntWithDecimal(1, 12))
DecMulFactor = sdk.NewDecFromInt(sdk.NewIntWithDecimal(1, 12))
DefaultMinOrderQuantity = sdk.NewDec(1)
)

func IsAllowedTickSpacing(tickSpacing uint32) bool {
Expand Down
2 changes: 1 addition & 1 deletion x/amm/types/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func NewPool(id uint64, marketId uint64, denom0, denom1 string, tickSpacing uint
ReserveAddress: DerivePoolReserveAddress(id).String(),
RewardsPool: DerivePoolRewardsPoolAddress(id).String(),
TickSpacing: tickSpacing,
MinOrderQuantity: utils.OneDec, // default is 1
MinOrderQuantity: DefaultMinOrderQuantity,
}
}

Expand Down
3 changes: 3 additions & 0 deletions x/exchange/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ func (s *KeeperTestSuite) TestQueryMarket() {
"",
func(resp *types.QueryMarketResponse) {
s.Require().EqualValues(2, resp.Market.Id)
s.AssertEqual(utils.ParseDec("-0.0015"), resp.Market.MakerFeeRate)
s.AssertEqual(utils.ParseDec("0.003"), resp.Market.TakerFeeRate)
s.AssertEqual(utils.ParseDec("0.5"), resp.Market.OrderSourceFeeRatio)
},
},
{
Expand Down
9 changes: 6 additions & 3 deletions x/exchange/keeper/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ func (k Keeper) CreateMarket(

marketId := k.GetNextMarketIdWithUpdate(ctx)
market = types.NewMarket(
marketId, baseDenom, quoteDenom, fees.DefaultMakerFeeRate, fees.DefaultTakerFeeRate)
marketId, baseDenom, quoteDenom,
fees.DefaultMakerFeeRate, fees.DefaultTakerFeeRate, fees.DefaultOrderSourceFeeRatio)
k.SetMarket(ctx, market)
k.SetMarketByDenomsIndex(ctx, market)
k.SetMarketState(ctx, market.Id, types.NewMarketState(nil))

if err = ctx.EventManager().EmitTypedEvent(&types.EventCreateMarket{
Creator: creatorAddr.String(),
MarketId: marketId,
Creator: creatorAddr.String(),
BaseDenom: baseDenom,
QuoteDenom: quoteDenom,
MarketId: marketId,
}); err != nil {
return
}
Expand Down
8 changes: 5 additions & 3 deletions x/exchange/keeper/proposal_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ func HandleMarketParameterChangeProposal(ctx sdk.Context, k Keeper, p *types.Mar
}
market.MakerFeeRate = change.MakerFeeRate
market.TakerFeeRate = change.TakerFeeRate
market.OrderSourceFeeRatio = change.OrderSourceFeeRatio
k.SetMarket(ctx, market)
if err := ctx.EventManager().EmitTypedEvent(&types.EventMarketParameterChanged{
MarketId: change.MarketId,
MakerFeeRate: change.MakerFeeRate,
TakerFeeRate: change.TakerFeeRate,
MarketId: change.MarketId,
MakerFeeRate: change.MakerFeeRate,
TakerFeeRate: change.TakerFeeRate,
OrderSourceFeeRatio: change.OrderSourceFeeRatio,
}); err != nil {
return err
}
Expand Down
6 changes: 4 additions & 2 deletions x/exchange/keeper/proposal_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,28 @@ func (s *KeeperTestSuite) TestPoolParameterChangeProposal() {
proposal := types.NewMarketParameterChangeProposal(
"Title", "Description", []types.MarketParameterChange{
types.NewMarketParameterChange(
market2.Id, utils.ParseDec("0.001"), utils.ParseDec("0.002")),
market2.Id, utils.ParseDec("0.001"), utils.ParseDec("0.002"), utils.ParseDec("0.3")),
})
s.Require().NoError(proposal.ValidateBasic())
s.Require().NoError(handler(s.Ctx, proposal))

market2, _ = s.keeper.GetMarket(s.Ctx, market2.Id)
s.Require().Equal(utils.ParseDec("0.001"), market2.MakerFeeRate)
s.Require().Equal(utils.ParseDec("0.002"), market2.TakerFeeRate)
s.Require().Equal(utils.ParseDec("0.3"), market2.OrderSourceFeeRatio)

// Untouched
market1, _ = s.keeper.GetMarket(s.Ctx, market1.Id)
fees := s.keeper.GetFees(s.Ctx)
s.Require().Equal(fees.DefaultMakerFeeRate, market1.MakerFeeRate)
s.Require().Equal(fees.DefaultTakerFeeRate, market1.TakerFeeRate)
s.Require().Equal(fees.DefaultOrderSourceFeeRatio, market1.OrderSourceFeeRatio)

// Market not found
proposal = types.NewMarketParameterChangeProposal(
"Title", "Description", []types.MarketParameterChange{
types.NewMarketParameterChange(
3, utils.ParseDec("0.001"), utils.ParseDec("0.002")),
3, utils.ParseDec("0.001"), utils.ParseDec("0.002"), utils.ParseDec("0.5")),
})
s.Require().NoError(proposal.ValidateBasic())
s.Require().EqualError(handler(s.Ctx, proposal), "market 3 not found: not found")
Expand Down
3 changes: 2 additions & 1 deletion x/exchange/simulation/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ func TestDecodeStore(t *testing.T) {
dec := simulation.NewDecodeStore(cdc)

market := types.NewMarket(
10, "ucre", "uusd", types.DefaultFees.DefaultMakerFeeRate, types.DefaultFees.DefaultTakerFeeRate)
10, "ucre", "uusd",
types.DefaultFees.DefaultMakerFeeRate, types.DefaultFees.DefaultTakerFeeRate, types.DefaultFees.DefaultOrderSourceFeeRatio)
marketState := types.NewMarketState(utils.ParseDecP("12.345"))
order := types.NewOrder(
1, types.OrderTypeLimit, utils.TestAddress(1), 10, false, utils.ParseDec("12.345"), sdk.NewDec(100_000000),
Expand Down
Loading

0 comments on commit 40d66ec

Please sign in to comment.