mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-14 12:05:18 +00:00
stop sending zero coins
This commit is contained in:
parent
de4f55ea20
commit
3a7cb7e4f6
@ -34,7 +34,7 @@ func (k Keeper) StartReverseAuction(ctx sdk.Context, buyer string, bid sdk.Coin,
|
|||||||
|
|
||||||
// This auction type mints coins at close. Need to check module account has minting privileges to avoid potential err in endblocker.
|
// This auction type mints coins at close. Need to check module account has minting privileges to avoid potential err in endblocker.
|
||||||
macc := k.supplyKeeper.GetModuleAccount(ctx, buyer)
|
macc := k.supplyKeeper.GetModuleAccount(ctx, buyer)
|
||||||
if !macc.HasPermission(supply.Minter) { // TODO ideally don't want to import supply
|
if !macc.HasPermission(supply.Minter) {
|
||||||
return 0, sdk.ErrInternal("module does not have minting permissions")
|
return 0, sdk.ErrInternal("module does not have minting permissions")
|
||||||
}
|
}
|
||||||
// store the auction
|
// store the auction
|
||||||
@ -103,7 +103,11 @@ func (k Keeper) PlaceBid(ctx sdk.Context, auctionID uint64, bidder sdk.AccAddres
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case types.ForwardReverseAuction:
|
case types.ForwardReverseAuction:
|
||||||
a, err = k.PlaceBidForwardReverse(ctx, auc, bidder, bid, lot)
|
if !auc.IsReversePhase() {
|
||||||
|
a, err = k.PlaceBidForwardReverseForward(ctx, auc, bidder, bid)
|
||||||
|
} else {
|
||||||
|
a, err = k.PlaceBidForwardReverseReverse(ctx, auc, bidder, lot)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -126,24 +130,23 @@ func (k Keeper) PlaceBidForward(ctx sdk.Context, a types.ForwardAuction, bidder
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move Coins
|
// Move Coins
|
||||||
increment := bid.Sub(a.Bid)
|
if !bidder.Equals(a.Bidder) && !a.Bid.IsZero() { // catch edge case of someone updating their bid with a low balance, also don't send if amt is zero
|
||||||
bidAmtToReturn := a.Bid
|
// pay back previous bidder
|
||||||
if bidder.Equals(a.Bidder) { // catch edge case of someone updating their bid with a low balance
|
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(a.Bid))
|
||||||
bidAmtToReturn = sdk.NewInt64Coin(a.Bid.Denom, 0)
|
if err != nil {
|
||||||
|
return a, err
|
||||||
|
}
|
||||||
|
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(a.Bid))
|
||||||
|
if err != nil {
|
||||||
|
return a, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(bidAmtToReturn.Add(increment)))
|
// burn increase in bid
|
||||||
|
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, a.Initiator, sdk.NewCoins(bid.Sub(a.Bid)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return a, err
|
return a, err
|
||||||
}
|
}
|
||||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(bidAmtToReturn))
|
err = k.supplyKeeper.BurnCoins(ctx, a.Initiator, sdk.NewCoins(bid.Sub(a.Bid)))
|
||||||
if err != nil {
|
|
||||||
return a, err
|
|
||||||
}
|
|
||||||
err = k.supplyKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, a.Initiator, sdk.NewCoins(increment)) // increase in bid size is burned
|
|
||||||
if err != nil {
|
|
||||||
return a, err
|
|
||||||
}
|
|
||||||
err = k.supplyKeeper.BurnCoins(ctx, a.Initiator, sdk.NewCoins(increment))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return a, err
|
return a, err
|
||||||
}
|
}
|
||||||
@ -156,56 +159,71 @@ func (k Keeper) PlaceBidForward(ctx sdk.Context, a types.ForwardAuction, bidder
|
|||||||
|
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
func (k Keeper) PlaceBidForwardReverse(ctx sdk.Context, a types.ForwardReverseAuction, bidder sdk.AccAddress, bid sdk.Coin, lot sdk.Coin) (types.ForwardReverseAuction, sdk.Error) {
|
|
||||||
// Validate New Bid // TODO min bid increments, make validation code less confusing
|
// TODO naming
|
||||||
if !a.Bid.IsEqual(a.MaxBid) {
|
func (k Keeper) PlaceBidForwardReverseForward(ctx sdk.Context, a types.ForwardReverseAuction, bidder sdk.AccAddress, bid sdk.Coin) (types.ForwardReverseAuction, sdk.Error) {
|
||||||
// Auction is in forward phase, a bid here can put the auction into forward or reverse phases
|
// Validate bid
|
||||||
if !a.Bid.IsLT(bid) {
|
if a.IsReversePhase() {
|
||||||
return a, sdk.ErrInternal("auction in forward phase, new bid not higher than last bid")
|
return a, sdk.ErrInternal("auction is not in forward phase")
|
||||||
|
}
|
||||||
|
if !a.Bid.IsLT(bid) {
|
||||||
|
return a, sdk.ErrInternal("auction in forward phase, new bid not higher than last bid")
|
||||||
|
}
|
||||||
|
if a.MaxBid.IsLT(bid) {
|
||||||
|
return a, sdk.ErrInternal("bid higher than max bid")
|
||||||
|
}
|
||||||
|
// Move Coins
|
||||||
|
// pay back previous bidder
|
||||||
|
if !bidder.Equals(a.Bidder) && !a.Bid.IsZero() { // catch edge case of someone updating their bid with a low balance, also don't send if amt is zero
|
||||||
|
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(a.Bid))
|
||||||
|
if err != nil {
|
||||||
|
return a, err
|
||||||
}
|
}
|
||||||
if a.MaxBid.IsLT(bid) {
|
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(a.Bid))
|
||||||
return a, sdk.ErrInternal("bid higher than max bid")
|
if err != nil {
|
||||||
}
|
return a, err
|
||||||
if lot.IsNegative() || a.Lot.IsLT(lot) {
|
|
||||||
return a, sdk.ErrInternal("lot out of bounds")
|
|
||||||
}
|
|
||||||
if lot.IsLT(a.Lot) && !bid.IsEqual(a.MaxBid) {
|
|
||||||
return a, sdk.ErrInternal("auction cannot enter reverse phase without bidding max bid")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Auction is in reverse phase, it can never leave reverse phase
|
|
||||||
if !bid.IsEqual(a.MaxBid) {
|
|
||||||
return a, sdk.ErrInternal("") // not necessary
|
|
||||||
}
|
|
||||||
if lot.IsNegative() {
|
|
||||||
return a, sdk.ErrInternal("can't bid negative amount")
|
|
||||||
}
|
|
||||||
if !lot.IsLT(a.Lot) {
|
|
||||||
return a, sdk.ErrInternal("auction in reverse phase, new bid not less than previous amount")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// pay increase in bid to auction initiator
|
||||||
|
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, a.Initiator, sdk.NewCoins(bid.Sub(a.Bid)))
|
||||||
|
if err != nil {
|
||||||
|
return a, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Auction
|
||||||
|
a.Bidder = bidder
|
||||||
|
a.Bid = bid
|
||||||
|
// increment timeout
|
||||||
|
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultBidDuration), a.MaxEndTime)
|
||||||
|
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Keeper) PlaceBidForwardReverseReverse(ctx sdk.Context, a types.ForwardReverseAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.ForwardReverseAuction, sdk.Error) {
|
||||||
|
// Validate bid
|
||||||
|
if !a.IsReversePhase() {
|
||||||
|
return a, sdk.ErrInternal("auction not in reverse phase")
|
||||||
|
}
|
||||||
|
if lot.IsNegative() {
|
||||||
|
return a, sdk.ErrInternal("can't bid negative amount")
|
||||||
|
}
|
||||||
|
if !lot.IsLT(a.Lot) {
|
||||||
|
return a, sdk.ErrInternal("auction in reverse phase, new bid not less than previous amount")
|
||||||
|
}
|
||||||
|
|
||||||
// Move Coins
|
// Move Coins
|
||||||
bidIncrement := bid.Sub(a.Bid)
|
if !bidder.Equals(a.Bidder) { // catch edge case of someone updating their bid with a low balance
|
||||||
bidAmtToReturn := a.Bid
|
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(a.Bid))
|
||||||
lotDecrement := a.Lot.Sub(lot)
|
if err != nil {
|
||||||
if bidder.Equals(a.Bidder) { // catch edge case of someone updating their bid with a low balance
|
return a, err
|
||||||
bidAmtToReturn = sdk.NewInt64Coin(a.Bid.Denom, 0)
|
}
|
||||||
}
|
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(a.Bid))
|
||||||
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(bidAmtToReturn.Add(bidIncrement)))
|
if err != nil {
|
||||||
if err != nil {
|
return a, err
|
||||||
return a, err
|
}
|
||||||
}
|
|
||||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(bidAmtToReturn))
|
|
||||||
if err != nil {
|
|
||||||
return a, err
|
|
||||||
}
|
|
||||||
err = k.supplyKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, a.Initiator, sdk.NewCoins(bidIncrement))
|
|
||||||
if err != nil {
|
|
||||||
return a, err
|
|
||||||
}
|
}
|
||||||
// FIXME paying out rateably to cdp depositors is vulnerable to errors compounding over multiple bids
|
// FIXME paying out rateably to cdp depositors is vulnerable to errors compounding over multiple bids
|
||||||
lotPayouts, err := splitCoinIntoWeightedBuckets(lotDecrement, a.LotReturns.Weights)
|
lotPayouts, err := splitCoinIntoWeightedBuckets(a.Lot.Sub(lot), a.LotReturns.Weights)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return a, err
|
return a, err
|
||||||
}
|
}
|
||||||
@ -219,12 +237,12 @@ func (k Keeper) PlaceBidForwardReverse(ctx sdk.Context, a types.ForwardReverseAu
|
|||||||
// Update Auction
|
// Update Auction
|
||||||
a.Bidder = bidder
|
a.Bidder = bidder
|
||||||
a.Lot = lot
|
a.Lot = lot
|
||||||
a.Bid = bid
|
|
||||||
// increment timeout
|
// increment timeout
|
||||||
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultBidDuration), a.MaxEndTime)
|
a.EndTime = earliestTime(ctx.BlockTime().Add(types.DefaultBidDuration), a.MaxEndTime)
|
||||||
|
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k Keeper) PlaceBidReverse(ctx sdk.Context, a types.ReverseAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.ReverseAuction, sdk.Error) {
|
func (k Keeper) PlaceBidReverse(ctx sdk.Context, a types.ReverseAuction, bidder sdk.AccAddress, lot sdk.Coin) (types.ReverseAuction, sdk.Error) {
|
||||||
// Validate New Bid
|
// Validate New Bid
|
||||||
if lot.Denom != a.Lot.Denom {
|
if lot.Denom != a.Lot.Denom {
|
||||||
@ -238,17 +256,15 @@ func (k Keeper) PlaceBidReverse(ctx sdk.Context, a types.ReverseAuction, bidder
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move Coins
|
// Move Coins
|
||||||
bidAmtToReturn := a.Bid
|
if !bidder.Equals(a.Bidder) { // catch edge case of someone updating their bid with a low balance
|
||||||
if bidder.Equals(a.Bidder) { // catch edge case of someone updating their bid with a low balance
|
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(a.Bid))
|
||||||
bidAmtToReturn = sdk.NewInt64Coin(a.Bid.Denom, 0)
|
if err != nil {
|
||||||
}
|
return a, err
|
||||||
err := k.supplyKeeper.SendCoinsFromAccountToModule(ctx, bidder, types.ModuleName, sdk.NewCoins(bidAmtToReturn))
|
}
|
||||||
if err != nil {
|
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(a.Bid))
|
||||||
return a, err
|
if err != nil {
|
||||||
}
|
return a, err
|
||||||
err = k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, a.Bidder, sdk.NewCoins(bidAmtToReturn))
|
}
|
||||||
if err != nil {
|
|
||||||
return a, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Auction
|
// Update Auction
|
||||||
|
@ -140,7 +140,8 @@ func TestForwardReverseAuctionBasic(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Place a reverse bid
|
// Place a reverse bid
|
||||||
require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 50), c("token1", 15))) // bid, lot
|
require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 50), c("token1", 15))) // first bid up to max bid to switch phases
|
||||||
|
require.NoError(t, keeper.PlaceBid(ctx, 0, buyer, c("token2", 50), c("token1", 15)))
|
||||||
// Check bidder's coins have decreased
|
// Check bidder's coins have decreased
|
||||||
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 50)))
|
tApp.CheckBalance(t, ctx, buyer, cs(c("token1", 100), c("token2", 50)))
|
||||||
// Check seller's coins have increased
|
// Check seller's coins have increased
|
||||||
|
@ -72,7 +72,7 @@ func NewForwardAuction(seller string, lot sdk.Coin, bidDenom string, endTime tim
|
|||||||
// no ID
|
// no ID
|
||||||
Initiator: seller,
|
Initiator: seller,
|
||||||
Lot: lot,
|
Lot: lot,
|
||||||
Bidder: nil, // TODO on the first place bid, 0 coins will be sent to this address, check if this causes problems or can be avoided
|
Bidder: nil,
|
||||||
Bid: sdk.NewInt64Coin(bidDenom, 0),
|
Bid: sdk.NewInt64Coin(bidDenom, 0),
|
||||||
EndTime: endTime,
|
EndTime: endTime,
|
||||||
MaxEndTime: endTime,
|
MaxEndTime: endTime,
|
||||||
@ -90,10 +90,9 @@ func (a ReverseAuction) WithID(id uint64) Auction { a.ID = id; return a }
|
|||||||
|
|
||||||
// NewReverseAuction creates a new reverse auction
|
// NewReverseAuction creates a new reverse auction
|
||||||
func NewReverseAuction(buyerModAccName string, bid sdk.Coin, initialLot sdk.Coin, EndTime time.Time) ReverseAuction {
|
func NewReverseAuction(buyerModAccName string, bid sdk.Coin, initialLot sdk.Coin, EndTime time.Time) ReverseAuction {
|
||||||
// TODO setting the bidder here is a bit hacky
|
// Note: Bidder is set to the initiator's module account address instead of module name. (when the first bid is placed, it is paid out to the initiator)
|
||||||
// Needs to be set so that when the first bid is placed, it is paid out to the initiator.
|
// Setting to the module account address bypasses calling supply.SendCoinsFromModuleToModule, instead calls SendCoinsFromModuleToAccount.
|
||||||
// Setting to the module account address bypasses calling supply.SendCoinsFromModuleToModule, instead calls SendCoinsFromModuleToModule. Not a problem currently but if checks/logic regarding modules accounts where added to those methods they would be bypassed.
|
// This isn't a problem currently, but if additional logic/validation was added for sending to coins to Module Accounts, it would be bypassed.
|
||||||
// Alternative: set address to nil, and catch it in an if statement in place bid
|
|
||||||
auction := ReverseAuction{BaseAuction{
|
auction := ReverseAuction{BaseAuction{
|
||||||
// no ID
|
// no ID
|
||||||
Initiator: buyerModAccName,
|
Initiator: buyerModAccName,
|
||||||
@ -116,6 +115,10 @@ type ForwardReverseAuction struct {
|
|||||||
// WithID returns an auction with the ID set
|
// WithID returns an auction with the ID set
|
||||||
func (a ForwardReverseAuction) WithID(id uint64) Auction { a.ID = id; return a }
|
func (a ForwardReverseAuction) WithID(id uint64) Auction { a.ID = id; return a }
|
||||||
|
|
||||||
|
func (a ForwardReverseAuction) IsReversePhase() bool {
|
||||||
|
return a.Bid.IsEqual(a.MaxBid)
|
||||||
|
}
|
||||||
|
|
||||||
func (a ForwardReverseAuction) String() string {
|
func (a ForwardReverseAuction) String() string {
|
||||||
return fmt.Sprintf(`Auction %d:
|
return fmt.Sprintf(`Auction %d:
|
||||||
Initiator: %s
|
Initiator: %s
|
||||||
@ -139,7 +142,7 @@ func NewForwardReverseAuction(seller string, lot sdk.Coin, EndTime time.Time, ma
|
|||||||
// no ID
|
// no ID
|
||||||
Initiator: seller,
|
Initiator: seller,
|
||||||
Lot: lot,
|
Lot: lot,
|
||||||
Bidder: nil, // TODO on the first place bid, 0 coins will be sent to this address, check if this causes problems or can be avoided
|
Bidder: nil,
|
||||||
Bid: sdk.NewInt64Coin(maxBid.Denom, 0),
|
Bid: sdk.NewInt64Coin(maxBid.Denom, 0),
|
||||||
EndTime: EndTime,
|
EndTime: EndTime,
|
||||||
MaxEndTime: EndTime},
|
MaxEndTime: EndTime},
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
const (
|
const (
|
||||||
// DefaultMaxAuctionDuration max length of auction
|
// DefaultMaxAuctionDuration max length of auction
|
||||||
DefaultMaxAuctionDuration time.Duration = 2 * 24 * time.Hour
|
DefaultMaxAuctionDuration time.Duration = 2 * 24 * time.Hour
|
||||||
// DefaultBidDuration how long an auction gets extended when someone bids, roughly 3 hours in blocks
|
// DefaultBidDuration how long an auction gets extended when someone bids
|
||||||
DefaultBidDuration time.Duration = 3 * time.Hour
|
DefaultBidDuration time.Duration = 1 * time.Hour
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parameter keys
|
// Parameter keys
|
||||||
|
Loading…
Reference in New Issue
Block a user