package keeper import ( "cosmos-test/x/cosmostest/math" "cosmos-test/x/cosmostest/memdb" "cosmos-test/x/cosmostest/types" "log" "math/big" "time" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/pkg/errors" ) func (k *Keeper) AuctionIsExpired(ctx sdk.Context, auctionId string) (bool, error) { auction, found := k.GetAuction(ctx, auctionId) // make sure the auction exists on-chain if !found { return true, errors.Errorf("auction %s not found", auctionId) } return uint64(ctx.BlockHeight()) >= auction.Deadline, nil } func (k *Keeper) FinalizeExpiredAuctions(ctx sdk.Context) { memdb.BidDB.ForEachAuction(func(auctionId string) error { auction, found := k.GetAuction(ctx, auctionId) // make sure the auction exists on-chain if !found { return errors.Errorf("auction %s not found", auctionId) } if uint64(ctx.BlockHeight()) >= auction.Deadline { var err error auction.Best, err = memdb.BidDB.GetLowestBid(auctionId) if err != nil { return errors.Errorf("could not get highest bid for auction %s: %s", auctionId, err) } // Remainig Unpaid: Full bid amount auction.Remaining = auction.Best.Amount // clear auction memdb.BidDB.ClearAuction(auctionId) // pay out remainder to auction creator ceiling := new(big.Int) ceiling.SetString(auction.Ceiling, 10) lowestBidAmt := new(big.Int) lowestBidAmt.SetString(auction.Best.Amount, 10) // only pay out if there is a difference if ceiling.Cmp(lowestBidAmt) == 1 { amtRemaining := new(big.Int) amtRemaining.Sub(ceiling, lowestBidAmt) coins := sdk.NewCoins(sdk.Coin{ Amount: sdk.NewIntFromBigInt(amtRemaining), Denom: auction.Denom, }) if err := k.bank.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.AccAddress(auction.Owner), coins); err != nil { log.Printf("Failed to send coins from module: %s\n", err) } } // end auction k.SetAuction(ctx, auction) } return nil }) } func (k *Keeper) PayAuctionAmountDue(ctx sdk.Context, auctionId string) error { auction, found := k.GetAuction(ctx, auctionId) if !found { return errors.Errorf("auction %s not found", auctionId) } blockTime := ctx.BlockTime() deadline := time.Unix(int64(auction.Deadline), 0) if blockTime.After(deadline) { return nil } else { amtTotal := new(big.Int) amtTotal.SetString(auction.Best.Amount, 10) amtRemaining := new(big.Int) amtTotal.SetString(auction.Remaining, 10) amt, err := math.CalcAmountVestableLinear( amtTotal, amtRemaining, ctx.BlockTime(), time.Unix(int64(auction.LeaseStart), 0), time.Unix(int64(auction.LeaseEnd), 0), ) if err != nil { return err } coins := sdk.NewCoins(sdk.NewCoin(auction.Denom, sdk.NewIntFromBigInt(amt))) err = k.bank.SendCoinsFromModuleToAccount(ctx, "cosmostest", sdk.AccAddress(auction.Best.Owner), coins) return err } }