github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/erc20/proposal_handler.go (about)

     1  package erc20
     2  
     3  import (
     4  	ethcmm "github.com/ethereum/go-ethereum/common"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
     9  	"github.com/fibonacci-chain/fbc/x/common"
    10  	"github.com/fibonacci-chain/fbc/x/erc20/types"
    11  	govTypes "github.com/fibonacci-chain/fbc/x/gov/types"
    12  )
    13  
    14  // NewProposalHandler handles "gov" type message in "erc20"
    15  func NewProposalHandler(k *Keeper) govTypes.Handler {
    16  	return func(ctx sdk.Context, proposal *govTypes.Proposal) (err sdk.Error) {
    17  		switch content := proposal.Content.(type) {
    18  		case types.TokenMappingProposal:
    19  			return handleTokenMappingProposal(ctx, k, content)
    20  		case types.ProxyContractRedirectProposal:
    21  			return handleProxyContractRedirectProposal(ctx, k, content)
    22  		case types.ContractTemplateProposal:
    23  			return handleContractTemplateProposal(ctx, k, content)
    24  		default:
    25  			return common.ErrUnknownProposalType(types.DefaultCodespace, content.ProposalType())
    26  		}
    27  	}
    28  }
    29  
    30  func handleTokenMappingProposal(ctx sdk.Context, k *Keeper, p types.TokenMappingProposal) sdk.Error {
    31  	if p.Denom == sdk.DefaultBondDenom || p.Denom == sdk.DefaultIbcWei {
    32  		return govTypes.ErrInvalidProposalContent("invalid denom, not support fibo or wei denom")
    33  	}
    34  
    35  	if len(p.Contract) == 0 {
    36  		// delete existing mapping
    37  		k.DeleteContractForDenom(ctx, p.Denom)
    38  	} else {
    39  		// update the mapping
    40  		contract := ethcmm.HexToAddress(p.Contract)
    41  		if tmtypes.HigherThanVenus3(ctx.BlockHeight()) {
    42  			// contract must already be deployed, to avoid empty contract
    43  			contractAccount, _ := k.GetEthAccount(ctx, contract)
    44  			if contractAccount == nil || !contractAccount.IsContract() {
    45  				return sdkerrors.Wrapf(types.ErrNoContractDeployed, "no contract code found at address %s", p.Contract)
    46  			}
    47  		}
    48  		if err := k.SetContractForDenom(ctx, p.Denom, contract); err != nil {
    49  			return err
    50  		}
    51  	}
    52  	return nil
    53  }
    54  
    55  func handleProxyContractRedirectProposal(ctx sdk.Context, k *Keeper, p types.ProxyContractRedirectProposal) sdk.Error {
    56  	address := ethcmm.HexToAddress(p.Addr)
    57  
    58  	return k.ProxyContractRedirect(ctx, p.Denom, p.Tp, address)
    59  }
    60  
    61  func handleContractTemplateProposal(ctx sdk.Context, k *Keeper, p types.ContractTemplateProposal) sdk.Error {
    62  	return k.SetTemplateContract(ctx, p.ContractType, p.Contract)
    63  }