2022-08-27 14:19:03 -07:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-08-27 19:48:00 -07:00
|
|
|
"errors"
|
2022-08-31 23:55:14 -07:00
|
|
|
"fmt"
|
|
|
|
"math/big"
|
2022-08-27 19:48:00 -07:00
|
|
|
"strconv"
|
2022-08-27 14:19:03 -07:00
|
|
|
|
2022-09-06 15:18:09 -07:00
|
|
|
"colinear/x/colinearcore/auctionconfig"
|
2022-09-13 17:01:06 -07:00
|
|
|
"colinear/x/colinearcore/memdb"
|
2022-09-06 15:18:09 -07:00
|
|
|
"colinear/x/colinearcore/types"
|
2022-08-27 19:48:00 -07:00
|
|
|
|
2022-08-27 14:19:03 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (k msgServer) NewAuction(goCtx context.Context, msg *types.MsgNewAuction) (*types.MsgNewAuctionResponse, error) {
|
|
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
|
2022-08-27 19:48:00 -07:00
|
|
|
next, found := k.Keeper.GetNextAuction(ctx)
|
|
|
|
if !found {
|
2022-09-05 15:17:55 -07:00
|
|
|
return nil, errors.New("unable to get next auction index")
|
2022-08-27 19:48:00 -07:00
|
|
|
}
|
|
|
|
index := strconv.FormatUint(next.AuctionId, 10)
|
|
|
|
|
2022-09-05 15:17:55 -07:00
|
|
|
auctionLen := msg.LeaseEnd - uint64(ctx.BlockTime().Unix())
|
|
|
|
|
2022-09-07 16:06:28 -07:00
|
|
|
// check that submitted denom is allowed
|
|
|
|
for _, denom := range auctionconfig.AllowedAuctionDenoms {
|
|
|
|
if msg.Denom == denom {
|
|
|
|
goto found
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("denom %s is not allowed; must be in %v", msg.Denom, auctionconfig.AllowedAuctionDenoms)
|
|
|
|
found:
|
|
|
|
|
2022-09-05 15:17:55 -07:00
|
|
|
if auctionLen < auctionconfig.MinLeasePeriod {
|
|
|
|
return nil, fmt.Errorf(
|
|
|
|
"Auction length %d is below min lease period of %d",
|
|
|
|
auctionLen,
|
|
|
|
auctionconfig.MinLeasePeriod,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if auctionLen > auctionconfig.MaxLeasePeriod {
|
|
|
|
return nil, fmt.Errorf(
|
|
|
|
"Auction length %d is above max lease period of %d",
|
|
|
|
auctionLen,
|
|
|
|
auctionconfig.MaxLeasePeriod,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-09-13 15:58:07 -07:00
|
|
|
senderAddr, err := sdk.AccAddressFromBech32(msg.Creator)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("sender address `%s` format invalid (bech32 required)", msg.Creator)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(msg.VerifiedProviders) > auctionconfig.MaxVerifiedProviders {
|
|
|
|
return nil, fmt.Errorf("must submit no more than %d verified providers (got %d)", auctionconfig.MaxVerifiedProviders, len(msg.VerifiedProviders))
|
|
|
|
}
|
|
|
|
|
|
|
|
bech32Len := len("colinear") + 39
|
|
|
|
for i, provider := range msg.VerifiedProviders {
|
|
|
|
if len(provider) > bech32Len {
|
|
|
|
return nil, fmt.Errorf("verified provider address %s (#%d) must be no longer than a colinear bech32 address (%d)", provider, i, bech32Len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-13 17:01:06 -07:00
|
|
|
if msg.VerifiedProviders != nil {
|
|
|
|
memdb.AuctionDB.SetVerifiedProviders(index, msg.VerifiedProviders)
|
|
|
|
} else {
|
|
|
|
memdb.AuctionDB.SetVerifiedProviders(index, []string{})
|
|
|
|
}
|
|
|
|
|
2022-08-27 19:48:00 -07:00
|
|
|
auction := types.Auction{
|
|
|
|
Index: index,
|
|
|
|
Name: msg.Name,
|
|
|
|
Description: msg.Description,
|
2022-09-05 14:18:04 -07:00
|
|
|
// best bid -> null
|
2022-08-31 21:49:24 -07:00
|
|
|
// Best: new(types.Bid),
|
2022-09-05 15:07:05 -07:00
|
|
|
Deadline: uint64(ctx.BlockHeight()) + auctionconfig.AuctionTime,
|
|
|
|
Denom: msg.Denom,
|
|
|
|
Owner: msg.Creator,
|
|
|
|
Ceiling: msg.Ceiling,
|
|
|
|
// lease start -> null
|
|
|
|
// instead, initialize when auction is finalized
|
|
|
|
// LeaseStart: uint64(ctx.BlockTime().Unix()),
|
|
|
|
LeaseEnd: msg.LeaseEnd,
|
2022-09-05 14:18:04 -07:00
|
|
|
// remaining payout -> null
|
|
|
|
// Remaining: "0",
|
2022-08-31 23:55:14 -07:00
|
|
|
}
|
|
|
|
|
2022-09-01 00:08:30 -07:00
|
|
|
spendable := k.bank.SpendableCoins(ctx, senderAddr)
|
2022-08-31 23:55:14 -07:00
|
|
|
// if balance does not exceed or equal proposed auction ceiling...
|
|
|
|
ceiling := new(big.Int)
|
|
|
|
ceiling.SetString(auction.Ceiling, 10)
|
|
|
|
if spendable.AmountOf(auction.Denom).BigInt().Cmp(ceiling) == -1 {
|
|
|
|
return nil, fmt.Errorf("not enough balance to set ceiling %s%s", msg.Ceiling, auction.Denom)
|
2022-08-27 19:48:00 -07:00
|
|
|
}
|
|
|
|
|
2022-09-01 00:08:30 -07:00
|
|
|
coins := sdk.NewCoins(sdk.Coin{
|
2022-09-04 16:36:57 -07:00
|
|
|
Amount: sdk.NewIntFromBigInt(ceiling),
|
2022-09-01 00:08:30 -07:00
|
|
|
Denom: auction.Denom,
|
|
|
|
})
|
|
|
|
|
2022-09-05 14:18:04 -07:00
|
|
|
if err := k.Keeper.bank.SendCoinsFromAccountToModule(ctx, senderAddr, types.ModuleName, coins); err != nil {
|
2022-09-01 00:08:30 -07:00
|
|
|
return nil, fmt.Errorf("failed to transfer %s%s", auction.Ceiling, auction.Denom)
|
|
|
|
}
|
|
|
|
|
2022-08-27 19:48:00 -07:00
|
|
|
k.Keeper.SetAuction(ctx, auction)
|
|
|
|
next.AuctionId++
|
|
|
|
|
2022-08-30 12:33:47 -07:00
|
|
|
k.Keeper.SetNextAuction(ctx, types.NextAuction{AuctionId: next.AuctionId})
|
2022-08-27 14:19:03 -07:00
|
|
|
|
2022-08-27 19:48:00 -07:00
|
|
|
return &types.MsgNewAuctionResponse{
|
|
|
|
AuctionId: strconv.FormatUint(next.AuctionId, 10),
|
|
|
|
}, nil
|
2022-08-27 14:19:03 -07:00
|
|
|
}
|