2022-09-14 14:36:30 -07:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
colinearmath "colinear/x/colinearcore/math"
|
|
|
|
"colinear/x/colinearcore/types"
|
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (k msgServer) ClaimFunds(goCtx context.Context, msg *types.MsgClaimFunds) (*types.MsgClaimFundsResponse, error) {
|
|
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
|
|
|
|
// check that auction exists
|
|
|
|
auction, found := k.Keeper.GetAuction(ctx, msg.AuctionId)
|
|
|
|
if !found {
|
|
|
|
return nil, fmt.Errorf("auction %s not found", msg.AuctionId)
|
|
|
|
}
|
|
|
|
|
|
|
|
// check that auction is finalized
|
|
|
|
if auction.Best == nil {
|
|
|
|
return nil, fmt.Errorf("auction %s is not finalized", msg.AuctionId)
|
|
|
|
}
|
|
|
|
|
|
|
|
// check that auction has remaining funds to pay out
|
|
|
|
if auction.Remaining == "0" {
|
2022-09-14 14:41:58 -07:00
|
|
|
return nil, fmt.Errorf("auction %s has no payable %s remaining", msg.AuctionId, auction.Denom)
|
2022-09-14 14:36:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// check that sender is the selected provider for the auction
|
|
|
|
if auction.Best.Owner != msg.Creator {
|
|
|
|
return nil, fmt.Errorf("lease reward is only claimable by selected provider (%s) (got %s)", auction.Best.Owner, msg.Creator)
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse address to send to
|
|
|
|
sendTo, err := sdk.AccAddressFromBech32(auction.Best.Owner)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to parse address %s: %s", auction.Best.Owner, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate payable amount
|
|
|
|
total := new(big.Int)
|
|
|
|
total.SetString(auction.Best.Amount, 10)
|
|
|
|
remaining := new(big.Int)
|
|
|
|
remaining.SetString(auction.Remaining, 10)
|
|
|
|
leaseBegin := time.Unix(int64(auction.LeaseStart), 0)
|
|
|
|
leaseEnd := time.Unix(int64(auction.LeaseEnd), 0)
|
|
|
|
now := ctx.BlockTime()
|
|
|
|
subAmt, err := colinearmath.CalcAmountVestableLinear(total, remaining, now, leaseBegin, leaseEnd)
|
|
|
|
if err != nil {
|
2022-09-14 17:41:33 -07:00
|
|
|
return nil, fmt.Errorf("unable to calculate vestable amount: %s", err)
|
|
|
|
}
|
|
|
|
if subAmt.Cmp(big.NewInt(0)) == 0 {
|
|
|
|
return nil, fmt.Errorf("no claimable %s (calculated vesting amount is 0)", auction.Denom)
|
2022-09-14 14:36:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// pay from module to user account
|
2022-09-14 14:41:58 -07:00
|
|
|
coins := sdk.NewCoins(sdk.NewCoin(auction.Denom, sdk.NewIntFromBigInt(subAmt)))
|
2022-09-14 14:36:30 -07:00
|
|
|
if err := k.bank.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sendTo, coins); err != nil {
|
2022-09-14 14:41:58 -07:00
|
|
|
return nil, fmt.Errorf("failed to send %s %s from module %s", subAmt.String(), auction.Denom, types.ModuleName)
|
2022-09-14 14:36:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// subtract paid amount off of remaining payout tally & commit to chain state
|
|
|
|
newRemaining := new(big.Int)
|
|
|
|
newRemaining.Sub(remaining, subAmt)
|
2022-09-14 17:41:33 -07:00
|
|
|
auction.Remaining = newRemaining.String()
|
2022-09-14 14:36:30 -07:00
|
|
|
k.Keeper.SetAuction(ctx, auction)
|
|
|
|
|
2022-09-21 13:31:20 -07:00
|
|
|
ctx.EventManager().EmitEvent(
|
|
|
|
sdk.NewEvent(types.LeaseFundsClaimedEventType,
|
|
|
|
sdk.NewAttribute(types.LeaseFundsClaimedEventCreator, msg.Creator),
|
|
|
|
sdk.NewAttribute(types.LeaseFundsClaimedAmountClaimed, subAmt.String()),
|
|
|
|
sdk.NewAttribute(types.LeaseFundsClaimedAmountRemaining, auction.Remaining),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
2022-09-14 14:36:30 -07:00
|
|
|
return &types.MsgClaimFundsResponse{}, nil
|
|
|
|
}
|