Created
April 20, 2022 10:00
-
-
Save jelilat/76905e7d847911bf29233c65795c093e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package keeper | |
import ( | |
"context" | |
"fmt" | |
"strconv" | |
"github.com/cosmonaut/gofundme/x/gofundme/types" | |
sdk "github.com/cosmos/cosmos-sdk/types" | |
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | |
) | |
func (k msgServer) WithdrawDonation(goCtx context.Context, msg *types.MsgWithdrawDonation) (*types.MsgWithdrawDonationResponse, error) { | |
ctx := sdk.UnwrapSDKContext(goCtx) | |
//Get the gofundme campaign with the given id | |
gofundme, found := k.GetGofundme(ctx, msg.Id) | |
if !found { | |
return nil, sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, "gofundme with id %s not found", msg.Id) | |
} | |
//Confirm that the donations have not been claimed | |
if gofundme.Claim == true { | |
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "gofundme with id %s has already been claimed", msg.Id) | |
} | |
//Get the end date | |
end, err := sdk.ParseTimeBytes([]byte(gofundme.End)) | |
if err != nil { | |
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Can't withdraw donations until the end of the gofundme campaign.") | |
} | |
//Check whether the current time is after the end date | |
if ctx.BlockTime().Before(end) { | |
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "gofundme campaign is not over. Please wait until the end date") | |
} | |
//Get gofundme creator and message sender | |
creator := sdk.AccAddress(gofundme.Creator) | |
messageSender := sdk.AccAddress(msg.Creator) | |
//Get total donations and gofundme goal | |
totalDonations := gofundme.Totaldonations | |
goal := gofundme.Goal | |
stringTotalDonation := strconv.FormatUint(totalDonations, 10) | |
normalizedTotalDonation, _ := sdk.ParseCoinsNormalized(stringTotalDonation) | |
fmt.Print(creator, messageSender) | |
//Ensure that creator can withdraw only if the goal was met | |
if creator.Equals(messageSender) && totalDonations < goal { | |
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Can't withdraw donations because goal wasn't met.") | |
} | |
if creator.Equals(messageSender) && totalDonations >= goal { | |
//update claim to true | |
gofundme.Claim = true | |
sdkError := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, creator, normalizedTotalDonation) | |
if sdkError != nil { | |
return nil, sdkError | |
} | |
} | |
//Ensure that donor can withdraw only if goal wasn't met | |
if !creator.Equals(messageSender) && totalDonations >= goal { | |
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Only the owner of the crowdfund can withdraw donations") | |
} | |
if !creator.Equals(messageSender) && totalDonations < goal { | |
var index int | |
for idx, v := range gofundme.Donation { | |
if v == msg.Creator { | |
index = idx | |
break | |
} | |
} | |
donation := gofundme.Donation[index] | |
normalizedDonation, _ := sdk.ParseCoinsNormalized(donation) | |
//Ensure that donor can only withdraw once | |
if normalizedDonation.IsZero() { | |
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Donation already withdrawn") | |
} | |
//Update the donation amount to zero to reflect that the donation was withdrawn | |
gofundme.Donation[index] = "0" | |
sdkError := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, messageSender, normalizedDonation) | |
if sdkError != nil { | |
return nil, sdkError | |
} | |
} | |
k.SetGofundme(ctx, gofundme) | |
return &types.MsgWithdrawDonationResponse{}, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment