2022-08-31 15:40:28 -07:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
2022-09-14 14:39:29 -07:00
|
|
|
colinearmath "colinear/x/colinearcore/math"
|
2022-09-06 15:18:09 -07:00
|
|
|
"colinear/x/colinearcore/memdb"
|
|
|
|
"colinear/x/colinearcore/types"
|
2022-09-04 16:36:57 -07:00
|
|
|
"log"
|
2022-09-01 10:07:09 -07:00
|
|
|
"math/big"
|
2022-09-02 14:03:03 -07:00
|
|
|
"time"
|
2022-08-31 15:40:28 -07:00
|
|
|
|
2022-09-01 10:07:09 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2022-08-31 15:40:28 -07:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
2022-09-05 14:18:04 -07:00
|
|
|
func (k Keeper) AuctionIsExpired(ctx sdk.Context, auctionId string) (bool, error) {
|
2022-08-31 15:40:28 -07:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-09-05 14:18:04 -07:00
|
|
|
func (k Keeper) FinalizeExpiredAuctions(ctx sdk.Context) {
|
2022-09-13 15:58:07 -07:00
|
|
|
memdb.AuctionDB.ForEachAuctionBidList(func(auctionId string) error {
|
2022-08-31 15:40:28 -07:00
|
|
|
auction, found := k.GetAuction(ctx, auctionId)
|
|
|
|
// make sure the auction exists on-chain
|
|
|
|
if !found {
|
2022-09-02 14:03:03 -07:00
|
|
|
return errors.Errorf("auction %s not found", auctionId)
|
2022-08-31 15:40:28 -07:00
|
|
|
}
|
|
|
|
|
2022-08-31 21:48:54 -07:00
|
|
|
if uint64(ctx.BlockHeight()) >= auction.Deadline {
|
2022-08-31 15:40:28 -07:00
|
|
|
var err error
|
2022-09-13 15:58:07 -07:00
|
|
|
auction.Best, err = memdb.AuctionDB.GetLowestBid(auctionId)
|
2022-08-31 15:40:28 -07:00
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("could not get highest bid for auction %s: %s", auctionId, err)
|
|
|
|
}
|
2022-08-31 23:09:36 -07:00
|
|
|
|
2022-09-05 15:17:55 -07:00
|
|
|
// Remaining Unpaid: Full bid amount
|
2022-09-02 14:03:03 -07:00
|
|
|
auction.Remaining = auction.Best.Amount
|
|
|
|
|
2022-09-13 17:01:06 -07:00
|
|
|
// clear auction bids
|
2022-09-13 15:58:07 -07:00
|
|
|
if err := memdb.AuctionDB.ClearAuctionBids(auctionId); err != nil {
|
2022-09-05 14:18:04 -07:00
|
|
|
return errors.Errorf("failed to clear auction from memcache: %s", err)
|
|
|
|
}
|
2022-08-31 23:09:36 -07:00
|
|
|
|
2022-09-13 17:01:06 -07:00
|
|
|
// clear verified provider list; swallow error since this isn't critical for now
|
|
|
|
_ = memdb.AuctionDB.ClearVerifiedProviders(auctionId)
|
|
|
|
|
|
|
|
// if err := memdb.AuctionDB.ClearVerifiedProviders(auctionId); err != nil {
|
|
|
|
// return errors.Errorf("failed to clear verified providers for auction %s: %s", auctionId, err)
|
|
|
|
// }
|
2022-09-13 15:58:07 -07:00
|
|
|
|
2022-09-05 14:18:04 -07:00
|
|
|
// pay out unpaid remainder to auction creator
|
2022-09-01 10:07:09 -07:00
|
|
|
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)
|
2022-09-05 14:18:04 -07:00
|
|
|
coins := sdk.NewCoins(sdk.NewCoin(
|
|
|
|
auction.Denom,
|
|
|
|
sdk.NewIntFromBigInt(amtRemaining),
|
|
|
|
))
|
|
|
|
recipAddr, err := sdk.AccAddressFromBech32(auction.Owner)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Errorf("failed to parse address %s", auction.Owner)
|
|
|
|
}
|
|
|
|
if err := k.bank.SendCoinsFromModuleToAccount(ctx, types.ModuleName, recipAddr, coins); err != nil {
|
2022-09-04 16:36:57 -07:00
|
|
|
log.Printf("Failed to send coins from module: %s\n", err)
|
2022-09-05 14:18:04 -07:00
|
|
|
// log.Fatalf("Failed to send coins from module: %s\n", err)
|
2022-09-04 16:36:57 -07:00
|
|
|
}
|
2022-09-01 10:07:09 -07:00
|
|
|
}
|
2022-08-31 23:09:36 -07:00
|
|
|
|
2022-09-05 15:07:05 -07:00
|
|
|
// lease period starts now
|
|
|
|
auction.LeaseStart = uint64(ctx.BlockTime().Unix())
|
|
|
|
|
2022-08-31 23:09:36 -07:00
|
|
|
// end auction
|
|
|
|
k.SetAuction(ctx, auction)
|
2022-09-21 13:31:20 -07:00
|
|
|
|
|
|
|
// emit finalization event
|
|
|
|
ctx.EventManager().EmitEvent(
|
|
|
|
sdk.NewEvent(types.AuctionFinalizedEventType,
|
|
|
|
sdk.NewAttribute(types.AuctionFinalizedIndex, auction.Index),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
2022-08-31 15:40:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
2022-09-01 12:13:17 -07:00
|
|
|
|
2022-09-04 16:36:57 -07:00
|
|
|
func (k *Keeper) PayAuctionAmountDue(ctx sdk.Context, auctionId string) error {
|
2022-09-02 14:03:03 -07:00
|
|
|
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)
|
2022-09-01 12:13:17 -07:00
|
|
|
|
2022-09-02 14:03:03 -07:00
|
|
|
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)
|
2022-09-14 14:39:29 -07:00
|
|
|
amt, err := colinearmath.CalcAmountVestableLinear(
|
2022-09-02 14:03:03 -07:00
|
|
|
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)))
|
2022-09-05 16:03:12 -07:00
|
|
|
err = k.bank.SendCoinsFromModuleToAccount(ctx, "colinear", sdk.AccAddress(auction.Best.Owner), coins)
|
2022-09-02 14:03:03 -07:00
|
|
|
return err
|
|
|
|
}
|
2022-09-01 12:13:17 -07:00
|
|
|
}
|