mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 16:25:21 +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() {
|
if !a.IsReversePhase() {
|
||||||
return a, sdk.ErrInternal("auction not in reverse phase")
|
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) {
|
if !lot.IsLT(a.Lot) {
|
||||||
return a, sdk.ErrInternal("auction in reverse phase, new bid not less than previous amount")
|
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 {
|
if lot.Denom != a.Lot.Denom {
|
||||||
return a, sdk.ErrInternal("lot denom doesn't match auction")
|
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) {
|
if !lot.IsLT(a.Lot) {
|
||||||
return a, sdk.ErrInternal("lot not smaller than last 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)))
|
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) {
|
func TestCollateralAuctionBasic(t *testing.T) {
|
||||||
// Setup
|
// Setup
|
||||||
_, addrs := app.GeneratePrivKeyAddressPairs(4)
|
_, 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)))
|
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) {
|
func TestStartSurplusAuction(t *testing.T) {
|
||||||
someTime := time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
|
someTime := time.Date(1998, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||||
type args struct {
|
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
|
package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/kava-labs/kava/x/auction/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) {
|
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 {
|
keeper.IterateAuctions(ctx, func(a types.Auction) bool {
|
||||||
auctionsList = append(auctionsList, fmt.Sprintf("%+v", a)) // TODO formatting
|
auctionsList = append(auctionsList, a)
|
||||||
return false
|
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 {
|
type Auction interface {
|
||||||
GetID() uint64
|
GetID() uint64
|
||||||
WithID(uint64) Auction
|
WithID(uint64) Auction
|
||||||
|
GetInitiator() string
|
||||||
|
GetLot() sdk.Coin
|
||||||
|
GetBidder() sdk.AccAddress
|
||||||
|
GetBid() sdk.Coin
|
||||||
GetEndTime() time.Time
|
GetEndTime() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auctions is a slice of auctions.
|
||||||
|
type Auctions []Auction
|
||||||
|
|
||||||
// BaseAuction is a common type shared by all Auctions.
|
// BaseAuction is a common type shared by all Auctions.
|
||||||
type BaseAuction struct {
|
type BaseAuction struct {
|
||||||
ID uint64
|
ID uint64
|
||||||
@ -35,6 +42,18 @@ type BaseAuction struct {
|
|||||||
// GetID is a getter for auction ID.
|
// GetID is a getter for auction ID.
|
||||||
func (a BaseAuction) GetID() uint64 { return a.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.
|
// GetEndTime is a getter for auction end time.
|
||||||
func (a BaseAuction) GetEndTime() time.Time { return a.EndTime }
|
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 default name for parameter store
|
||||||
DefaultParamspace = ModuleName
|
DefaultParamspace = ModuleName
|
||||||
|
|
||||||
|
QuerierRoute = ModuleName
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -16,3 +16,17 @@ type QueryResAuctions []string
|
|||||||
func (n QueryResAuctions) String() string {
|
func (n QueryResAuctions) String() string {
|
||||||
return strings.Join(n[:], "\n")
|
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