mirror of
https://github.com/colinear-labs/chain.git
synced 2026-03-05 05:04:25 -08:00
basic linear vesting payouts (manual claim)
This commit is contained in:
72
x/colinearcore/keeper/msg_server_claim_funds.go
Normal file
72
x/colinearcore/keeper/msg_server_claim_funds.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"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" {
|
||||
return nil, fmt.Errorf("auction %s has no payable CLR remaining", msg.AuctionId)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, errors.New("unable to calculate vestable amount")
|
||||
}
|
||||
|
||||
// pay from module to user account
|
||||
coins := sdk.NewCoins(sdk.NewCoin("uclr", sdk.NewIntFromBigInt(subAmt)))
|
||||
if err := k.bank.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sendTo, coins); err != nil {
|
||||
return nil, fmt.Errorf("failed to send %s uCLR from module %s", subAmt.String(), types.ModuleName)
|
||||
}
|
||||
|
||||
// subtract paid amount off of remaining payout tally & commit to chain state
|
||||
newRemaining := new(big.Int)
|
||||
newRemaining.Sub(remaining, subAmt)
|
||||
auction.Remaining = subAmt.String()
|
||||
k.Keeper.SetAuction(ctx, auction)
|
||||
|
||||
return &types.MsgClaimFundsResponse{}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user