mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 05:07:26 +00:00 
			
		
		
		
	Ro address auction todos (#284)
* make auctions not expire without bids * add events * improve genesis state validation * add genesis tests * Keeper auctions test, types auctions test, keeper bidding test * Resolved TODOs, added querier test * Removed 'import x/liquidator' from keeper_test package for circleci * Fixes for lack of liquidator module account in tests * update comment Co-Authored-By: Kevin Davis <karzak@users.noreply.github.com> * add more events attributes * feat: add back bidding on closed auction test * feat: test failed debt/collateral auctions Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com> Co-authored-by: Denali Marsh <denalimarsh@gmail.com>
This commit is contained in:
		
							parent
							
								
									22e168d06a
								
							
						
					
					
						commit
						8128a680cc
					
				@ -294,9 +294,6 @@ func (k Keeper) PlaceReverseBidCollateral(ctx sdk.Context, a types.CollateralAuc
 | 
			
		||||
	if !a.IsReversePhase() {
 | 
			
		||||
		return a, sdk.ErrInternal("auction not in reverse phase")
 | 
			
		||||
	}
 | 
			
		||||
	if lot.IsNegative() {
 | 
			
		||||
		return a, sdk.ErrInternal("can't bid negative amount")
 | 
			
		||||
	}
 | 
			
		||||
	if !lot.IsLT(a.Lot) {
 | 
			
		||||
		return a, sdk.ErrInternal("auction in reverse phase, new bid not less than previous amount")
 | 
			
		||||
	}
 | 
			
		||||
@ -354,9 +351,6 @@ func (k Keeper) PlaceBidDebt(ctx sdk.Context, a types.DebtAuction, bidder sdk.Ac
 | 
			
		||||
	if lot.Denom != a.Lot.Denom {
 | 
			
		||||
		return a, sdk.ErrInternal("lot denom doesn't match auction")
 | 
			
		||||
	}
 | 
			
		||||
	if lot.IsNegative() {
 | 
			
		||||
		return a, sdk.ErrInternal("lot less than 0")
 | 
			
		||||
	}
 | 
			
		||||
	if !lot.IsLT(a.Lot) {
 | 
			
		||||
		return a, sdk.ErrInternal("lot not smaller than last lot")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -100,6 +100,48 @@ func TestDebtAuctionBasic(t *testing.T) {
 | 
			
		||||
	tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 110)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDebtAuctionDebtRemaining(t *testing.T) {
 | 
			
		||||
	// Setup
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(1)
 | 
			
		||||
	seller := addrs[0]
 | 
			
		||||
	buyerModName := cdp.LiquidatorMacc
 | 
			
		||||
	buyerAddr := supply.NewModuleAddress(buyerModName)
 | 
			
		||||
 | 
			
		||||
	tApp := app.NewTestApp()
 | 
			
		||||
 | 
			
		||||
	buyerAcc := supply.NewEmptyModuleAccount(buyerModName, supply.Minter) // reverse auctions mint payout
 | 
			
		||||
	require.NoError(t, buyerAcc.SetCoins(cs(c("debt", 100))))
 | 
			
		||||
	tApp.InitializeFromGenesisStates(
 | 
			
		||||
		NewAuthGenStateFromAccs(authexported.GenesisAccounts{
 | 
			
		||||
			auth.NewBaseAccount(seller, cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			buyerAcc,
 | 
			
		||||
		}),
 | 
			
		||||
	)
 | 
			
		||||
	ctx := tApp.NewContext(false, abci.Header{})
 | 
			
		||||
	keeper := tApp.GetAuctionKeeper()
 | 
			
		||||
 | 
			
		||||
	// Start auction
 | 
			
		||||
	auctionID, err := keeper.StartDebtAuction(ctx, buyerModName, c("token1", 10), c("token2", 99999), c("debt", 20))
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
	// Check buyer's coins have not decreased (except for debt), as lot is minted at the end
 | 
			
		||||
	tApp.CheckBalance(t, ctx, buyerAddr, cs(c("debt", 80)))
 | 
			
		||||
 | 
			
		||||
	// Place a bid
 | 
			
		||||
	require.NoError(t, keeper.PlaceBid(ctx, 0, seller, c("token2", 10)))
 | 
			
		||||
	// Check seller's coins have decreased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, seller, cs(c("token1", 90), c("token2", 100)))
 | 
			
		||||
	// Check buyer's coins have increased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, buyerAddr, cs(c("token1", 10), c("debt", 90)))
 | 
			
		||||
 | 
			
		||||
	// Close auction at just after auction expiry
 | 
			
		||||
	ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultBidDuration))
 | 
			
		||||
	require.NoError(t, keeper.CloseAuction(ctx, auctionID))
 | 
			
		||||
	// Check seller's coins increased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, seller, cs(c("token1", 90), c("token2", 110)))
 | 
			
		||||
	// check that debt has increased due to corresponding debt being greater than bid
 | 
			
		||||
	tApp.CheckBalance(t, ctx, buyerAddr, cs(c("token1", 10), c("debt", 100)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCollateralAuctionBasic(t *testing.T) {
 | 
			
		||||
	// Setup
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(4)
 | 
			
		||||
@ -160,6 +202,59 @@ func TestCollateralAuctionBasic(t *testing.T) {
 | 
			
		||||
	tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 115), c("token2", 50)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCollateralAuctionDebtRemaining(t *testing.T) {
 | 
			
		||||
	// Setup
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(4)
 | 
			
		||||
	buyer := addrs[0]
 | 
			
		||||
	returnAddrs := addrs[1:]
 | 
			
		||||
	returnWeights := is(30, 20, 10)
 | 
			
		||||
	sellerModName := cdp.LiquidatorMacc
 | 
			
		||||
	sellerAddr := supply.NewModuleAddress(sellerModName)
 | 
			
		||||
 | 
			
		||||
	tApp := app.NewTestApp()
 | 
			
		||||
	sellerAcc := supply.NewEmptyModuleAccount(sellerModName)
 | 
			
		||||
	require.NoError(t, sellerAcc.SetCoins(cs(c("token1", 100), c("token2", 100), c("debt", 100))))
 | 
			
		||||
	tApp.InitializeFromGenesisStates(
 | 
			
		||||
		NewAuthGenStateFromAccs(authexported.GenesisAccounts{
 | 
			
		||||
			auth.NewBaseAccount(buyer, cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(returnAddrs[0], cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(returnAddrs[1], cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(returnAddrs[2], cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			sellerAcc,
 | 
			
		||||
		}),
 | 
			
		||||
	)
 | 
			
		||||
	ctx := tApp.NewContext(false, abci.Header{})
 | 
			
		||||
	keeper := tApp.GetAuctionKeeper()
 | 
			
		||||
 | 
			
		||||
	// Start auction
 | 
			
		||||
	auctionID, err := keeper.StartCollateralAuction(ctx, sellerModName, c("token1", 20), c("token2", 50), returnAddrs, returnWeights, c("debt", 40))
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
	// Check seller's coins have decreased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 100), c("debt", 60)))
 | 
			
		||||
 | 
			
		||||
	// Place a forward bid
 | 
			
		||||
	require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 10)))
 | 
			
		||||
	// Check bidder's coins have decreased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 90)))
 | 
			
		||||
	// Check seller's coins have increased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 110), c("debt", 70)))
 | 
			
		||||
	// Check return addresses have not received coins
 | 
			
		||||
	for _, ra := range returnAddrs {
 | 
			
		||||
		tApp.CheckBalance(t, ctx, ra, cs(c("token1", 100), c("token2", 100)))
 | 
			
		||||
	}
 | 
			
		||||
	ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultBidDuration))
 | 
			
		||||
	require.NoError(t, keeper.CloseAuction(ctx, auctionID))
 | 
			
		||||
 | 
			
		||||
	// check that buyers coins have increased
 | 
			
		||||
	tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 120), c("token2", 90)))
 | 
			
		||||
	// Check return addresses have not received coins
 | 
			
		||||
	for _, ra := range returnAddrs {
 | 
			
		||||
		tApp.CheckBalance(t, ctx, ra, cs(c("token1", 100), c("token2", 100)))
 | 
			
		||||
	}
 | 
			
		||||
	// check that token2 has increased by 10, debt by 40, for a net debt increase of 30 debt
 | 
			
		||||
	tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 110), c("debt", 100)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestStartSurplusAuction(t *testing.T) {
 | 
			
		||||
	someTime := time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
 | 
			
		||||
	type args struct {
 | 
			
		||||
@ -247,3 +342,68 @@ func TestStartSurplusAuction(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCloseAuction(t *testing.T) {
 | 
			
		||||
	// Set up
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(1)
 | 
			
		||||
	buyer := addrs[0]
 | 
			
		||||
	sellerModName := cdp.LiquidatorMacc
 | 
			
		||||
 | 
			
		||||
	tApp := app.NewTestApp()
 | 
			
		||||
 | 
			
		||||
	sellerAcc := supply.NewEmptyModuleAccount(sellerModName, supply.Burner) // forward auctions burn proceeds
 | 
			
		||||
	require.NoError(t, sellerAcc.SetCoins(cs(c("token1", 100), c("token2", 100))))
 | 
			
		||||
	tApp.InitializeFromGenesisStates(
 | 
			
		||||
		NewAuthGenStateFromAccs(authexported.GenesisAccounts{
 | 
			
		||||
			auth.NewBaseAccount(buyer, cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			sellerAcc,
 | 
			
		||||
		}),
 | 
			
		||||
	)
 | 
			
		||||
	ctx := tApp.NewContext(false, abci.Header{})
 | 
			
		||||
	keeper := tApp.GetAuctionKeeper()
 | 
			
		||||
 | 
			
		||||
	// Create an auction (lot: 20 token1, initialBid: 0 token2)
 | 
			
		||||
	id, err := keeper.StartSurplusAuction(ctx, sellerModName, c("token1", 20), "token2") // lot, bid denom
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	// Attempt to close the auction before EndTime
 | 
			
		||||
	require.Error(t, keeper.CloseAuction(ctx, id))
 | 
			
		||||
 | 
			
		||||
	// Attempt to close auction that does not exist
 | 
			
		||||
	require.Error(t, keeper.CloseAuction(ctx, 999))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestCloseExpiredAuctions(t *testing.T) {
 | 
			
		||||
	// Set up
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(1)
 | 
			
		||||
	buyer := addrs[0]
 | 
			
		||||
	sellerModName := "liquidator"
 | 
			
		||||
 | 
			
		||||
	tApp := app.NewTestApp()
 | 
			
		||||
 | 
			
		||||
	sellerAcc := supply.NewEmptyModuleAccount(sellerModName, supply.Burner) // forward auctions burn proceeds
 | 
			
		||||
	require.NoError(t, sellerAcc.SetCoins(cs(c("token1", 100), c("token2", 100))))
 | 
			
		||||
	tApp.InitializeFromGenesisStates(
 | 
			
		||||
		NewAuthGenStateFromAccs(authexported.GenesisAccounts{
 | 
			
		||||
			auth.NewBaseAccount(buyer, cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
 | 
			
		||||
			sellerAcc,
 | 
			
		||||
		}),
 | 
			
		||||
	)
 | 
			
		||||
	ctx := tApp.NewContext(false, abci.Header{})
 | 
			
		||||
	keeper := tApp.GetAuctionKeeper()
 | 
			
		||||
 | 
			
		||||
	// Start auction 1
 | 
			
		||||
	_, err := keeper.StartSurplusAuction(ctx, sellerModName, c("token1", 20), "token2") // lot, bid denom
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	// Start auction 2
 | 
			
		||||
	_, err = keeper.StartSurplusAuction(ctx, sellerModName, c("token1", 20), "token2") // lot, bid denom
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	// Fast forward the block time
 | 
			
		||||
	ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxAuctionDuration).Add(1))
 | 
			
		||||
 | 
			
		||||
	// Close expired auctions
 | 
			
		||||
	err = keeper.CloseExpiredAuctions(ctx)
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										349
									
								
								x/auction/keeper/bidding_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								x/auction/keeper/bidding_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,349 @@
 | 
			
		||||
package keeper_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth"
 | 
			
		||||
	authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/supply"
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
	abci "github.com/tendermint/tendermint/abci/types"
 | 
			
		||||
 | 
			
		||||
	"github.com/kava-labs/kava/app"
 | 
			
		||||
	"github.com/kava-labs/kava/x/auction/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type AuctionType int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	Invalid          AuctionType = 0
 | 
			
		||||
	Surplus          AuctionType = 1
 | 
			
		||||
	Debt             AuctionType = 2
 | 
			
		||||
	CollateralPhase1 AuctionType = 3
 | 
			
		||||
	CollateralPhase2 AuctionType = 4
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestAuctionBidding(t *testing.T) {
 | 
			
		||||
	someTime := time.Date(0001, time.January, 1, 0, 0, 0, 0, time.UTC)
 | 
			
		||||
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(5)
 | 
			
		||||
	buyer := addrs[0]
 | 
			
		||||
	secondBuyer := addrs[1]
 | 
			
		||||
	modName := "liquidator"
 | 
			
		||||
	collateralAddrs := addrs[2:]
 | 
			
		||||
	collateralWeights := is(30, 20, 10)
 | 
			
		||||
 | 
			
		||||
	tApp := app.NewTestApp()
 | 
			
		||||
 | 
			
		||||
	// Set up seller account
 | 
			
		||||
	sellerAcc := supply.NewEmptyModuleAccount(modName, supply.Minter, supply.Burner)
 | 
			
		||||
	require.NoError(t, sellerAcc.SetCoins(cs(c("token1", 1000), c("token2", 1000), c("debt", 1000))))
 | 
			
		||||
 | 
			
		||||
	// Initialize genesis accounts
 | 
			
		||||
	tApp.InitializeFromGenesisStates(
 | 
			
		||||
		NewAuthGenStateFromAccs(authexported.GenesisAccounts{
 | 
			
		||||
			auth.NewBaseAccount(buyer, cs(c("token1", 1000), c("token2", 1000)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(secondBuyer, cs(c("token1", 1000), c("token2", 1000)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(collateralAddrs[0], cs(c("token1", 1000), c("token2", 1000)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(collateralAddrs[1], cs(c("token1", 1000), c("token2", 1000)), nil, 0, 0),
 | 
			
		||||
			auth.NewBaseAccount(collateralAddrs[2], cs(c("token1", 1000), c("token2", 1000)), nil, 0, 0),
 | 
			
		||||
			sellerAcc,
 | 
			
		||||
		}),
 | 
			
		||||
	)
 | 
			
		||||
	ctx := tApp.NewContext(false, abci.Header{})
 | 
			
		||||
	keeper := tApp.GetAuctionKeeper()
 | 
			
		||||
 | 
			
		||||
	type auctionArgs struct {
 | 
			
		||||
		auctionType AuctionType
 | 
			
		||||
		seller      string
 | 
			
		||||
		lot         sdk.Coin
 | 
			
		||||
		bid         sdk.Coin
 | 
			
		||||
		debt        sdk.Coin
 | 
			
		||||
		addresses   []sdk.AccAddress
 | 
			
		||||
		weights     []sdk.Int
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	type bidArgs struct {
 | 
			
		||||
		bidder       sdk.AccAddress
 | 
			
		||||
		amount       sdk.Coin
 | 
			
		||||
		secondBidder sdk.AccAddress
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name            string
 | 
			
		||||
		auctionArgs     auctionArgs
 | 
			
		||||
		bidArgs         bidArgs
 | 
			
		||||
		expectedError   string
 | 
			
		||||
		expectedEndTime time.Time
 | 
			
		||||
		expectedBidder  sdk.AccAddress
 | 
			
		||||
		expectedBid     sdk.Coin
 | 
			
		||||
		expectpass      bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"basic: auction doesn't exist",
 | 
			
		||||
			auctionArgs{Surplus, "", c("token1", 1), c("token2", 1), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("token2", 10), nil},
 | 
			
		||||
			"auction doesn't exist",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"surplus: normal",
 | 
			
		||||
			auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("token2", 10), nil},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"surplus: second bidder",
 | 
			
		||||
			auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("token2", 10), secondBuyer},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			secondBuyer,
 | 
			
		||||
			c("token2", 11),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"surplus: invalid bid denom",
 | 
			
		||||
			auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("badtoken", 10), nil},
 | 
			
		||||
			"bid denom doesn't match auction",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"surplus: invalid bid (equal)",
 | 
			
		||||
			auctionArgs{Surplus, modName, c("token1", 100), c("token2", 0), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("token2", 0), nil},
 | 
			
		||||
			"bid not greater than last bid",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"debt: normal",
 | 
			
		||||
			auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot
 | 
			
		||||
			bidArgs{buyer, c("token1", 10), nil},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 100),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"debt: second bidder",
 | 
			
		||||
			auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot
 | 
			
		||||
			bidArgs{buyer, c("token1", 10), secondBuyer},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			secondBuyer,
 | 
			
		||||
			c("token2", 100),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"debt: invalid lot denom",
 | 
			
		||||
			auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}}, // initial bid, lot
 | 
			
		||||
			bidArgs{buyer, c("badtoken", 10), nil},
 | 
			
		||||
			"lot denom doesn't match auction",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token1", 20),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"debt: invalid lot size (larger)",
 | 
			
		||||
			auctionArgs{Debt, modName, c("token1", 20), c("token2", 100), c("debt", 20), []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("token1", 21), nil},
 | 
			
		||||
			"lot not smaller than last lot",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token1", 20),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [forward]: normal",
 | 
			
		||||
			auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token2", 10), nil},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [forward]: second bidder",
 | 
			
		||||
			auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token2", 10), secondBuyer},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			secondBuyer,
 | 
			
		||||
			c("token2", 11),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [forward]: invalid bid denom",
 | 
			
		||||
			auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("badtoken", 10), nil},
 | 
			
		||||
			"bid denom doesn't match auction",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [forward]: invalid bid size (smaller)",
 | 
			
		||||
			auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token2", 0), nil},                                                                                          // lot, bid
 | 
			
		||||
			"auction in forward phase, new bid not higher than last bid",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [forward]: invalid bid size (greater than max)",
 | 
			
		||||
			auctionArgs{CollateralPhase1, modName, c("token1", 20), c("token2", 100), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token2", 101), nil},                                                                                        // lot, bid
 | 
			
		||||
			"bid higher than max bid",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [reverse]: normal",
 | 
			
		||||
			auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token1", 15), nil},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 50),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [reverse]: second bidder",
 | 
			
		||||
			auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token1", 15), secondBuyer},
 | 
			
		||||
			"",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			secondBuyer,
 | 
			
		||||
			c("token2", 50),
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [reverse]: invalid lot denom",
 | 
			
		||||
			auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("badtoken", 15), nil},
 | 
			
		||||
			"lot denom doesn't match auction",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 50),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [reverse]: invalid lot size (equal)",
 | 
			
		||||
			auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token1", 20), nil},
 | 
			
		||||
			"auction in reverse phase, new bid not less than previous amount",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 50),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"collateral [reverse]: invalid lot size (greater)",
 | 
			
		||||
			auctionArgs{CollateralPhase2, modName, c("token1", 20), c("token2", 50), c("debt", 50), collateralAddrs, collateralWeights}, // lot, max bid
 | 
			
		||||
			bidArgs{buyer, c("token1", 21), nil},
 | 
			
		||||
			"auction in reverse phase, new bid not less than previous amount",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 50),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"basic: closed auction",
 | 
			
		||||
			auctionArgs{Surplus, modName, c("token1", 100), c("token2", 10), sdk.Coin{}, []sdk.AccAddress{}, []sdk.Int{}},
 | 
			
		||||
			bidArgs{buyer, c("token2", 10), nil},
 | 
			
		||||
			"auction has closed",
 | 
			
		||||
			someTime.Add(types.DefaultBidDuration),
 | 
			
		||||
			buyer,
 | 
			
		||||
			c("token2", 10),
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tc := range tests {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			// Start Auction
 | 
			
		||||
			var id uint64
 | 
			
		||||
			var err error
 | 
			
		||||
			switch tc.auctionArgs.auctionType {
 | 
			
		||||
			case Surplus:
 | 
			
		||||
				id, _ = keeper.StartSurplusAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid.Denom)
 | 
			
		||||
			case Debt:
 | 
			
		||||
				id, _ = keeper.StartDebtAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.bid, tc.auctionArgs.lot, tc.auctionArgs.debt)
 | 
			
		||||
			case CollateralPhase1, CollateralPhase2:
 | 
			
		||||
				id, _ = keeper.StartCollateralAuction(ctx, tc.auctionArgs.seller, tc.auctionArgs.lot, tc.auctionArgs.bid, tc.auctionArgs.addresses, tc.auctionArgs.weights, tc.auctionArgs.debt) // seller, lot, maxBid, otherPerson
 | 
			
		||||
				// Move CollateralAuction to debt phase by placing max bid
 | 
			
		||||
				if tc.auctionArgs.auctionType == CollateralPhase2 {
 | 
			
		||||
					err = keeper.PlaceBid(ctx, id, tc.bidArgs.bidder, tc.auctionArgs.bid)
 | 
			
		||||
					require.NoError(t, err)
 | 
			
		||||
				}
 | 
			
		||||
			default:
 | 
			
		||||
				t.Fail()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Close the auction early to test late bidding (if applicable)
 | 
			
		||||
			if strings.Contains(tc.name, "closed") {
 | 
			
		||||
				ctx = ctx.WithBlockTime(types.DistantFuture.Add(1))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Place bid on auction
 | 
			
		||||
			err = keeper.PlaceBid(ctx, id, tc.bidArgs.bidder, tc.bidArgs.amount)
 | 
			
		||||
 | 
			
		||||
			// Place second bid from new bidder
 | 
			
		||||
			if tc.bidArgs.secondBidder != nil {
 | 
			
		||||
				// Set bid increase/decrease based on auction type, phase
 | 
			
		||||
				var secondBid sdk.Coin
 | 
			
		||||
				switch tc.auctionArgs.auctionType {
 | 
			
		||||
				case Surplus, CollateralPhase1:
 | 
			
		||||
					secondBid = tc.bidArgs.amount.Add(c(tc.bidArgs.amount.Denom, 1))
 | 
			
		||||
				case Debt, CollateralPhase2:
 | 
			
		||||
					secondBid = tc.bidArgs.amount.Sub(c(tc.bidArgs.amount.Denom, 1))
 | 
			
		||||
				default:
 | 
			
		||||
					t.Fail()
 | 
			
		||||
				}
 | 
			
		||||
				// Place the second bid
 | 
			
		||||
				err2 := keeper.PlaceBid(ctx, id, tc.bidArgs.secondBidder, secondBid)
 | 
			
		||||
				require.NoError(t, err2)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Check success/failure
 | 
			
		||||
			if tc.expectpass {
 | 
			
		||||
				require.Nil(t, err)
 | 
			
		||||
				// Get auction from store
 | 
			
		||||
				auction, found := keeper.GetAuction(ctx, id)
 | 
			
		||||
				require.True(t, found)
 | 
			
		||||
				// Check auction values
 | 
			
		||||
				require.Equal(t, modName, auction.GetInitiator())
 | 
			
		||||
				require.Equal(t, tc.expectedBidder, auction.GetBidder())
 | 
			
		||||
				require.Equal(t, tc.expectedBid, auction.GetBid())
 | 
			
		||||
				require.Equal(t, tc.expectedEndTime, auction.GetEndTime())
 | 
			
		||||
			} else {
 | 
			
		||||
				// Check expected error message
 | 
			
		||||
				require.Contains(t, err.Error(), tc.expectedError)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
package keeper
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/codec"
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/kava-labs/kava/x/auction/types"
 | 
			
		||||
@ -21,10 +20,10 @@ func NewQuerier(keeper Keeper) sdk.Querier {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func queryAuctions(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
 | 
			
		||||
	var auctionsList types.QueryResAuctions
 | 
			
		||||
	var auctionsList types.Auctions
 | 
			
		||||
 | 
			
		||||
	keeper.IterateAuctions(ctx, func(a types.Auction) bool {
 | 
			
		||||
		auctionsList = append(auctionsList, fmt.Sprintf("%+v", a)) // TODO formatting
 | 
			
		||||
		auctionsList = append(auctionsList, a)
 | 
			
		||||
		return false
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										104
									
								
								x/auction/keeper/querier_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								x/auction/keeper/querier_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
			
		||||
package keeper_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth"
 | 
			
		||||
	authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/simulation"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/supply"
 | 
			
		||||
	"github.com/kava-labs/kava/app"
 | 
			
		||||
	"github.com/kava-labs/kava/x/auction/keeper"
 | 
			
		||||
	"github.com/kava-labs/kava/x/auction/types"
 | 
			
		||||
	"github.com/kava-labs/kava/x/cdp"
 | 
			
		||||
	"github.com/stretchr/testify/suite"
 | 
			
		||||
	abci "github.com/tendermint/tendermint/abci/types"
 | 
			
		||||
	tmtime "github.com/tendermint/tendermint/types/time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	custom           = "custom"
 | 
			
		||||
	TestAuctionCount = 10
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type QuerierTestSuite struct {
 | 
			
		||||
	suite.Suite
 | 
			
		||||
 | 
			
		||||
	keeper   keeper.Keeper
 | 
			
		||||
	app      app.TestApp
 | 
			
		||||
	auctions types.Auctions
 | 
			
		||||
	ctx      sdk.Context
 | 
			
		||||
	querier  sdk.Querier
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *QuerierTestSuite) SetupTest() {
 | 
			
		||||
	tApp := app.NewTestApp()
 | 
			
		||||
	ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
 | 
			
		||||
 | 
			
		||||
	_, addrs := app.GeneratePrivKeyAddressPairs(1)
 | 
			
		||||
	buyer := addrs[0]
 | 
			
		||||
	modName := cdp.LiquidatorMacc
 | 
			
		||||
 | 
			
		||||
	// Set up seller account
 | 
			
		||||
	sellerAcc := supply.NewEmptyModuleAccount(modName, supply.Minter, supply.Burner)
 | 
			
		||||
	sellerAcc.SetCoins(cs(c("token1", 1000), c("token2", 1000), c("debt", 1000)))
 | 
			
		||||
 | 
			
		||||
	// Initialize genesis accounts
 | 
			
		||||
	tApp.InitializeFromGenesisStates(
 | 
			
		||||
		NewAuthGenStateFromAccs(authexported.GenesisAccounts{
 | 
			
		||||
			auth.NewBaseAccount(buyer, cs(c("token1", 1000), c("token2", 1000)), nil, 0, 0),
 | 
			
		||||
			sellerAcc,
 | 
			
		||||
		}),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	suite.ctx = ctx
 | 
			
		||||
	suite.app = tApp
 | 
			
		||||
	suite.keeper = tApp.GetAuctionKeeper()
 | 
			
		||||
 | 
			
		||||
	// Populate with auctions
 | 
			
		||||
	for j := 0; j < TestAuctionCount; j++ {
 | 
			
		||||
		lotAmount := simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 10, 100)
 | 
			
		||||
		id, err := suite.keeper.StartSurplusAuction(suite.ctx, modName, c("token1", int64(lotAmount)), "token2")
 | 
			
		||||
		suite.Nil(err)
 | 
			
		||||
 | 
			
		||||
		auc, found := suite.keeper.GetAuction(suite.ctx, id)
 | 
			
		||||
		suite.True(found)
 | 
			
		||||
		suite.auctions = append(suite.auctions, auc)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	suite.querier = keeper.NewQuerier(suite.keeper)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *QuerierTestSuite) TestQueryAuctions() {
 | 
			
		||||
	ctx := suite.ctx.WithIsCheckTx(false)
 | 
			
		||||
	// Set up request query
 | 
			
		||||
	query := abci.RequestQuery{
 | 
			
		||||
		Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetAuction}, "/"),
 | 
			
		||||
		Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryAllAuctionParams(1, TestAuctionCount)),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Execute query and check the []byte result
 | 
			
		||||
	bz, err := suite.querier(ctx, []string{types.QueryGetAuction}, query)
 | 
			
		||||
	suite.NoError(err)
 | 
			
		||||
	suite.NotNil(bz)
 | 
			
		||||
 | 
			
		||||
	// Unmarshal the bytes into type Auctions
 | 
			
		||||
	var auctions types.Auctions
 | 
			
		||||
	suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &auctions))
 | 
			
		||||
 | 
			
		||||
	// Check that each Auction has correct values
 | 
			
		||||
	for i := 0; i < TestAuctionCount; i++ {
 | 
			
		||||
		suite.Equal(suite.auctions[i].GetID(), auctions[i].GetID())
 | 
			
		||||
		suite.Equal(suite.auctions[i].GetInitiator(), auctions[i].GetInitiator())
 | 
			
		||||
		suite.Equal(suite.auctions[i].GetLot(), auctions[i].GetLot())
 | 
			
		||||
		suite.Equal(suite.auctions[i].GetBid(), auctions[i].GetBid())
 | 
			
		||||
		suite.Equal(suite.auctions[i].GetEndTime(), auctions[i].GetEndTime())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestQuerierTestSuite(t *testing.T) {
 | 
			
		||||
	suite.Run(t, new(QuerierTestSuite))
 | 
			
		||||
}
 | 
			
		||||
@ -17,9 +17,16 @@ var DistantFuture time.Time = time.Date(9000, 1, 1, 0, 0, 0, 0, time.UTC)
 | 
			
		||||
type Auction interface {
 | 
			
		||||
	GetID() uint64
 | 
			
		||||
	WithID(uint64) Auction
 | 
			
		||||
	GetInitiator() string
 | 
			
		||||
	GetLot() sdk.Coin
 | 
			
		||||
	GetBidder() sdk.AccAddress
 | 
			
		||||
	GetBid() sdk.Coin
 | 
			
		||||
	GetEndTime() time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Auctions is a slice of auctions.
 | 
			
		||||
type Auctions []Auction
 | 
			
		||||
 | 
			
		||||
// BaseAuction is a common type shared by all Auctions.
 | 
			
		||||
type BaseAuction struct {
 | 
			
		||||
	ID              uint64
 | 
			
		||||
@ -35,6 +42,18 @@ type BaseAuction struct {
 | 
			
		||||
// GetID is a getter for auction ID.
 | 
			
		||||
func (a BaseAuction) GetID() uint64 { return a.ID }
 | 
			
		||||
 | 
			
		||||
// GetInitiator is a getter for auction Initiator.
 | 
			
		||||
func (a BaseAuction) GetInitiator() string { return a.Initiator }
 | 
			
		||||
 | 
			
		||||
// GetLot is a getter for auction Lot.
 | 
			
		||||
func (a BaseAuction) GetLot() sdk.Coin { return a.Lot }
 | 
			
		||||
 | 
			
		||||
// GetBidder is a getter for auction Bidder.
 | 
			
		||||
func (a BaseAuction) GetBidder() sdk.AccAddress { return a.Bidder }
 | 
			
		||||
 | 
			
		||||
// GetBid is a getter for auction Bid.
 | 
			
		||||
func (a BaseAuction) GetBid() sdk.Coin { return a.Bid }
 | 
			
		||||
 | 
			
		||||
// GetEndTime is a getter for auction end time.
 | 
			
		||||
func (a BaseAuction) GetEndTime() time.Time { return a.EndTime }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										195
									
								
								x/auction/types/auctions_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								x/auction/types/auctions_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,195 @@
 | 
			
		||||
package types
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	TestInitiatorModuleName = "liquidator"
 | 
			
		||||
	TestLotDenom            = "usdx"
 | 
			
		||||
	TestLotAmount           = 100
 | 
			
		||||
	TestBidDenom            = "kava"
 | 
			
		||||
	TestBidAmount           = 20
 | 
			
		||||
	TestDebtDenom           = "debt"
 | 
			
		||||
	TestDebtAmount1         = 20
 | 
			
		||||
	TestDebtAmount2         = 15
 | 
			
		||||
	TestExtraEndTime        = 10000
 | 
			
		||||
	TestAuctionID           = 9999123
 | 
			
		||||
	TestAccAddress1         = "kava1qcfdf69js922qrdr4yaww3ax7gjml6pd39p8lj"
 | 
			
		||||
	TestAccAddress2         = "kava1pdfav2cjhry9k79nu6r8kgknnjtq6a7rcr0qlr"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestNewWeightedAddresses(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name       string
 | 
			
		||||
		addresses  []sdk.AccAddress
 | 
			
		||||
		weights    []sdk.Int
 | 
			
		||||
		expectpass bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"normal",
 | 
			
		||||
			[]sdk.AccAddress{
 | 
			
		||||
				sdk.AccAddress([]byte(TestAccAddress1)),
 | 
			
		||||
				sdk.AccAddress([]byte(TestAccAddress2)),
 | 
			
		||||
			},
 | 
			
		||||
			[]sdk.Int{
 | 
			
		||||
				sdk.NewInt(6),
 | 
			
		||||
				sdk.NewInt(8),
 | 
			
		||||
			},
 | 
			
		||||
			true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"mismatched",
 | 
			
		||||
			[]sdk.AccAddress{
 | 
			
		||||
				sdk.AccAddress([]byte(TestAccAddress1)),
 | 
			
		||||
				sdk.AccAddress([]byte(TestAccAddress2)),
 | 
			
		||||
			},
 | 
			
		||||
			[]sdk.Int{
 | 
			
		||||
				sdk.NewInt(6),
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"negativeWeight",
 | 
			
		||||
			[]sdk.AccAddress{
 | 
			
		||||
				sdk.AccAddress([]byte(TestAccAddress1)),
 | 
			
		||||
				sdk.AccAddress([]byte(TestAccAddress2)),
 | 
			
		||||
			},
 | 
			
		||||
			[]sdk.Int{
 | 
			
		||||
				sdk.NewInt(6),
 | 
			
		||||
				sdk.NewInt(-8),
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Run NewWeightedAdresses tests
 | 
			
		||||
	for _, tc := range tests {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			// Attempt to instantiate new WeightedAddresses
 | 
			
		||||
			weightedAddresses, err := NewWeightedAddresses(tc.addresses, tc.weights)
 | 
			
		||||
 | 
			
		||||
			if tc.expectpass {
 | 
			
		||||
				// Confirm there is no error
 | 
			
		||||
				require.Nil(t, err)
 | 
			
		||||
 | 
			
		||||
				// Check addresses, weights
 | 
			
		||||
				require.Equal(t, tc.addresses, weightedAddresses.Addresses)
 | 
			
		||||
				require.Equal(t, tc.weights, weightedAddresses.Weights)
 | 
			
		||||
			} else {
 | 
			
		||||
				// Confirm that there is an error
 | 
			
		||||
				require.NotNil(t, err)
 | 
			
		||||
 | 
			
		||||
				switch tc.name {
 | 
			
		||||
				case "mismatched":
 | 
			
		||||
					require.Contains(t, err.Error(), "number of addresses doesn't match number of weights")
 | 
			
		||||
				case "negativeWeight":
 | 
			
		||||
					require.Contains(t, err.Error(), "weights contain a negative amount")
 | 
			
		||||
				default:
 | 
			
		||||
					// Unexpected error state
 | 
			
		||||
					t.Fail()
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestBaseAuctionGetters(t *testing.T) {
 | 
			
		||||
	endTime := time.Now().Add(TestExtraEndTime)
 | 
			
		||||
 | 
			
		||||
	// Create a new BaseAuction (via SurplusAuction)
 | 
			
		||||
	auction := NewSurplusAuction(
 | 
			
		||||
		TestInitiatorModuleName,
 | 
			
		||||
		c(TestLotDenom, TestLotAmount),
 | 
			
		||||
		TestBidDenom, endTime,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	auctionID := auction.GetID()
 | 
			
		||||
	auctionBid := auction.GetBid()
 | 
			
		||||
	auctionLot := auction.GetLot()
 | 
			
		||||
	auctionEndTime := auction.GetEndTime()
 | 
			
		||||
	auctionString := auction.String()
 | 
			
		||||
 | 
			
		||||
	require.Equal(t, auction.ID, auctionID)
 | 
			
		||||
	require.Equal(t, auction.Bid, auctionBid)
 | 
			
		||||
	require.Equal(t, auction.Lot, auctionLot)
 | 
			
		||||
	require.Equal(t, auction.EndTime, auctionEndTime)
 | 
			
		||||
	require.NotNil(t, auctionString)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewSurplusAuction(t *testing.T) {
 | 
			
		||||
	endTime := time.Now().Add(TestExtraEndTime)
 | 
			
		||||
 | 
			
		||||
	// Create a new SurplusAuction
 | 
			
		||||
	surplusAuction := NewSurplusAuction(
 | 
			
		||||
		TestInitiatorModuleName,
 | 
			
		||||
		c(TestLotDenom, TestLotAmount),
 | 
			
		||||
		TestBidDenom, endTime,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	require.Equal(t, surplusAuction.Initiator, TestInitiatorModuleName)
 | 
			
		||||
	require.Equal(t, surplusAuction.Lot, c(TestLotDenom, TestLotAmount))
 | 
			
		||||
	require.Equal(t, surplusAuction.Bid, c(TestBidDenom, 0))
 | 
			
		||||
	require.Equal(t, surplusAuction.EndTime, endTime)
 | 
			
		||||
	require.Equal(t, surplusAuction.MaxEndTime, endTime)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewDebtAuction(t *testing.T) {
 | 
			
		||||
	endTime := time.Now().Add(TestExtraEndTime)
 | 
			
		||||
 | 
			
		||||
	// Create a new DebtAuction
 | 
			
		||||
	debtAuction := NewDebtAuction(
 | 
			
		||||
		TestInitiatorModuleName,
 | 
			
		||||
		c(TestBidDenom, TestBidAmount),
 | 
			
		||||
		c(TestLotDenom, TestLotAmount),
 | 
			
		||||
		endTime,
 | 
			
		||||
		c(TestDebtDenom, TestDebtAmount1),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	require.Equal(t, debtAuction.Initiator, TestInitiatorModuleName)
 | 
			
		||||
	require.Equal(t, debtAuction.Lot, c(TestLotDenom, TestLotAmount))
 | 
			
		||||
	require.Equal(t, debtAuction.Bid, c(TestBidDenom, TestBidAmount))
 | 
			
		||||
	require.Equal(t, debtAuction.EndTime, endTime)
 | 
			
		||||
	require.Equal(t, debtAuction.MaxEndTime, endTime)
 | 
			
		||||
	require.Equal(t, debtAuction.CorrespondingDebt, c(TestDebtDenom, TestDebtAmount1))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNewCollateralAuction(t *testing.T) {
 | 
			
		||||
	// Set up WeightedAddresses
 | 
			
		||||
	addresses := []sdk.AccAddress{
 | 
			
		||||
		sdk.AccAddress([]byte(TestAccAddress1)),
 | 
			
		||||
		sdk.AccAddress([]byte(TestAccAddress2)),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	weights := []sdk.Int{
 | 
			
		||||
		sdk.NewInt(6),
 | 
			
		||||
		sdk.NewInt(8),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	weightedAddresses, _ := NewWeightedAddresses(addresses, weights)
 | 
			
		||||
 | 
			
		||||
	endTime := time.Now().Add(TestExtraEndTime)
 | 
			
		||||
 | 
			
		||||
	collateralAuction := NewCollateralAuction(
 | 
			
		||||
		TestInitiatorModuleName,
 | 
			
		||||
		c(TestLotDenom, TestLotAmount),
 | 
			
		||||
		endTime,
 | 
			
		||||
		c(TestBidDenom, TestBidAmount),
 | 
			
		||||
		weightedAddresses,
 | 
			
		||||
		c(TestDebtDenom, TestDebtAmount2),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	require.Equal(t, collateralAuction.BaseAuction.Initiator, TestInitiatorModuleName)
 | 
			
		||||
	require.Equal(t, collateralAuction.BaseAuction.Lot, c(TestLotDenom, TestLotAmount))
 | 
			
		||||
	require.Equal(t, collateralAuction.BaseAuction.Bid, c(TestBidDenom, 0))
 | 
			
		||||
	require.Equal(t, collateralAuction.BaseAuction.EndTime, endTime)
 | 
			
		||||
	require.Equal(t, collateralAuction.BaseAuction.MaxEndTime, endTime)
 | 
			
		||||
	require.Equal(t, collateralAuction.MaxBid, c(TestBidDenom, TestBidAmount))
 | 
			
		||||
	require.Equal(t, collateralAuction.LotReturns, weightedAddresses)
 | 
			
		||||
	require.Equal(t, collateralAuction.CorrespondingDebt, c(TestDebtDenom, TestDebtAmount2))
 | 
			
		||||
}
 | 
			
		||||
@ -19,6 +19,8 @@ const (
 | 
			
		||||
 | 
			
		||||
	// DefaultParamspace default name for parameter store
 | 
			
		||||
	DefaultParamspace = ModuleName
 | 
			
		||||
 | 
			
		||||
	QuerierRoute = ModuleName
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
 | 
			
		||||
@ -16,3 +16,17 @@ type QueryResAuctions []string
 | 
			
		||||
func (n QueryResAuctions) String() string {
 | 
			
		||||
	return strings.Join(n[:], "\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// QueryAllAuctionParams is the params for an auctions query
 | 
			
		||||
type QueryAllAuctionParams struct {
 | 
			
		||||
	Page  int `json"page:" yaml:"page"`
 | 
			
		||||
	Limit int `json"limit:" yaml:"limit"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewQueryAllAuctionParams creates a new QueryAllAuctionParams
 | 
			
		||||
func NewQueryAllAuctionParams(page int, limit int) QueryAllAuctionParams {
 | 
			
		||||
	return QueryAllAuctionParams{
 | 
			
		||||
		Page:  page,
 | 
			
		||||
		Limit: limit,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user