mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 15:55:18 +00:00
add basic auction tests
This commit is contained in:
parent
ac27571d15
commit
0d72f47bc2
10
app/app.go
10
app/app.go
@ -61,7 +61,7 @@ var (
|
||||
supply.AppModuleBasic{},
|
||||
auction.AppModuleBasic{},
|
||||
cdp.AppModuleBasic{},
|
||||
liquidator.AppModuleBasic{},
|
||||
//liquidator.AppModuleBasic{},
|
||||
pricefeed.AppModuleBasic{},
|
||||
)
|
||||
|
||||
@ -74,6 +74,8 @@ var (
|
||||
staking.NotBondedPoolName: {supply.Burner, supply.Staking},
|
||||
gov.ModuleName: {supply.Burner},
|
||||
validatorvesting.ModuleName: {supply.Burner},
|
||||
auction.ModuleName: nil,
|
||||
liquidator.ModuleName: {supply.Minter, supply.Burner},
|
||||
}
|
||||
)
|
||||
|
||||
@ -238,7 +240,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
app.auctionKeeper = auction.NewKeeper(
|
||||
app.cdc,
|
||||
keys[auction.StoreKey],
|
||||
app.supplyKeeper, // CDP keeper standing in for bank
|
||||
app.supplyKeeper,
|
||||
auctionSubspace)
|
||||
// app.liquidatorKeeper = liquidator.NewKeeper(
|
||||
// app.cdc,
|
||||
@ -269,7 +271,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
validatorvesting.NewAppModule(app.vvKeeper, app.accountKeeper),
|
||||
auction.NewAppModule(app.auctionKeeper),
|
||||
cdp.NewAppModule(app.cdpKeeper, app.pricefeedKeeper),
|
||||
liquidator.NewAppModule(app.liquidatorKeeper),
|
||||
//liquidator.NewAppModule(app.liquidatorKeeper),
|
||||
pricefeed.NewAppModule(app.pricefeedKeeper),
|
||||
)
|
||||
|
||||
@ -289,7 +291,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
auth.ModuleName, validatorvesting.ModuleName, distr.ModuleName,
|
||||
staking.ModuleName, bank.ModuleName, slashing.ModuleName,
|
||||
gov.ModuleName, mint.ModuleName, supply.ModuleName, crisis.ModuleName, genutil.ModuleName,
|
||||
pricefeed.ModuleName, cdp.ModuleName, auction.ModuleName, liquidator.ModuleName, // TODO is this order ok?
|
||||
pricefeed.ModuleName, cdp.ModuleName, auction.ModuleName, //liquidator.ModuleName, // TODO is this order ok?
|
||||
)
|
||||
|
||||
app.mm.RegisterInvariants(&app.crisisKeeper)
|
||||
|
@ -20,7 +20,7 @@ func (k Keeper) StartForwardAuction(ctx sdk.Context, seller string, lot sdk.Coin
|
||||
return 0, err
|
||||
}
|
||||
// store the auction
|
||||
auctionID, err := k.storeNewAuction(ctx, auction) // TODO does this need to be a pointer to satisfy the interface?
|
||||
auctionID, err := k.storeNewAuction(ctx, auction)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -38,7 +38,7 @@ func (k Keeper) StartReverseAuction(ctx sdk.Context, buyer string, bid sdk.Coin,
|
||||
return 0, sdk.ErrInternal("module does not have minting permissions")
|
||||
}
|
||||
// store the auction
|
||||
auctionID, err := k.storeNewAuction(ctx, &auction)
|
||||
auctionID, err := k.storeNewAuction(ctx, auction)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -51,12 +51,12 @@ func (k Keeper) StartForwardReverseAuction(ctx sdk.Context, seller string, lot s
|
||||
auction := types.NewForwardReverseAuction(seller, lot, ctx.BlockTime().Add(types.DefaultMaxAuctionDuration), maxBid, otherPerson)
|
||||
|
||||
// take coins from module account
|
||||
err := k.supplyKeeper.SendCoinsFromModuleToModule(ctx, seller, types.ModuleName, sdk.Coins{lot})
|
||||
err := k.supplyKeeper.SendCoinsFromModuleToModule(ctx, seller, types.ModuleName, sdk.NewCoins(lot))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// store the auction
|
||||
auctionID, err := k.storeNewAuction(ctx, &auction)
|
||||
auctionID, err := k.storeNewAuction(ctx, auction)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -64,6 +64,7 @@ func (k Keeper) StartForwardReverseAuction(ctx sdk.Context, seller string, lot s
|
||||
}
|
||||
|
||||
// PlaceBid places a bid on any auction.
|
||||
// TODO passing bid and lot is weird when only one needed
|
||||
func (k Keeper) PlaceBid(ctx sdk.Context, auctionID types.ID, bidder sdk.AccAddress, bid sdk.Coin, lot sdk.Coin) sdk.Error {
|
||||
|
||||
// get auction from store
|
||||
@ -72,11 +73,18 @@ func (k Keeper) PlaceBid(ctx sdk.Context, auctionID types.ID, bidder sdk.AccAddr
|
||||
return sdk.ErrInternal("auction doesn't exist")
|
||||
}
|
||||
|
||||
// check end time
|
||||
// validate
|
||||
if ctx.BlockTime().After(auction.GetEndTime()) {
|
||||
return sdk.ErrInternal("auction has closed")
|
||||
}
|
||||
if auction.GetBid().Denom != bid.Denom {
|
||||
return sdk.ErrInternal("bid has incorrect denom")
|
||||
}
|
||||
if auction.GetLot().Denom != lot.Denom {
|
||||
return sdk.ErrInternal("lot has incorrect denom")
|
||||
}
|
||||
|
||||
// place bid
|
||||
var err sdk.Error
|
||||
var a types.Auction
|
||||
switch auc := auction.(type) {
|
||||
@ -124,7 +132,7 @@ func (k Keeper) PlaceBidForward(ctx sdk.Context, a types.ForwardAuction, bidder
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, bidder, sdk.NewCoins(bidAmtToReturn))
|
||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(bidAmtToReturn))
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
@ -185,7 +193,7 @@ func (k Keeper) PlaceBidForwardReverse(ctx sdk.Context, a types.ForwardReverseAu
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, bidder, sdk.NewCoins(bidAmtToReturn))
|
||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(bidAmtToReturn))
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
@ -205,7 +213,7 @@ func (k Keeper) PlaceBidForwardReverse(ctx sdk.Context, a types.ForwardReverseAu
|
||||
// increment timeout
|
||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration), a.MaxEndTime)
|
||||
|
||||
return types.ForwardReverseAuction{}, nil
|
||||
return a, nil
|
||||
}
|
||||
func (k Keeper) PlaceBidReverse(ctx sdk.Context, a types.ReverseAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.ReverseAuction, sdk.Error) {
|
||||
// Validate New Bid
|
||||
@ -228,7 +236,7 @@ func (k Keeper) PlaceBidReverse(ctx sdk.Context, a types.ReverseAuction, bidder
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, bidder, sdk.NewCoins(bidAmtToReturn))
|
||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(bidAmtToReturn))
|
||||
if err != nil {
|
||||
return a, err
|
||||
}
|
||||
@ -297,7 +305,11 @@ func (k Keeper) PayoutAuctionLot(ctx sdk.Context, a types.Auction) sdk.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FIXME stand in func for compiler
|
||||
// earliestTime returns the earliest of two times.
|
||||
func earliestTime(t1, t2 time.Time) time.Time {
|
||||
return t1
|
||||
if t1.Before(t2) {
|
||||
return t1
|
||||
} else {
|
||||
return t2 // also returned if times are equal
|
||||
}
|
||||
}
|
||||
|
145
x/auction/keeper/auctions_test.go
Normal file
145
x/auction/keeper/auctions_test.go
Normal file
@ -0,0 +1,145 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"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"
|
||||
"github.com/kava-labs/kava/x/liquidator"
|
||||
)
|
||||
|
||||
func TestForwardAuctionBasic(t *testing.T) {
|
||||
// Setup
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||
buyer := addrs[0]
|
||||
sellerModName := liquidator.ModuleName
|
||||
sellerAddr := supply.NewModuleAddress(sellerModName)
|
||||
|
||||
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)
|
||||
auctionID, err := keeper.StartForwardAuction(ctx, sellerModName, c("token1", 20), "token2") // lot, bid denom
|
||||
require.NoError(t, err)
|
||||
// Check seller's coins have decreased
|
||||
tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 100)))
|
||||
|
||||
// PlaceBid (bid: 10 token, lot: same as starting)
|
||||
require.NoError(t, keeper.PlaceBid(ctx, auctionID, buyer, c("token2", 10), c("token1", 20))) // bid, lot
|
||||
// Check buyer's coins have decreased
|
||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 90)))
|
||||
// Check seller's coins have not increased (because proceeds are burned)
|
||||
tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 100)))
|
||||
|
||||
// Close auction at just at auction expiry time
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration))
|
||||
require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// Check buyer's coins increased
|
||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 120), c("token2", 90)))
|
||||
}
|
||||
|
||||
func TestReverseAuctionBasic(t *testing.T) {
|
||||
// Setup
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||
seller := addrs[0]
|
||||
buyerModName := liquidator.ModuleName
|
||||
buyerAddr := supply.NewModuleAddress(buyerModName)
|
||||
|
||||
tApp := app.NewTestApp()
|
||||
|
||||
tApp.InitializeFromGenesisStates(
|
||||
NewAuthGenStateFromAccs(authexported.GenesisAccounts{
|
||||
auth.NewBaseAccount(seller, cs(c("token1", 100), c("token2", 100)), nil, 0, 0),
|
||||
supply.NewEmptyModuleAccount(buyerModName, supply.Minter), // reverse auctions mint payout
|
||||
}),
|
||||
)
|
||||
ctx := tApp.NewContext(false, abci.Header{})
|
||||
keeper := tApp.GetAuctionKeeper()
|
||||
|
||||
// Start auction
|
||||
auctionID, err := keeper.StartReverseAuction(ctx, buyerModName, c("token1", 20), c("token2", 99999)) // buyer, bid, initialLot
|
||||
require.NoError(t, err)
|
||||
// Check buyer's coins have not decreased, as lot is minted at the end
|
||||
tApp.CheckBalance(t, ctx, buyerAddr, nil) // zero coins
|
||||
|
||||
// Place a bid
|
||||
require.NoError(t, keeper.PlaceBid(ctx, 0, seller, c("token1", 20), c("token2", 10))) // bid, lot
|
||||
// Check seller's coins have decreased
|
||||
tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 100)))
|
||||
// Check buyer's coins have increased
|
||||
tApp.CheckBalance(t, ctx, buyerAddr, cs(c("token1", 20)))
|
||||
|
||||
// Close auction at just after auction expiry
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration))
|
||||
require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// Check seller's coins increased
|
||||
tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 110)))
|
||||
}
|
||||
|
||||
func TestForwardReverseAuctionBasic(t *testing.T) {
|
||||
// Setup
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
buyer := addrs[0]
|
||||
recipient := addrs[1]
|
||||
sellerModName := liquidator.ModuleName
|
||||
sellerAddr := supply.NewModuleAddress(sellerModName)
|
||||
|
||||
tApp := app.NewTestApp()
|
||||
sellerAcc := supply.NewEmptyModuleAccount(sellerModName)
|
||||
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),
|
||||
auth.NewBaseAccount(recipient, 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.StartForwardReverseAuction(ctx, sellerModName, c("token1", 20), c("token2", 50), recipient) // seller, lot, maxBid, otherPerson
|
||||
require.NoError(t, err)
|
||||
// Check seller's coins have decreased
|
||||
tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 100)))
|
||||
|
||||
// Place a forward bid
|
||||
require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 10), c("token1", 20))) // bid, lot
|
||||
// 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)))
|
||||
// Check recipient has not received coins
|
||||
tApp.CheckBalance(t, ctx, recipient, cs(c("token1", 100), c("token2", 100)))
|
||||
|
||||
// Place a reverse bid
|
||||
require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 50), c("token1", 15))) // bid, lot
|
||||
// Check bidder's coins have decreased
|
||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 50)))
|
||||
// Check seller's coins have increased
|
||||
tApp.CheckBalance(t, ctx, sellerAddr, cs(c("token1", 80), c("token2", 150)))
|
||||
// Check "recipient" has received coins
|
||||
tApp.CheckBalance(t, ctx, recipient, cs(c("token1", 105), c("token2", 100)))
|
||||
|
||||
// Close auction at just after auction expiry
|
||||
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(types.DefaultMaxBidDuration))
|
||||
require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// Check buyer's coins increased
|
||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 115), c("token2", 50)))
|
||||
}
|
17
x/auction/keeper/integration_test.go
Normal file
17
x/auction/keeper/integration_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
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/kava-labs/kava/app"
|
||||
)
|
||||
|
||||
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
|
||||
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|
||||
|
||||
func NewAuthGenStateFromAccs(accounts authexported.GenesisAccounts) app.GenesisState {
|
||||
authGenesis := auth.NewGenesisState(auth.DefaultParams(), accounts)
|
||||
return app.GenesisState{auth.ModuleName: auth.ModuleCdc.MustMarshalJSON(authGenesis)}
|
||||
}
|
@ -13,128 +13,22 @@ import (
|
||||
"github.com/kava-labs/kava/x/auction/types"
|
||||
)
|
||||
|
||||
// func TestKeeper_ForwardAuction(t *testing.T) {
|
||||
// // Setup
|
||||
// _, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
// seller := addrs[0]
|
||||
// buyer := addrs[1]
|
||||
|
||||
// tApp := app.NewTestApp()
|
||||
// tApp.InitializeFromGenesisStates(
|
||||
// app.NewAuthGenState(addrs, []sdk.Coins{cs(c("token1", 100), c("token2", 100)), cs(c("token1", 100), c("token2", 100))}),
|
||||
// )
|
||||
|
||||
// ctx := tApp.NewContext(false, abci.Header{})
|
||||
// keeper := tApp.GetAuctionKeeper()
|
||||
|
||||
// // Create an auction (lot: 20 t1, initialBid: 0 t2)
|
||||
// auctionID, err := keeper.StartForwardAuction(ctx, seller, c("token1", 20), c("token2", 0)) // lot, initialBid
|
||||
// require.NoError(t, err)
|
||||
// // Check seller's coins have decreased
|
||||
// tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 100)))
|
||||
|
||||
// // PlaceBid (bid: 10 t2, lot: same as starting)
|
||||
// require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 10), c("token1", 20))) // bid, lot
|
||||
// // Check buyer'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, seller, cs(c("token1", 80), c("token2", 110)))
|
||||
|
||||
// // Close auction at just after auction expiry
|
||||
// ctx = ctx.WithBlockHeight(int64(types.DefaultMaxBidDuration))
|
||||
// require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// // Check buyer's coins increased
|
||||
// tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 120), c("token2", 90)))
|
||||
// }
|
||||
|
||||
// func TestKeeper_ReverseAuction(t *testing.T) {
|
||||
// // Setup
|
||||
// _, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
// seller := addrs[0]
|
||||
// buyer := addrs[1]
|
||||
|
||||
// tApp := app.NewTestApp()
|
||||
// tApp.InitializeFromGenesisStates(
|
||||
// app.NewAuthGenState(addrs, []sdk.Coins{cs(c("token1", 100), c("token2", 100)), cs(c("token1", 100), c("token2", 100))}),
|
||||
// )
|
||||
|
||||
// ctx := tApp.NewContext(false, abci.Header{})
|
||||
// keeper := tApp.GetAuctionKeeper()
|
||||
|
||||
// // Start auction
|
||||
// auctionID, err := keeper.StartReverseAuction(ctx, buyer, c("token1", 20), c("token2", 99)) // buyer, bid, initialLot
|
||||
// require.NoError(t, err)
|
||||
// // Check buyer's coins have decreased
|
||||
// tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 1)))
|
||||
|
||||
// // Place a bid
|
||||
// require.NoError(t, keeper.PlaceBid(ctx, 0, seller, c("token1", 20), c("token2", 10))) // bid, lot
|
||||
// // Check seller's coins have decreased
|
||||
// tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 100)))
|
||||
// // Check buyer's coins have increased
|
||||
// tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 120), c("token2", 90)))
|
||||
|
||||
// // Close auction at just after auction expiry
|
||||
// ctx = ctx.WithBlockHeight(int64(types.DefaultMaxBidDuration))
|
||||
// require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// // Check seller's coins increased
|
||||
// tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 110)))
|
||||
// }
|
||||
|
||||
// func TestKeeper_ForwardReverseAuction(t *testing.T) {
|
||||
// // Setup
|
||||
// _, addrs := app.GeneratePrivKeyAddressPairs(3)
|
||||
// seller := addrs[0]
|
||||
// buyer := addrs[1]
|
||||
// recipient := addrs[2]
|
||||
|
||||
// tApp := app.NewTestApp()
|
||||
// tApp.InitializeFromGenesisStates(
|
||||
// app.NewAuthGenState(addrs, []sdk.Coins{cs(c("token1", 100), c("token2", 100)), cs(c("token1", 100), c("token2", 100)), cs(c("token1", 100), c("token2", 100))}),
|
||||
// )
|
||||
|
||||
// ctx := tApp.NewContext(false, abci.Header{})
|
||||
// keeper := tApp.GetAuctionKeeper()
|
||||
|
||||
// // Start auction
|
||||
// auctionID, err := keeper.StartForwardReverseAuction(ctx, seller, c("token1", 20), c("token2", 50), recipient) // seller, lot, maxBid, otherPerson
|
||||
// require.NoError(t, err)
|
||||
// // Check seller's coins have decreased
|
||||
// tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 100)))
|
||||
|
||||
// // Place a bid
|
||||
// require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 50), c("token1", 15))) // bid, lot
|
||||
// // Check bidder's coins have decreased
|
||||
// tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 50)))
|
||||
// // Check seller's coins have increased
|
||||
// tApp.CheckBalance(t, ctx, seller, cs(c("token1", 80), c("token2", 150)))
|
||||
// // Check "recipient" has received coins
|
||||
// tApp.CheckBalance(t, ctx, recipient, cs(c("token1", 105), c("token2", 100)))
|
||||
|
||||
// // Close auction at just after auction expiry
|
||||
// ctx = ctx.WithBlockHeight(int64(types.DefaultMaxBidDuration))
|
||||
// require.NoError(t, keeper.CloseAuction(ctx, auctionID))
|
||||
// // Check buyer's coins increased
|
||||
// tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 115), c("token2", 50)))
|
||||
// }
|
||||
|
||||
func SetGetDeleteAuction(t *testing.T) {
|
||||
// setup keeper, create auction
|
||||
tApp := app.NewTestApp()
|
||||
keeper := tApp.GetAuctionKeeper()
|
||||
ctx := tApp.NewContext(true, abci.Header{})
|
||||
someTime := time.Date(43, time.January, 1, 0, 0, 0, 0, time.UTC) // need to specify UTC as tz info is lost on unmarshal
|
||||
auction := types.NewForwardAuction("some_module", c("usdx", 100), "kava", someTime)
|
||||
id := types.ID(5)
|
||||
auction.SetID(id)
|
||||
auction := types.NewForwardAuction("some_module", c("usdx", 100), "kava", someTime).WithID(id)
|
||||
|
||||
// write and read from store
|
||||
keeper.SetAuction(ctx, &auction)
|
||||
keeper.SetAuction(ctx, auction)
|
||||
readAuction, found := keeper.GetAuction(ctx, id)
|
||||
|
||||
// check before and after match
|
||||
require.True(t, found)
|
||||
require.Equal(t, &auction, readAuction)
|
||||
require.Equal(t, auction, readAuction)
|
||||
// check auction is in queue
|
||||
// iter := keeper.GetQueueIterator(ctx, 100000)
|
||||
// require.Equal(t, 1, len(convertIteratorToSlice(keeper, iter)))
|
||||
@ -245,6 +139,3 @@ func convertIteratorToSlice(keeper keeper.Keeper, iterator sdk.Iterator) []types
|
||||
}
|
||||
return queue
|
||||
}
|
||||
|
||||
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
|
||||
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|
||||
|
@ -37,6 +37,7 @@ type Auction interface {
|
||||
GetID() ID
|
||||
WithID(ID) Auction
|
||||
GetBidder() sdk.AccAddress
|
||||
GetBid() sdk.Coin
|
||||
GetLot() sdk.Coin
|
||||
GetEndTime() time.Time
|
||||
}
|
||||
@ -44,7 +45,7 @@ type Auction interface {
|
||||
// BaseAuction type shared by all Auctions
|
||||
type BaseAuction struct {
|
||||
ID ID
|
||||
Initiator string // Module who starts the auction. Giving away Lot (aka seller in a forward auction). Restricted to being a module account name rather than any account.
|
||||
Initiator string // Module that starts the auction. Giving away Lot (aka seller in a forward auction). Restricted to being a module account name rather than any account.
|
||||
Lot sdk.Coin // Amount of coins up being given by initiator (FA - amount for sale by seller, RA - cost of good by buyer (bid))
|
||||
Bidder sdk.AccAddress // Person who bids in the auction. Receiver of Lot. (aka buyer in forward auction, seller in RA)
|
||||
Bid sdk.Coin // Amount of coins being given by the bidder (FA - bid, RA - amount being sold)
|
||||
@ -58,6 +59,9 @@ func (a BaseAuction) GetID() ID { return a.ID }
|
||||
// GetBid getter for auction bid
|
||||
func (a BaseAuction) GetBidder() sdk.AccAddress { return a.Bidder }
|
||||
|
||||
// GetBid getter for auction lot
|
||||
func (a BaseAuction) GetBid() sdk.Coin { return a.Bid }
|
||||
|
||||
// GetLot getter for auction lot
|
||||
func (a BaseAuction) GetLot() sdk.Coin { return a.Lot }
|
||||
|
||||
@ -83,7 +87,7 @@ type ForwardAuction struct {
|
||||
BaseAuction
|
||||
}
|
||||
|
||||
// WithID returns an auction wtih the ID set
|
||||
// WithID returns an auction with the ID set
|
||||
func (a ForwardAuction) WithID(id ID) Auction { a.ID = id; return a }
|
||||
|
||||
// NewForwardAuction creates a new forward auction
|
||||
@ -97,7 +101,6 @@ func NewForwardAuction(seller string, lot sdk.Coin, bidDenom string, endTime tim
|
||||
EndTime: endTime,
|
||||
MaxEndTime: endTime,
|
||||
}}
|
||||
// output := BankOutput{seller, lot}
|
||||
return auction
|
||||
}
|
||||
|
||||
@ -106,7 +109,7 @@ type ReverseAuction struct {
|
||||
BaseAuction
|
||||
}
|
||||
|
||||
// WithID returns an auction wtih the ID set
|
||||
// WithID returns an auction with the ID set
|
||||
func (a ReverseAuction) WithID(id ID) Auction { a.ID = id; return a }
|
||||
|
||||
// NewReverseAuction creates a new reverse auction
|
||||
@ -134,7 +137,7 @@ type ForwardReverseAuction struct {
|
||||
OtherPerson sdk.AccAddress // TODO rename, this is normally the original CDP owner, will have to be updated to account for deposits
|
||||
}
|
||||
|
||||
// WithID returns an auction wtih the ID set
|
||||
// WithID returns an auction with the ID set
|
||||
func (a ForwardReverseAuction) WithID(id ID) Auction { a.ID = id; return a }
|
||||
|
||||
func (a ForwardReverseAuction) String() string {
|
||||
@ -167,6 +170,5 @@ func NewForwardReverseAuction(seller string, lot sdk.Coin, EndTime time.Time, ma
|
||||
MaxBid: maxBid,
|
||||
OtherPerson: otherPerson,
|
||||
}
|
||||
//output := BankOutput{seller, lot}
|
||||
return auction
|
||||
}
|
||||
|
@ -1,403 +1,396 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
// // TODO can this be less verbose? Should PlaceBid() be split into smaller functions?
|
||||
// // It would be possible to combine all auction tests into one test runner.
|
||||
// func TestForwardAuction_PlaceBid(t *testing.T) {
|
||||
// seller := sdk.AccAddress([]byte("a_seller"))
|
||||
// buyer1 := sdk.AccAddress([]byte("buyer1"))
|
||||
// buyer2 := sdk.AccAddress([]byte("buyer2"))
|
||||
// end := EndTime(10000)
|
||||
// now := EndTime(10)
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
// type args struct {
|
||||
// currentBlockHeight EndTime
|
||||
// bidder sdk.AccAddress
|
||||
// lot sdk.Coin
|
||||
// bid sdk.Coin
|
||||
// }
|
||||
// tests := []struct {
|
||||
// name string
|
||||
// auction ForwardAuction
|
||||
// args args
|
||||
// expectedOutputs []BankOutput
|
||||
// expectedInputs []BankInput
|
||||
// expectedEndTime EndTime
|
||||
// expectedBidder sdk.AccAddress
|
||||
// expectedBid sdk.Coin
|
||||
// expectpass bool
|
||||
// }{
|
||||
// {
|
||||
// "normal",
|
||||
// ForwardAuction{BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("usdx", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("kava", 6),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{now, buyer2, c("usdx", 100), c("kava", 10)},
|
||||
// []BankOutput{{buyer2, c("kava", 10)}},
|
||||
// []BankInput{{buyer1, c("kava", 6)}, {seller, c("kava", 4)}},
|
||||
// now + DefaultMaxBidDuration,
|
||||
// buyer2,
|
||||
// c("kava", 10),
|
||||
// true,
|
||||
// },
|
||||
// {
|
||||
// "lowBid",
|
||||
// ForwardAuction{BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("usdx", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("kava", 6),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{now, buyer2, c("usdx", 100), c("kava", 5)},
|
||||
// []BankOutput{},
|
||||
// []BankInput{},
|
||||
// end,
|
||||
// buyer1,
|
||||
// c("kava", 6),
|
||||
// false,
|
||||
// },
|
||||
// {
|
||||
// "equalBid",
|
||||
// ForwardAuction{BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("usdx", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("kava", 6),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{now, buyer2, c("usdx", 100), c("kava", 6)},
|
||||
// []BankOutput{},
|
||||
// []BankInput{},
|
||||
// end,
|
||||
// buyer1,
|
||||
// c("kava", 6),
|
||||
// false,
|
||||
// },
|
||||
// {
|
||||
// "timeout",
|
||||
// ForwardAuction{BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("usdx", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("kava", 6),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{end + 1, buyer2, c("usdx", 100), c("kava", 10)},
|
||||
// []BankOutput{},
|
||||
// []BankInput{},
|
||||
// end,
|
||||
// buyer1,
|
||||
// c("kava", 6),
|
||||
// false,
|
||||
// },
|
||||
// {
|
||||
// "hitMaxEndTime",
|
||||
// ForwardAuction{BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("usdx", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("kava", 6),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{end - 1, buyer2, c("usdx", 100), c("kava", 10)},
|
||||
// []BankOutput{{buyer2, c("kava", 10)}},
|
||||
// []BankInput{{buyer1, c("kava", 6)}, {seller, c("kava", 4)}},
|
||||
// end, // end time should be capped at MaxEndTime
|
||||
// buyer2,
|
||||
// c("kava", 10),
|
||||
// true,
|
||||
// },
|
||||
// }
|
||||
// for _, tc := range tests {
|
||||
// t.Run(tc.name, func(t *testing.T) {
|
||||
// // update auction and return in/outputs
|
||||
// outputs, inputs, err := tc.auction.PlaceBid(tc.args.currentBlockHeight, tc.args.bidder, tc.args.lot, tc.args.bid)
|
||||
|
||||
// TODO can this be less verbose? Should PlaceBid() be split into smaller functions?
|
||||
// It would be possible to combine all auction tests into one test runner.
|
||||
func TestForwardAuction_PlaceBid(t *testing.T) {
|
||||
seller := sdk.AccAddress([]byte("a_seller"))
|
||||
buyer1 := sdk.AccAddress([]byte("buyer1"))
|
||||
buyer2 := sdk.AccAddress([]byte("buyer2"))
|
||||
end := EndTime(10000)
|
||||
now := EndTime(10)
|
||||
// // check for err
|
||||
// if tc.expectpass {
|
||||
// require.Nil(t, err)
|
||||
// } else {
|
||||
// require.NotNil(t, err)
|
||||
// }
|
||||
// // check for correct in/outputs
|
||||
// require.Equal(t, tc.expectedOutputs, outputs)
|
||||
// require.Equal(t, tc.expectedInputs, inputs)
|
||||
// // check for correct EndTime, bidder, bid
|
||||
// require.Equal(t, tc.expectedEndTime, tc.auction.EndTime)
|
||||
// require.Equal(t, tc.expectedBidder, tc.auction.Bidder)
|
||||
// require.Equal(t, tc.expectedBid, tc.auction.Bid)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
type args struct {
|
||||
currentBlockHeight EndTime
|
||||
bidder sdk.AccAddress
|
||||
lot sdk.Coin
|
||||
bid sdk.Coin
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
auction ForwardAuction
|
||||
args args
|
||||
expectedOutputs []BankOutput
|
||||
expectedInputs []BankInput
|
||||
expectedEndTime EndTime
|
||||
expectedBidder sdk.AccAddress
|
||||
expectedBid sdk.Coin
|
||||
expectpass bool
|
||||
}{
|
||||
{
|
||||
"normal",
|
||||
ForwardAuction{BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("usdx", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("kava", 6),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{now, buyer2, c("usdx", 100), c("kava", 10)},
|
||||
[]BankOutput{{buyer2, c("kava", 10)}},
|
||||
[]BankInput{{buyer1, c("kava", 6)}, {seller, c("kava", 4)}},
|
||||
now + DefaultMaxBidDuration,
|
||||
buyer2,
|
||||
c("kava", 10),
|
||||
true,
|
||||
},
|
||||
{
|
||||
"lowBid",
|
||||
ForwardAuction{BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("usdx", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("kava", 6),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{now, buyer2, c("usdx", 100), c("kava", 5)},
|
||||
[]BankOutput{},
|
||||
[]BankInput{},
|
||||
end,
|
||||
buyer1,
|
||||
c("kava", 6),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"equalBid",
|
||||
ForwardAuction{BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("usdx", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("kava", 6),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{now, buyer2, c("usdx", 100), c("kava", 6)},
|
||||
[]BankOutput{},
|
||||
[]BankInput{},
|
||||
end,
|
||||
buyer1,
|
||||
c("kava", 6),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"timeout",
|
||||
ForwardAuction{BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("usdx", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("kava", 6),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{end + 1, buyer2, c("usdx", 100), c("kava", 10)},
|
||||
[]BankOutput{},
|
||||
[]BankInput{},
|
||||
end,
|
||||
buyer1,
|
||||
c("kava", 6),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"hitMaxEndTime",
|
||||
ForwardAuction{BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("usdx", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("kava", 6),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{end - 1, buyer2, c("usdx", 100), c("kava", 10)},
|
||||
[]BankOutput{{buyer2, c("kava", 10)}},
|
||||
[]BankInput{{buyer1, c("kava", 6)}, {seller, c("kava", 4)}},
|
||||
end, // end time should be capped at MaxEndTime
|
||||
buyer2,
|
||||
c("kava", 10),
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// update auction and return in/outputs
|
||||
outputs, inputs, err := tc.auction.PlaceBid(tc.args.currentBlockHeight, tc.args.bidder, tc.args.lot, tc.args.bid)
|
||||
// func TestReverseAuction_PlaceBid(t *testing.T) {
|
||||
// buyer := sdk.AccAddress([]byte("a_buyer"))
|
||||
// seller1 := sdk.AccAddress([]byte("seller1"))
|
||||
// seller2 := sdk.AccAddress([]byte("seller2"))
|
||||
// end := EndTime(10000)
|
||||
// now := EndTime(10)
|
||||
|
||||
// check for err
|
||||
if tc.expectpass {
|
||||
require.Nil(t, err)
|
||||
} else {
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
// check for correct in/outputs
|
||||
require.Equal(t, tc.expectedOutputs, outputs)
|
||||
require.Equal(t, tc.expectedInputs, inputs)
|
||||
// check for correct EndTime, bidder, bid
|
||||
require.Equal(t, tc.expectedEndTime, tc.auction.EndTime)
|
||||
require.Equal(t, tc.expectedBidder, tc.auction.Bidder)
|
||||
require.Equal(t, tc.expectedBid, tc.auction.Bid)
|
||||
})
|
||||
}
|
||||
}
|
||||
// type args struct {
|
||||
// currentBlockHeight EndTime
|
||||
// bidder sdk.AccAddress
|
||||
// lot sdk.Coin
|
||||
// bid sdk.Coin
|
||||
// }
|
||||
// tests := []struct {
|
||||
// name string
|
||||
// auction ReverseAuction
|
||||
// args args
|
||||
// expectedOutputs []BankOutput
|
||||
// expectedInputs []BankInput
|
||||
// expectedEndTime EndTime
|
||||
// expectedBidder sdk.AccAddress
|
||||
// expectedLot sdk.Coin
|
||||
// expectpass bool
|
||||
// }{
|
||||
// {
|
||||
// "normal",
|
||||
// ReverseAuction{BaseAuction{
|
||||
// Initiator: buyer,
|
||||
// Lot: c("kava", 10),
|
||||
// Bidder: seller1,
|
||||
// Bid: c("usdx", 100),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{now, seller2, c("kava", 9), c("usdx", 100)},
|
||||
// []BankOutput{{seller2, c("usdx", 100)}},
|
||||
// []BankInput{{seller1, c("usdx", 100)}, {buyer, c("kava", 1)}},
|
||||
// now + DefaultMaxBidDuration,
|
||||
// seller2,
|
||||
// c("kava", 9),
|
||||
// true,
|
||||
// },
|
||||
// {
|
||||
// "highBid",
|
||||
// ReverseAuction{BaseAuction{
|
||||
// Initiator: buyer,
|
||||
// Lot: c("kava", 10),
|
||||
// Bidder: seller1,
|
||||
// Bid: c("usdx", 100),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{now, seller2, c("kava", 11), c("usdx", 100)},
|
||||
// []BankOutput{},
|
||||
// []BankInput{},
|
||||
// end,
|
||||
// seller1,
|
||||
// c("kava", 10),
|
||||
// false,
|
||||
// },
|
||||
// {
|
||||
// "equalBid",
|
||||
// ReverseAuction{BaseAuction{
|
||||
// Initiator: buyer,
|
||||
// Lot: c("kava", 10),
|
||||
// Bidder: seller1,
|
||||
// Bid: c("usdx", 100),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{now, seller2, c("kava", 10), c("usdx", 100)},
|
||||
// []BankOutput{},
|
||||
// []BankInput{},
|
||||
// end,
|
||||
// seller1,
|
||||
// c("kava", 10),
|
||||
// false,
|
||||
// },
|
||||
// {
|
||||
// "timeout",
|
||||
// ReverseAuction{BaseAuction{
|
||||
// Initiator: buyer,
|
||||
// Lot: c("kava", 10),
|
||||
// Bidder: seller1,
|
||||
// Bid: c("usdx", 100),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{end + 1, seller2, c("kava", 9), c("usdx", 100)},
|
||||
// []BankOutput{},
|
||||
// []BankInput{},
|
||||
// end,
|
||||
// seller1,
|
||||
// c("kava", 10),
|
||||
// false,
|
||||
// },
|
||||
// {
|
||||
// "hitMaxEndTime",
|
||||
// ReverseAuction{BaseAuction{
|
||||
// Initiator: buyer,
|
||||
// Lot: c("kava", 10),
|
||||
// Bidder: seller1,
|
||||
// Bid: c("usdx", 100),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end,
|
||||
// }},
|
||||
// args{end - 1, seller2, c("kava", 9), c("usdx", 100)},
|
||||
// []BankOutput{{seller2, c("usdx", 100)}},
|
||||
// []BankInput{{seller1, c("usdx", 100)}, {buyer, c("kava", 1)}},
|
||||
// end, // end time should be capped at MaxEndTime
|
||||
// seller2,
|
||||
// c("kava", 9),
|
||||
// true,
|
||||
// },
|
||||
// }
|
||||
// for _, tc := range tests {
|
||||
// t.Run(tc.name, func(t *testing.T) {
|
||||
// // update auction and return in/outputs
|
||||
// outputs, inputs, err := tc.auction.PlaceBid(tc.args.currentBlockHeight, tc.args.bidder, tc.args.lot, tc.args.bid)
|
||||
|
||||
func TestReverseAuction_PlaceBid(t *testing.T) {
|
||||
buyer := sdk.AccAddress([]byte("a_buyer"))
|
||||
seller1 := sdk.AccAddress([]byte("seller1"))
|
||||
seller2 := sdk.AccAddress([]byte("seller2"))
|
||||
end := EndTime(10000)
|
||||
now := EndTime(10)
|
||||
// // check for err
|
||||
// if tc.expectpass {
|
||||
// require.Nil(t, err)
|
||||
// } else {
|
||||
// require.NotNil(t, err)
|
||||
// }
|
||||
// // check for correct in/outputs
|
||||
// require.Equal(t, tc.expectedOutputs, outputs)
|
||||
// require.Equal(t, tc.expectedInputs, inputs)
|
||||
// // check for correct EndTime, bidder, bid
|
||||
// require.Equal(t, tc.expectedEndTime, tc.auction.EndTime)
|
||||
// require.Equal(t, tc.expectedBidder, tc.auction.Bidder)
|
||||
// require.Equal(t, tc.expectedLot, tc.auction.Lot)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
type args struct {
|
||||
currentBlockHeight EndTime
|
||||
bidder sdk.AccAddress
|
||||
lot sdk.Coin
|
||||
bid sdk.Coin
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
auction ReverseAuction
|
||||
args args
|
||||
expectedOutputs []BankOutput
|
||||
expectedInputs []BankInput
|
||||
expectedEndTime EndTime
|
||||
expectedBidder sdk.AccAddress
|
||||
expectedLot sdk.Coin
|
||||
expectpass bool
|
||||
}{
|
||||
{
|
||||
"normal",
|
||||
ReverseAuction{BaseAuction{
|
||||
Initiator: buyer,
|
||||
Lot: c("kava", 10),
|
||||
Bidder: seller1,
|
||||
Bid: c("usdx", 100),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{now, seller2, c("kava", 9), c("usdx", 100)},
|
||||
[]BankOutput{{seller2, c("usdx", 100)}},
|
||||
[]BankInput{{seller1, c("usdx", 100)}, {buyer, c("kava", 1)}},
|
||||
now + DefaultMaxBidDuration,
|
||||
seller2,
|
||||
c("kava", 9),
|
||||
true,
|
||||
},
|
||||
{
|
||||
"highBid",
|
||||
ReverseAuction{BaseAuction{
|
||||
Initiator: buyer,
|
||||
Lot: c("kava", 10),
|
||||
Bidder: seller1,
|
||||
Bid: c("usdx", 100),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{now, seller2, c("kava", 11), c("usdx", 100)},
|
||||
[]BankOutput{},
|
||||
[]BankInput{},
|
||||
end,
|
||||
seller1,
|
||||
c("kava", 10),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"equalBid",
|
||||
ReverseAuction{BaseAuction{
|
||||
Initiator: buyer,
|
||||
Lot: c("kava", 10),
|
||||
Bidder: seller1,
|
||||
Bid: c("usdx", 100),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{now, seller2, c("kava", 10), c("usdx", 100)},
|
||||
[]BankOutput{},
|
||||
[]BankInput{},
|
||||
end,
|
||||
seller1,
|
||||
c("kava", 10),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"timeout",
|
||||
ReverseAuction{BaseAuction{
|
||||
Initiator: buyer,
|
||||
Lot: c("kava", 10),
|
||||
Bidder: seller1,
|
||||
Bid: c("usdx", 100),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{end + 1, seller2, c("kava", 9), c("usdx", 100)},
|
||||
[]BankOutput{},
|
||||
[]BankInput{},
|
||||
end,
|
||||
seller1,
|
||||
c("kava", 10),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"hitMaxEndTime",
|
||||
ReverseAuction{BaseAuction{
|
||||
Initiator: buyer,
|
||||
Lot: c("kava", 10),
|
||||
Bidder: seller1,
|
||||
Bid: c("usdx", 100),
|
||||
EndTime: end,
|
||||
MaxEndTime: end,
|
||||
}},
|
||||
args{end - 1, seller2, c("kava", 9), c("usdx", 100)},
|
||||
[]BankOutput{{seller2, c("usdx", 100)}},
|
||||
[]BankInput{{seller1, c("usdx", 100)}, {buyer, c("kava", 1)}},
|
||||
end, // end time should be capped at MaxEndTime
|
||||
seller2,
|
||||
c("kava", 9),
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// update auction and return in/outputs
|
||||
outputs, inputs, err := tc.auction.PlaceBid(tc.args.currentBlockHeight, tc.args.bidder, tc.args.lot, tc.args.bid)
|
||||
// func TestForwardReverseAuction_PlaceBid(t *testing.T) {
|
||||
// cdpOwner := sdk.AccAddress([]byte("a_cdp_owner"))
|
||||
// seller := sdk.AccAddress([]byte("a_seller"))
|
||||
// buyer1 := sdk.AccAddress([]byte("buyer1"))
|
||||
// buyer2 := sdk.AccAddress([]byte("buyer2"))
|
||||
// end := EndTime(10000)
|
||||
// now := EndTime(10)
|
||||
|
||||
// check for err
|
||||
if tc.expectpass {
|
||||
require.Nil(t, err)
|
||||
} else {
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
// check for correct in/outputs
|
||||
require.Equal(t, tc.expectedOutputs, outputs)
|
||||
require.Equal(t, tc.expectedInputs, inputs)
|
||||
// check for correct EndTime, bidder, bid
|
||||
require.Equal(t, tc.expectedEndTime, tc.auction.EndTime)
|
||||
require.Equal(t, tc.expectedBidder, tc.auction.Bidder)
|
||||
require.Equal(t, tc.expectedLot, tc.auction.Lot)
|
||||
})
|
||||
}
|
||||
}
|
||||
// type args struct {
|
||||
// currentBlockHeight EndTime
|
||||
// bidder sdk.AccAddress
|
||||
// lot sdk.Coin
|
||||
// bid sdk.Coin
|
||||
// }
|
||||
// tests := []struct {
|
||||
// name string
|
||||
// auction ForwardReverseAuction
|
||||
// args args
|
||||
// expectedOutputs []BankOutput
|
||||
// expectedInputs []BankInput
|
||||
// expectedEndTime EndTime
|
||||
// expectedBidder sdk.AccAddress
|
||||
// expectedLot sdk.Coin
|
||||
// expectedBid sdk.Coin
|
||||
// expectpass bool
|
||||
// }{
|
||||
// {
|
||||
// "normalForwardBid",
|
||||
// ForwardReverseAuction{BaseAuction: BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("xrp", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("usdx", 5),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end},
|
||||
// MaxBid: c("usdx", 10),
|
||||
// OtherPerson: cdpOwner,
|
||||
// },
|
||||
// args{now, buyer2, c("xrp", 100), c("usdx", 6)},
|
||||
// []BankOutput{{buyer2, c("usdx", 6)}},
|
||||
// []BankInput{{buyer1, c("usdx", 5)}, {seller, c("usdx", 1)}},
|
||||
// now + DefaultMaxBidDuration,
|
||||
// buyer2,
|
||||
// c("xrp", 100),
|
||||
// c("usdx", 6),
|
||||
// true,
|
||||
// },
|
||||
// {
|
||||
// "normalSwitchOverBid",
|
||||
// ForwardReverseAuction{BaseAuction: BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("xrp", 100),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("usdx", 5),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end},
|
||||
// MaxBid: c("usdx", 10),
|
||||
// OtherPerson: cdpOwner,
|
||||
// },
|
||||
// args{now, buyer2, c("xrp", 99), c("usdx", 10)},
|
||||
// []BankOutput{{buyer2, c("usdx", 10)}},
|
||||
// []BankInput{{buyer1, c("usdx", 5)}, {seller, c("usdx", 5)}, {cdpOwner, c("xrp", 1)}},
|
||||
// now + DefaultMaxBidDuration,
|
||||
// buyer2,
|
||||
// c("xrp", 99),
|
||||
// c("usdx", 10),
|
||||
// true,
|
||||
// },
|
||||
// {
|
||||
// "normalReverseBid",
|
||||
// ForwardReverseAuction{BaseAuction: BaseAuction{
|
||||
// Initiator: seller,
|
||||
// Lot: c("xrp", 99),
|
||||
// Bidder: buyer1,
|
||||
// Bid: c("usdx", 10),
|
||||
// EndTime: end,
|
||||
// MaxEndTime: end},
|
||||
// MaxBid: c("usdx", 10),
|
||||
// OtherPerson: cdpOwner,
|
||||
// },
|
||||
// args{now, buyer2, c("xrp", 90), c("usdx", 10)},
|
||||
// []BankOutput{{buyer2, c("usdx", 10)}},
|
||||
// []BankInput{{buyer1, c("usdx", 10)}, {cdpOwner, c("xrp", 9)}},
|
||||
// now + DefaultMaxBidDuration,
|
||||
// buyer2,
|
||||
// c("xrp", 90),
|
||||
// c("usdx", 10),
|
||||
// true,
|
||||
// },
|
||||
// // TODO more test cases
|
||||
// }
|
||||
// for _, tc := range tests {
|
||||
// t.Run(tc.name, func(t *testing.T) {
|
||||
// // update auction and return in/outputs
|
||||
// outputs, inputs, err := tc.auction.PlaceBid(tc.args.currentBlockHeight, tc.args.bidder, tc.args.lot, tc.args.bid)
|
||||
|
||||
func TestForwardReverseAuction_PlaceBid(t *testing.T) {
|
||||
cdpOwner := sdk.AccAddress([]byte("a_cdp_owner"))
|
||||
seller := sdk.AccAddress([]byte("a_seller"))
|
||||
buyer1 := sdk.AccAddress([]byte("buyer1"))
|
||||
buyer2 := sdk.AccAddress([]byte("buyer2"))
|
||||
end := EndTime(10000)
|
||||
now := EndTime(10)
|
||||
// // check for err
|
||||
// if tc.expectpass {
|
||||
// require.Nil(t, err)
|
||||
// } else {
|
||||
// require.NotNil(t, err)
|
||||
// }
|
||||
// // check for correct in/outputs
|
||||
// require.Equal(t, tc.expectedOutputs, outputs)
|
||||
// require.Equal(t, tc.expectedInputs, inputs)
|
||||
// // check for correct EndTime, bidder, bid
|
||||
// require.Equal(t, tc.expectedEndTime, tc.auction.EndTime)
|
||||
// require.Equal(t, tc.expectedBidder, tc.auction.Bidder)
|
||||
// require.Equal(t, tc.expectedLot, tc.auction.Lot)
|
||||
// require.Equal(t, tc.expectedBid, tc.auction.Bid)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
type args struct {
|
||||
currentBlockHeight EndTime
|
||||
bidder sdk.AccAddress
|
||||
lot sdk.Coin
|
||||
bid sdk.Coin
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
auction ForwardReverseAuction
|
||||
args args
|
||||
expectedOutputs []BankOutput
|
||||
expectedInputs []BankInput
|
||||
expectedEndTime EndTime
|
||||
expectedBidder sdk.AccAddress
|
||||
expectedLot sdk.Coin
|
||||
expectedBid sdk.Coin
|
||||
expectpass bool
|
||||
}{
|
||||
{
|
||||
"normalForwardBid",
|
||||
ForwardReverseAuction{BaseAuction: BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("xrp", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("usdx", 5),
|
||||
EndTime: end,
|
||||
MaxEndTime: end},
|
||||
MaxBid: c("usdx", 10),
|
||||
OtherPerson: cdpOwner,
|
||||
},
|
||||
args{now, buyer2, c("xrp", 100), c("usdx", 6)},
|
||||
[]BankOutput{{buyer2, c("usdx", 6)}},
|
||||
[]BankInput{{buyer1, c("usdx", 5)}, {seller, c("usdx", 1)}},
|
||||
now + DefaultMaxBidDuration,
|
||||
buyer2,
|
||||
c("xrp", 100),
|
||||
c("usdx", 6),
|
||||
true,
|
||||
},
|
||||
{
|
||||
"normalSwitchOverBid",
|
||||
ForwardReverseAuction{BaseAuction: BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("xrp", 100),
|
||||
Bidder: buyer1,
|
||||
Bid: c("usdx", 5),
|
||||
EndTime: end,
|
||||
MaxEndTime: end},
|
||||
MaxBid: c("usdx", 10),
|
||||
OtherPerson: cdpOwner,
|
||||
},
|
||||
args{now, buyer2, c("xrp", 99), c("usdx", 10)},
|
||||
[]BankOutput{{buyer2, c("usdx", 10)}},
|
||||
[]BankInput{{buyer1, c("usdx", 5)}, {seller, c("usdx", 5)}, {cdpOwner, c("xrp", 1)}},
|
||||
now + DefaultMaxBidDuration,
|
||||
buyer2,
|
||||
c("xrp", 99),
|
||||
c("usdx", 10),
|
||||
true,
|
||||
},
|
||||
{
|
||||
"normalReverseBid",
|
||||
ForwardReverseAuction{BaseAuction: BaseAuction{
|
||||
Initiator: seller,
|
||||
Lot: c("xrp", 99),
|
||||
Bidder: buyer1,
|
||||
Bid: c("usdx", 10),
|
||||
EndTime: end,
|
||||
MaxEndTime: end},
|
||||
MaxBid: c("usdx", 10),
|
||||
OtherPerson: cdpOwner,
|
||||
},
|
||||
args{now, buyer2, c("xrp", 90), c("usdx", 10)},
|
||||
[]BankOutput{{buyer2, c("usdx", 10)}},
|
||||
[]BankInput{{buyer1, c("usdx", 10)}, {cdpOwner, c("xrp", 9)}},
|
||||
now + DefaultMaxBidDuration,
|
||||
buyer2,
|
||||
c("xrp", 90),
|
||||
c("usdx", 10),
|
||||
true,
|
||||
},
|
||||
// TODO more test cases
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// update auction and return in/outputs
|
||||
outputs, inputs, err := tc.auction.PlaceBid(tc.args.currentBlockHeight, tc.args.bidder, tc.args.lot, tc.args.bid)
|
||||
|
||||
// check for err
|
||||
if tc.expectpass {
|
||||
require.Nil(t, err)
|
||||
} else {
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
// check for correct in/outputs
|
||||
require.Equal(t, tc.expectedOutputs, outputs)
|
||||
require.Equal(t, tc.expectedInputs, inputs)
|
||||
// check for correct EndTime, bidder, bid
|
||||
require.Equal(t, tc.expectedEndTime, tc.auction.EndTime)
|
||||
require.Equal(t, tc.expectedBidder, tc.auction.Bidder)
|
||||
require.Equal(t, tc.expectedLot, tc.auction.Lot)
|
||||
require.Equal(t, tc.expectedBid, tc.auction.Bid)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// defined to avoid cluttering test cases with long function name
|
||||
func c(denom string, amount int64) sdk.Coin {
|
||||
return sdk.NewInt64Coin(denom, amount)
|
||||
}
|
||||
// // defined to avoid cluttering test cases with long function name
|
||||
// func c(denom string, amount int64) sdk.Coin {
|
||||
// return sdk.NewInt64Coin(denom, amount)
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user