[ENG-585]: Setting min bid increment in ante (#28)
This commit is contained in:
parent
b6da342a49
commit
fdfd12a81d
@ -158,6 +158,16 @@ func (am *AuctionMempool) RemoveWithoutRefTx(tx sdk.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTopAuctionTx returns the highest bidding transaction in the auction mempool.
|
||||
func (am *AuctionMempool) GetTopAuctionTx(ctx context.Context) sdk.Tx {
|
||||
iterator := am.auctionIndex.Select(ctx, nil)
|
||||
if iterator == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return iterator.Tx()
|
||||
}
|
||||
|
||||
// AuctionBidSelect returns an iterator over auction bids transactions only.
|
||||
func (am *AuctionMempool) AuctionBidSelect(ctx context.Context) sdkmempool.Iterator {
|
||||
return am.auctionIndex.Select(ctx, nil)
|
||||
|
||||
@ -12,12 +12,14 @@ var _ sdk.AnteDecorator = AuctionDecorator{}
|
||||
type AuctionDecorator struct {
|
||||
auctionKeeper keeper.Keeper
|
||||
txDecoder sdk.TxDecoder
|
||||
mempool *mempool.AuctionMempool
|
||||
}
|
||||
|
||||
func NewAuctionDecorator(ak keeper.Keeper, txDecoder sdk.TxDecoder) AuctionDecorator {
|
||||
func NewAuctionDecorator(ak keeper.Keeper, txDecoder sdk.TxDecoder, mempool *mempool.AuctionMempool) AuctionDecorator {
|
||||
return AuctionDecorator{
|
||||
auctionKeeper: ak,
|
||||
txDecoder: txDecoder,
|
||||
mempool: mempool,
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,10 +48,25 @@ func (ad AuctionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
transactions[i] = decodedTx
|
||||
}
|
||||
|
||||
if err := ad.auctionKeeper.ValidateAuctionMsg(ctx, bidder, auctionMsg.Bid, transactions); err != nil {
|
||||
highestBid, err := ad.GetHighestAuctionBid(ctx)
|
||||
if err != nil {
|
||||
return ctx, errors.Wrap(err, "failed to get highest auction bid")
|
||||
}
|
||||
|
||||
if err := ad.auctionKeeper.ValidateAuctionMsg(ctx, bidder, auctionMsg.Bid, highestBid, transactions); err != nil {
|
||||
return ctx, errors.Wrap(err, "failed to validate auction bid")
|
||||
}
|
||||
}
|
||||
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
// GetHighestAuctionBid returns the highest auction bid if one exists.
|
||||
func (ad AuctionDecorator) GetHighestAuctionBid(ctx sdk.Context) (sdk.Coins, error) {
|
||||
auctionTx := ad.mempool.GetTopAuctionTx(ctx)
|
||||
if auctionTx == nil {
|
||||
return sdk.NewCoins(), nil
|
||||
}
|
||||
|
||||
return auctionTx.(*mempool.WrappedBidTx).GetBid(), nil
|
||||
}
|
||||
|
||||
@ -6,10 +6,8 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// ValidateAuctionMsg validates that the MsgAuctionBid is valid. It checks that the bidder has sufficient funds to bid the
|
||||
// amount specified in the message, that the bundle size is not greater than the max bundle size, and that the bundle
|
||||
// transactions are valid.
|
||||
func (k Keeper) ValidateAuctionMsg(ctx sdk.Context, bidder sdk.AccAddress, bid sdk.Coins, transactions []sdk.Tx) error {
|
||||
// ValidateAuctionMsg validates that the MsgAuctionBid can be included in the auction.
|
||||
func (k Keeper) ValidateAuctionMsg(ctx sdk.Context, bidder sdk.AccAddress, bid, highestBid sdk.Coins, transactions []sdk.Tx) error {
|
||||
// Validate the bundle size.
|
||||
maxBundleSize, err := k.GetMaxBundleSize(ctx)
|
||||
if err != nil {
|
||||
@ -21,7 +19,7 @@ func (k Keeper) ValidateAuctionMsg(ctx sdk.Context, bidder sdk.AccAddress, bid s
|
||||
}
|
||||
|
||||
// Validate the bid amount.
|
||||
if err := k.ValidateAuctionBid(ctx, bidder, bid); err != nil {
|
||||
if err := k.ValidateAuctionBid(ctx, bidder, bid, highestBid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -40,8 +38,20 @@ func (k Keeper) ValidateAuctionMsg(ctx sdk.Context, bidder sdk.AccAddress, bid s
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateAuctionBid validates that the bidder has sufficient funds to participate in the auction.
|
||||
func (k Keeper) ValidateAuctionBid(ctx sdk.Context, bidder sdk.AccAddress, bid sdk.Coins) error {
|
||||
// ValidateAuctionBid validates that the bidder has sufficient funds to participate in the auction and that the bid amount
|
||||
// is sufficiently high enough.
|
||||
func (k Keeper) ValidateAuctionBid(ctx sdk.Context, bidder sdk.AccAddress, bid, highestBid sdk.Coins) error {
|
||||
// Ensure the bid is greater than the highest bid + min bid increment.
|
||||
minBidIncrement, err := k.GetMinBidIncrement(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minBid := highestBid.Add(minBidIncrement...)
|
||||
if !bid.IsAllGTE(minBid) {
|
||||
return fmt.Errorf("bid amount (%s) is less than the highest bid (%s) + min bid increment (%s)", bid, highestBid, minBidIncrement)
|
||||
}
|
||||
|
||||
// Get the bid floor.
|
||||
reserveFee, err := k.GetReserveFee(ctx)
|
||||
if err != nil {
|
||||
|
||||
@ -24,8 +24,12 @@ func (suite *IntegrationTestSuite) TestValidateAuctionMsg() {
|
||||
maxBundleSize uint32 = 10
|
||||
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
|
||||
minBuyInFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
|
||||
minBidIncrement = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
|
||||
escrowAddress = sdk.AccAddress([]byte("escrow"))
|
||||
frontRunningProtection = true
|
||||
|
||||
// mempool variables
|
||||
highestBid = sdk.NewCoins()
|
||||
)
|
||||
|
||||
rnd := rand.New(rand.NewSource(time.Now().Unix()))
|
||||
@ -123,6 +127,23 @@ func (suite *IntegrationTestSuite) TestValidateAuctionMsg() {
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid bundle that does not outbid the highest bid",
|
||||
func() {
|
||||
accounts = []Account{bidder, bidder, bidder}
|
||||
highestBid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(500)))
|
||||
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(500)))
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"valid bundle that outbids the highest bid",
|
||||
func() {
|
||||
highestBid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(500)))
|
||||
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1500)))
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
@ -148,6 +169,7 @@ func (suite *IntegrationTestSuite) TestValidateAuctionMsg() {
|
||||
MinBuyInFee: minBuyInFee,
|
||||
EscrowAccountAddress: escrowAddress.String(),
|
||||
FrontRunningProtection: frontRunningProtection,
|
||||
MinBidIncrement: minBidIncrement,
|
||||
}
|
||||
suite.auctionKeeper.SetParams(suite.ctx, params)
|
||||
|
||||
@ -159,7 +181,7 @@ func (suite *IntegrationTestSuite) TestValidateAuctionMsg() {
|
||||
bundle = append(bundle, tx)
|
||||
}
|
||||
|
||||
err := suite.auctionKeeper.ValidateAuctionMsg(suite.ctx, bidder.Address, bid, bundle)
|
||||
err := suite.auctionKeeper.ValidateAuctionMsg(suite.ctx, bidder.Address, bid, highestBid, bundle)
|
||||
if tc.pass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
"github.com/skip-mev/pob/x/auction/ante"
|
||||
"github.com/skip-mev/pob/x/auction/keeper"
|
||||
"github.com/skip-mev/pob/x/auction/types"
|
||||
@ -37,6 +38,8 @@ type IntegrationTestSuite struct {
|
||||
msgServer types.MsgServer
|
||||
key *storetypes.KVStoreKey
|
||||
authorityAccount sdk.AccAddress
|
||||
|
||||
mempool *mempool.AuctionMempool
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
@ -60,7 +63,8 @@ func (suite *IntegrationTestSuite) SetupTest() {
|
||||
err := suite.auctionKeeper.SetParams(suite.ctx, types.DefaultParams())
|
||||
suite.Require().NoError(err)
|
||||
|
||||
suite.AuctionDecorator = ante.NewAuctionDecorator(suite.auctionKeeper, suite.encCfg.TxConfig.TxDecoder())
|
||||
suite.mempool = mempool.NewAuctionMempool(suite.encCfg.TxConfig.TxDecoder(), 0)
|
||||
suite.AuctionDecorator = ante.NewAuctionDecorator(suite.auctionKeeper, suite.encCfg.TxConfig.TxDecoder(), suite.mempool)
|
||||
suite.msgServer = keeper.NewMsgServerImpl(suite.auctionKeeper)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user