2020-01-14 15:04:47 +00:00
package keeper_test
import (
2020-04-23 16:35:58 +00:00
"errors"
2020-01-14 15:04:47 +00:00
"strings"
"testing"
"time"
2020-04-30 14:23:41 +00:00
"github.com/stretchr/testify/require"
2020-01-14 15:04:47 +00:00
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"
2020-04-30 14:23:41 +00:00
2020-01-14 15:04:47 +00:00
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 (
2020-02-28 22:16:22 +00:00
Invalid AuctionType = 0
Surplus AuctionType = 1
Debt AuctionType = 2
Collateral AuctionType = 3
2020-01-14 15:04:47 +00:00
)
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 )
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 {
2020-02-28 22:16:22 +00:00
bidder sdk . AccAddress
amount sdk . Coin
2020-01-14 15:04:47 +00:00
}
tests := [ ] struct {
name string
auctionArgs auctionArgs
2020-02-28 22:16:22 +00:00
setupBids [ ] bidArgs
2020-01-14 15:04:47 +00:00
bidArgs bidArgs
2020-04-23 16:35:58 +00:00
expectedError error
2020-01-14 15:04:47 +00:00
expectedEndTime time . Time
expectedBidder sdk . AccAddress
expectedBid sdk . Coin
2020-04-23 16:35:58 +00:00
expectPass bool
expectPanic bool
2020-01-14 15:04:47 +00:00
} {
{
"basic: auction doesn't exist" ,
auctionArgs { Surplus , "" , c ( "token1" , 1 ) , c ( "token2" , 1 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
2020-02-28 22:16:22 +00:00
nil ,
bidArgs { buyer , c ( "token2" , 10 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrAuctionNotFound ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 10 ) ,
false ,
2020-04-23 16:35:58 +00:00
true ,
2020-01-14 15:04:47 +00:00
} ,
2020-02-28 22:16:22 +00:00
{
"basic: closed auction" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 10 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
nil ,
bidArgs { buyer , c ( "token2" , 10 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrAuctionHasExpired ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
nil ,
c ( "token2" , 0 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
2020-01-14 15:04:47 +00:00
{
"surplus: normal" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 10 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
2020-02-28 22:16:22 +00:00
nil ,
bidArgs { buyer , c ( "token2" , 10 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 10 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"surplus: second bidder" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 10 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
2020-02-28 22:16:22 +00:00
[ ] bidArgs { { buyer , c ( "token2" , 10 ) } } ,
bidArgs { secondBuyer , c ( "token2" , 11 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
secondBuyer ,
c ( "token2" , 11 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"surplus: invalid bid denom" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 10 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
2020-02-28 22:16:22 +00:00
nil ,
bidArgs { buyer , c ( "badtoken" , 10 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrInvalidBidDenom ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
nil , // surplus auctions are created with initial bidder as a nil address
c ( "token2" , 0 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"surplus: invalid bid (less than)" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 0 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
[ ] bidArgs { { buyer , c ( "token2" , 100 ) } } ,
bidArgs { buyer , c ( "token2" , 99 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrBidTooSmall ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
2020-02-28 22:16:22 +00:00
c ( "token2" , 100 ) ,
2020-01-14 15:04:47 +00:00
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"surplus: invalid bid (equal)" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 0 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
2020-02-28 22:16:22 +00:00
nil ,
bidArgs { buyer , c ( "token2" , 0 ) } , // min bid is technically 0 at default 5%, but it's capped at 1
2020-04-23 16:35:58 +00:00
types . ErrBidTooSmall ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
nil , // surplus auctions are created with initial bidder as a nil address
c ( "token2" , 0 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"surplus: invalid bid (less than min increment)" ,
auctionArgs { Surplus , modName , c ( "token1" , 100 ) , c ( "token2" , 0 ) , sdk . Coin { } , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
[ ] bidArgs { { buyer , c ( "token2" , 100 ) } } ,
bidArgs { buyer , c ( "token2" , 104 ) } , // min bid is 105 at default 5%
2020-04-23 16:35:58 +00:00
types . ErrBidTooSmall ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
2020-02-28 22:16:22 +00:00
c ( "token2" , 100 ) ,
2020-01-14 15:04:47 +00:00
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"debt: normal" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Debt , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 100 ) , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } , // initial bid, lot
nil ,
bidArgs { buyer , c ( "token1" , 10 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 100 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"debt: second bidder" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Debt , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 100 ) , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } , // initial bid, lot
[ ] bidArgs { { buyer , c ( "token1" , 10 ) } } ,
bidArgs { secondBuyer , c ( "token1" , 9 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
secondBuyer ,
c ( "token2" , 100 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"debt: invalid lot denom" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Debt , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 100 ) , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } , // initial bid, lot
nil ,
bidArgs { buyer , c ( "badtoken" , 10 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrInvalidLotDenom ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
supply . NewModuleAddress ( modName ) ,
c ( "token2" , 100 ) ,
2020-01-14 15:04:47 +00:00
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"debt: invalid lot size (larger)" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Debt , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 100 ) , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
nil ,
bidArgs { buyer , c ( "token1" , 21 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrLotTooLarge ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
supply . NewModuleAddress ( modName ) ,
c ( "token2" , 100 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"debt: invalid lot size (equal)" ,
auctionArgs { Debt , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 100 ) , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
nil ,
bidArgs { buyer , c ( "token1" , 20 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrLotTooLarge ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
supply . NewModuleAddress ( modName ) ,
c ( "token2" , 100 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"debt: invalid lot size (larger than min increment)" ,
auctionArgs { Debt , modName , c ( "token1" , 60 ) , c ( "token2" , 100 ) , c ( "debt" , 100 ) , [ ] sdk . AccAddress { } , [ ] sdk . Int { } } ,
nil ,
bidArgs { buyer , c ( "token1" , 58 ) } , // max lot at default 5% is 57
2020-04-23 16:35:58 +00:00
types . ErrLotTooLarge ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
supply . NewModuleAddress ( modName ) ,
c ( "token2" , 100 ) ,
2020-04-23 16:35:58 +00:00
false , false ,
2020-01-14 15:04:47 +00:00
} ,
{
"collateral [forward]: normal" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
nil ,
bidArgs { buyer , c ( "token2" , 10 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 10 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"collateral [forward]: second bidder" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 10 ) } } ,
bidArgs { secondBuyer , c ( "token2" , 11 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
secondBuyer ,
c ( "token2" , 11 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"collateral [forward]: invalid bid denom" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
nil ,
bidArgs { buyer , c ( "badtoken" , 10 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrInvalidBidDenom ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
nil ,
c ( "token2" , 0 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"collateral [forward]: invalid bid size (smaller)" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 10 ) } } ,
bidArgs { buyer , c ( "token2" , 9 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrBidTooSmall ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 10 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
2020-02-28 22:16:22 +00:00
"collateral [forward]: invalid bid size (equal)" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
nil ,
bidArgs { buyer , c ( "token2" , 0 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrBidTooSmall ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
nil ,
c ( "token2" , 0 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"collateral [forward]: invalid bid size (less than min increment)" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } } ,
bidArgs { buyer , c ( "token2" , 51 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrBidTooSmall ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
2020-02-28 22:16:22 +00:00
c ( "token2" , 50 ) ,
2020-01-14 15:04:47 +00:00
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
2020-02-28 22:16:22 +00:00
"collateral [forward]: less than min increment but equal to maxBid" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 99 ) } } ,
bidArgs { buyer , c ( "token2" , 100 ) } , // min bid at default 5% is 104
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
2020-02-28 22:16:22 +00:00
c ( "token2" , 100 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-02-28 22:16:22 +00:00
} ,
{
"collateral [forward]: invalid bid size (greater than max)" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 100 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
nil ,
bidArgs { buyer , c ( "token2" , 101 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrBidTooLarge ,
2020-02-28 22:16:22 +00:00
types . DistantFuture ,
nil ,
c ( "token2" , 0 ) ,
2020-01-14 15:04:47 +00:00
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"collateral [reverse]: normal" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 50 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } } , // put auction into reverse phase
bidArgs { buyer , c ( "token1" , 15 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 50 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"collateral [reverse]: second bidder" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 50 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } , { buyer , c ( "token1" , 15 ) } } , // put auction into reverse phase, and add a reverse phase bid
bidArgs { secondBuyer , c ( "token1" , 14 ) } ,
2020-04-23 16:35:58 +00:00
nil ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
secondBuyer ,
c ( "token2" , 50 ) ,
true ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
"collateral [reverse]: invalid lot denom" ,
2020-02-28 22:16:22 +00:00
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 50 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } } , // put auction into reverse phase
bidArgs { buyer , c ( "badtoken" , 15 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrInvalidLotDenom ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 50 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
2020-02-28 22:16:22 +00:00
"collateral [reverse]: invalid lot size (greater)" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 50 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } } , // put auction into reverse phase
bidArgs { buyer , c ( "token1" , 21 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrLotTooLarge ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 50 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
2020-02-28 22:16:22 +00:00
"collateral [reverse]: invalid lot size (equal)" ,
auctionArgs { Collateral , modName , c ( "token1" , 20 ) , c ( "token2" , 50 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } } , // put auction into reverse phase
bidArgs { buyer , c ( "token1" , 20 ) } ,
2020-04-23 16:35:58 +00:00
types . ErrLotTooLarge ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
c ( "token2" , 50 ) ,
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
{
2020-02-28 22:16:22 +00:00
"collateral [reverse]: invalid lot size (larger than min increment)" ,
auctionArgs { Collateral , modName , c ( "token1" , 60 ) , c ( "token2" , 50 ) , c ( "debt" , 50 ) , collateralAddrs , collateralWeights } , // lot, max bid
[ ] bidArgs { { buyer , c ( "token2" , 50 ) } } , // put auction into reverse phase
bidArgs { buyer , c ( "token1" , 58 ) } , // max lot at default 5% is 57
2020-04-23 16:35:58 +00:00
types . ErrLotTooLarge ,
2020-01-14 15:04:47 +00:00
someTime . Add ( types . DefaultBidDuration ) ,
buyer ,
2020-02-28 22:16:22 +00:00
c ( "token2" , 50 ) ,
2020-01-14 15:04:47 +00:00
false ,
2020-04-23 16:35:58 +00:00
false ,
2020-01-14 15:04:47 +00:00
} ,
}
for _ , tc := range tests {
t . Run ( tc . name , func ( t * testing . T ) {
2020-01-21 10:06:07 +00:00
// Setup test
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 ( )
2020-02-28 22:16:22 +00:00
bank := tApp . GetBankKeeper ( )
2020-01-21 10:06:07 +00:00
2020-01-14 15:04:47 +00:00
// Start Auction
var id uint64
2020-04-23 16:35:58 +00:00
var err error
2020-01-14 15:04:47 +00:00
switch tc . auctionArgs . auctionType {
case Surplus :
2020-04-23 16:35:58 +00:00
if tc . expectPanic {
require . Panics ( t , func ( ) {
id , err = keeper . StartSurplusAuction ( ctx , tc . auctionArgs . seller , tc . auctionArgs . lot , tc . auctionArgs . bid . Denom )
} )
} else {
id , err = keeper . StartSurplusAuction ( ctx , tc . auctionArgs . seller , tc . auctionArgs . lot , tc . auctionArgs . bid . Denom )
}
2020-01-14 15:04:47 +00:00
case Debt :
2020-04-23 16:35:58 +00:00
id , err = keeper . StartDebtAuction ( ctx , tc . auctionArgs . seller , tc . auctionArgs . bid , tc . auctionArgs . lot , tc . auctionArgs . debt )
2020-02-28 22:16:22 +00:00
case Collateral :
2020-04-23 16:35:58 +00:00
id , err = 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
2020-01-14 15:04:47 +00:00
default :
t . Fail ( )
}
2020-04-23 16:35:58 +00:00
require . NoError ( t , err )
2020-02-28 22:16:22 +00:00
// Place setup bids
for _ , b := range tc . setupBids {
require . NoError ( t , keeper . PlaceBid ( ctx , id , b . bidder , b . amount ) )
}
2020-01-14 15:04:47 +00:00
// Close the auction early to test late bidding (if applicable)
if strings . Contains ( tc . name , "closed" ) {
ctx = ctx . WithBlockTime ( types . DistantFuture . Add ( 1 ) )
}
2020-02-28 22:16:22 +00:00
// Store some state for use in checks
oldAuction , found := keeper . GetAuction ( ctx , id )
var oldBidder sdk . AccAddress
if found {
oldBidder = oldAuction . GetBidder ( )
}
oldBidderOldCoins := bank . GetCoins ( ctx , oldBidder )
newBidderOldCoins := bank . GetCoins ( ctx , tc . bidArgs . bidder )
2020-01-14 15:04:47 +00:00
// Place bid on auction
err = keeper . PlaceBid ( ctx , id , tc . bidArgs . bidder , tc . bidArgs . amount )
// Check success/failure
2020-04-23 16:35:58 +00:00
if tc . expectPass {
2020-01-14 15:04:47 +00:00
require . Nil ( t , err )
2020-02-28 22:16:22 +00:00
// Check auction was found
newAuction , found := keeper . GetAuction ( ctx , id )
2020-01-14 15:04:47 +00:00
require . True ( t , found )
// Check auction values
2020-02-28 22:16:22 +00:00
require . Equal ( t , modName , newAuction . GetInitiator ( ) )
require . Equal ( t , tc . expectedBidder , newAuction . GetBidder ( ) )
require . Equal ( t , tc . expectedBid , newAuction . GetBid ( ) )
require . Equal ( t , tc . expectedEndTime , newAuction . GetEndTime ( ) )
// Check coins have moved between bidder and previous bidder
bidAmt := tc . bidArgs . amount
switch tc . auctionArgs . auctionType {
case Debt :
bidAmt = oldAuction . GetBid ( )
case Collateral :
2020-04-23 16:35:58 +00:00
collatAuction , ok := oldAuction . ( types . CollateralAuction )
require . True ( t , ok , tc . name )
2020-02-28 22:16:22 +00:00
if collatAuction . IsReversePhase ( ) {
bidAmt = oldAuction . GetBid ( )
}
}
if oldBidder . Equals ( tc . bidArgs . bidder ) { // same bidder
require . Equal ( t , newBidderOldCoins . Sub ( cs ( bidAmt . Sub ( oldAuction . GetBid ( ) ) ) ) , bank . GetCoins ( ctx , tc . bidArgs . bidder ) )
} else {
2020-04-23 16:35:58 +00:00
require . Equal ( t , newBidderOldCoins . Sub ( cs ( bidAmt ) ) , bank . GetCoins ( ctx , tc . bidArgs . bidder ) ) // wrapping in cs() to avoid comparing nil and empty coins
if oldBidder . Equals ( supply . NewModuleAddress ( oldAuction . GetInitiator ( ) ) ) { // handle checking debt coins for case debt auction has had no bids placed yet TODO make this less confusing
require . Equal ( t , oldBidderOldCoins . Add ( oldAuction . GetBid ( ) ) . Add ( c ( "debt" , oldAuction . GetBid ( ) . Amount . Int64 ( ) ) ) , bank . GetCoins ( ctx , oldBidder ) )
2020-02-28 22:16:22 +00:00
} else {
2020-04-23 16:35:58 +00:00
require . Equal ( t , cs ( oldBidderOldCoins . Add ( oldAuction . GetBid ( ) ) ... ) , bank . GetCoins ( ctx , oldBidder ) )
2020-02-28 22:16:22 +00:00
}
}
2020-01-14 15:04:47 +00:00
} else {
2020-01-15 10:39:55 +00:00
// Check expected error code type
2020-02-28 22:16:22 +00:00
require . NotNil ( t , err , "PlaceBid did not return an error" ) // catch nil values before they cause a panic below
2020-04-23 16:35:58 +00:00
require . True ( t , errors . Is ( err , tc . expectedError ) )
2020-02-28 22:16:22 +00:00
// Check auction values
newAuction , found := keeper . GetAuction ( ctx , id )
if found {
require . Equal ( t , modName , newAuction . GetInitiator ( ) )
require . Equal ( t , tc . expectedBidder , newAuction . GetBidder ( ) )
require . Equal ( t , tc . expectedBid , newAuction . GetBid ( ) )
require . Equal ( t , tc . expectedEndTime , newAuction . GetEndTime ( ) )
}
// Check coins have not moved
require . Equal ( t , newBidderOldCoins , bank . GetCoins ( ctx , tc . bidArgs . bidder ) )
require . Equal ( t , oldBidderOldCoins , bank . GetCoins ( ctx , oldBidder ) )
2020-01-14 15:04:47 +00:00
}
} )
}
}