Skip to content

Commit

Permalink
Remove IsMintable native token flag (#22)
Browse files Browse the repository at this point in the history
* Remove IsMintable native token flag

* Remove key from PremineInfo

* Add blade admin flag (#24)

* Introduce blade admin

* Move to the newest main branch on contracts

* Remove NativeTokenConfig from e2e tests

* Comments fix

---------

Co-authored-by: Goran Rojovic <100121253+goran-ethernal@users.noreply.github.com>
  • Loading branch information
Stefan-Ethernal and goran-ethernal authored Nov 28, 2023
1 parent 6b95bb1 commit 013b5f2
Show file tree
Hide file tree
Showing 24 changed files with 146 additions and 697 deletions.
30 changes: 1 addition & 29 deletions command/bridge/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const (
exitHelperName = "ExitHelper"
rootERC20PredicateName = "RootERC20Predicate"
childERC20MintablePredicateName = "ChildERC20MintablePredicate"
rootERC20Name = "RootERC20"
erc20TemplateName = "ERC20Template"
rootERC721PredicateName = "RootERC721Predicate"
childERC721MintablePredicateName = "ChildERC721MintablePredicate"
Expand Down Expand Up @@ -78,9 +77,6 @@ var (
rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.ChildMintableERC20PredicateAddress = addr
},
rootERC20Name: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.RootNativeERC20Address = addr
},
erc20TemplateName: func(rootchainConfig *polybft.RootchainConfig, addr types.Address) {
rootchainConfig.ChildERC20Address = addr
},
Expand Down Expand Up @@ -133,7 +129,7 @@ var (
NewChildERC20Predicate: contracts.ChildERC20PredicateContract,
NewChildTokenTemplate: contracts.ChildERC20Contract,
// map root native token address should be non-zero only if native token is non-mintable on a childchain
NewNativeTokenRoot: config.RootNativeERC20Address,
NewNativeTokenRoot: types.ZeroAddress,
}

return initContract(fmt, relayer, inputParams,
Expand Down Expand Up @@ -247,13 +243,6 @@ func GetCommand() *cobra.Command {
"the JSON RPC rootchain IP address",
)

cmd.Flags().StringVar(
&params.rootERC20TokenAddr,
erc20AddrFlag,
"",
"existing root chain root native token address",
)

cmd.Flags().BoolVar(
&params.isTestMode,
helper.TestModeFlag,
Expand Down Expand Up @@ -419,21 +408,6 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client,
StakeManagerAddress: types.StringToAddress(params.stakeManagerAddr),
}

tokenContracts := []*contractInfo{}

// deploy root ERC20 token only if non-mintable native token flavor is used on a child chain
if params.rootERC20TokenAddr != "" {
// use existing root chain ERC20 token
if err := populateExistingTokenAddr(client.Eth(),
params.rootERC20TokenAddr, rootERC20Name, rootchainConfig); err != nil {
return deploymentResultInfo{RootchainCfg: nil, CommandResults: nil}, err
}
} else {
// deploy MockERC20 as a root chain root native token
tokenContracts = append(tokenContracts,
&contractInfo{name: rootERC20Name, artifact: contractsapi.RootERC20})
}

allContracts := []*contractInfo{
{
name: stateSenderName,
Expand Down Expand Up @@ -515,8 +489,6 @@ func deployContracts(outputter command.OutputFormatter, client *jsonrpc.Client,
},
}

allContracts = append(tokenContracts, allContracts...)

g, ctx := errgroup.WithContext(cmdCtx)
results := make(map[string]*deployContractResult, len(allContracts))
resultsLock := sync.Mutex{}
Expand Down
7 changes: 3 additions & 4 deletions command/bridge/deploy/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ func TestDeployContracts_NoPanics(t *testing.T) {
params.proxyContractsAdmin = "0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed"
consensusCfg = polybft.PolyBFTConfig{
NativeTokenConfig: &polybft.TokenConfig{
Name: "Test",
Symbol: "TST",
Decimals: 18,
IsMintable: false,
Name: "Test",
Symbol: "TST",
Decimals: 18,
},
}

Expand Down
7 changes: 0 additions & 7 deletions command/bridge/deploy/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ import (
const (
deployerKeyFlag = "deployer-key"
jsonRPCFlag = "json-rpc"
erc20AddrFlag = "erc20-token"
)

type deployParams struct {
genesisPath string
deployerKey string
jsonRPCAddress string
stakeTokenAddr string
rootERC20TokenAddr string
stakeManagerAddr string
proxyContractsAdmin string
isTestMode bool
Expand All @@ -42,11 +40,6 @@ func (ip *deployParams) validateFlags() error {
return errors.New("native token configuration is undefined")
}

// when using mintable native token, child native token on root chain gets mapped automatically
if consensusCfg.NativeTokenConfig.IsMintable && ip.rootERC20TokenAddr != "" {
return errors.New("if child chain native token is mintable, root native token must not pre-exist on root chain")
}

if params.stakeTokenAddr == "" {
return errors.New("stake token address is not provided")
}
Expand Down
9 changes: 8 additions & 1 deletion command/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func setFlags(cmd *cobra.Command) {
nativeTokenConfigFlag,
"",
"native token configuration, provided in the following format: "+
"<name:symbol:decimals count:mintable token owner address>",
"<name:symbol:decimals count>",
)

cmd.Flags().StringVar(
Expand Down Expand Up @@ -220,6 +220,13 @@ func setFlags(cmd *cobra.Command) {
defaultBlockTrackerPollInterval,
"interval (number of seconds) at which block tracker polls for latest block at rootchain",
)

cmd.Flags().StringVar(
&params.bladeAdmin,
bladeAdminFlag,
"",
"address of owner/admin of NativeERC20 token and StakeManager",
)
}

// Access Control Lists
Expand Down
9 changes: 6 additions & 3 deletions command/genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ var (
errBaseFeeEMZero = errors.New("base fee elasticity multiplier must be greater than 0")
errBaseFeeZero = errors.New("base fee must be greater than 0")
errRewardWalletNotDefined = errors.New("reward wallet address must be defined")
errRewardTokenOnNonMintable = errors.New("a custom reward token must be defined when " +
"native ERC20 token is non-mintable")
errRewardWalletZero = errors.New("reward wallet address must not be zero address")
errRewardWalletZero = errors.New("reward wallet address must not be zero address")
)

type genesisParams struct {
Expand Down Expand Up @@ -113,6 +111,7 @@ type genesisParams struct {
blockTrackerPollInterval time.Duration

proxyContractsAdmin string
bladeAdmin string
}

func (p *genesisParams) validateFlags() error {
Expand Down Expand Up @@ -156,6 +155,10 @@ func (p *genesisParams) validateFlags() error {
return err
}

if err := p.validateBladeAdminFlag(); err != nil {
return err
}

if err := p.parseStakeInfo(); err != nil {
return err
}
Expand Down
27 changes: 9 additions & 18 deletions command/genesis/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,31 @@ func Test_extractNativeTokenMetadata(t *testing.T) {
},
{
name: "not enough params provided",
rawConfig: "Test:TST:18",
rawConfig: "Test:TST",
expectErr: true,
},
{
name: "empty name provided",
rawConfig: ":TST:18:0x123456789",
rawConfig: ":TST:18",
expectErr: true,
},
{
name: "empty symbol provided",
rawConfig: "Test::18:0x123456789",
rawConfig: "Test::18",
expectErr: true,
},
{
name: "invalid decimals number provided",
rawConfig: "Test:TST:9999999999999999999999999999999999999999999999999999999999:false:0x123456789",
rawConfig: "Test:TST:9999999999999999999999999999999999999999999999999999999999:false",
expectErr: true,
},
{
name: "valid config",
rawConfig: "MyToken:MTK:9:0x123456789",
rawConfig: "MyToken:MTK:9",
expectedCfg: &polybft.TokenConfig{
Name: "MyToken",
Symbol: "MTK",
Decimals: 9,
IsMintable: true,
Owner: types.StringToAddress("0x123456789"),
Name: "MyToken",
Symbol: "MTK",
Decimals: 9,
},
expectErr: false,
},
Expand Down Expand Up @@ -185,13 +183,6 @@ func Test_validateRewardWallet(t *testing.T) {
isNativeERC20Mintable: true,
expectValidateErr: nil,
},
{
name: "valid reward wallet: native ERC20 mintable",
rewardWallet: types.StringToAddress("1").String() + ":0",
epochReward: 0,
isNativeERC20Mintable: false,
expectValidateErr: errRewardTokenOnNonMintable,
},
}
for _, c := range cases {
c := c
Expand All @@ -201,7 +192,7 @@ func Test_validateRewardWallet(t *testing.T) {
p := &genesisParams{
rewardWallet: c.rewardWallet,
epochReward: c.epochReward,
nativeTokenConfig: &polybft.TokenConfig{IsMintable: c.isNativeERC20Mintable},
nativeTokenConfig: &polybft.TokenConfig{},
}
err := p.validateRewardWalletAndToken()
require.ErrorIs(t, err, c.expectValidateErr)
Expand Down
99 changes: 41 additions & 58 deletions command/genesis/polybft_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
bridgeAllowListEnabledFlag = "bridge-allow-list-enabled"
bridgeBlockListAdminFlag = "bridge-block-list-admin"
bridgeBlockListEnabledFlag = "bridge-block-list-enabled"
bladeAdminFlag = "blade-admin"

bootnodePortStart = 30301

Expand All @@ -57,9 +58,13 @@ const (
)

var (
errNoGenesisValidators = errors.New("genesis validators aren't provided")
errNoPremineAllowed = errors.New("native token is not mintable, so no premine is allowed " +
"except for zero address and reward wallet if native token is used as reward token")
errNoGenesisValidators = errors.New("genesis validators aren't provided")
errProxyAdminNotProvided = errors.New("proxy contracts admin address must be set")
errProxyAdminIsZeroAddress = errors.New("proxy contracts admin address must not be zero address")
errProxyAdminIsSystemCaller = errors.New("proxy contracts admin address must not be system caller address")
errBladeAdminNotProvided = errors.New("blade admin address must be set")
errBladeAdminIsZeroAddress = errors.New("blade admin address must not be zero address")
errBladeAdminIsSystemCaller = errors.New("blade admin address must not be system caller address")
)

type contractInfo struct {
Expand All @@ -81,16 +86,6 @@ func (p *genesisParams) generateChainConfig(o command.OutputFormatter) error {
return fmt.Errorf("invalid reward wallet configuration provided '%s' : %w", p.rewardWallet, err)
}

if !p.nativeTokenConfig.IsMintable {
// validate premine map, no premine is allowed if token is not mintable,
// except for the reward wallet (if native token is used as reward token) and zero address
for a := range premineBalances {
if a != types.ZeroAddress && (p.rewardTokenCode != "" || a != walletPremineInfo.Address) {
return errNoPremineAllowed
}
}
}

var (
rewardTokenByteCode []byte
rewardTokenAddr = contracts.NativeERC20TokenContract
Expand Down Expand Up @@ -151,6 +146,7 @@ func (p *genesisParams) generateChainConfig(o command.OutputFormatter) error {
BlockTimeDrift: p.blockTimeDrift,
BlockTrackerPollInterval: common.Duration{Duration: p.blockTrackerPollInterval},
ProxyContractsAdmin: types.StringToAddress(p.proxyContractsAdmin),
BladeAdmin: types.StringToAddress(p.bladeAdmin),
}

enabledForks := chain.AllForksEnabled
Expand Down Expand Up @@ -339,20 +335,10 @@ func (p *genesisParams) deployContracts(
artifact: contractsapi.RootERC20,
address: contracts.ERC20Contract,
},
}

if !params.nativeTokenConfig.IsMintable {
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.NativeERC20,
address: contracts.NativeERC20TokenContractV1,
})
} else {
genesisContracts = append(genesisContracts,
&contractInfo{
artifact: contractsapi.NativeERC20,
address: contracts.NativeERC20TokenContractV1,
})
{
artifact: contractsapi.NativeERC20,
address: contracts.NativeERC20TokenContractV1,
},
}

if len(params.bridgeAllowListAdmin) != 0 || len(params.bridgeBlockListAdmin) != 0 {
Expand Down Expand Up @@ -510,40 +496,12 @@ func (p *genesisParams) getValidatorAccounts() ([]*validator.GenesisValidator, e
return validators, nil
}

// validatePolyBFTParams validates params for polybft consensus
func (p *genesisParams) validatePolyBFTParams() error {
if err := p.extractNativeTokenMetadata(); err != nil {
return err
}

if err := p.validateRewardWalletAndToken(); err != nil {
return err
}

if err := p.validatePremineInfo(); err != nil {
return err
}

if p.epochSize < 2 {
// Epoch size must be greater than 1, so new transactions have a chance to be added to a block.
// Otherwise, every block would be an endblock (meaning it will not have any transactions).
// Check is placed here to avoid additional parsing if epochSize < 2
return errInvalidEpochSize
}

return p.validateProxyContractsAdmin()
}

// validateRewardWalletAndToken validates reward wallet flag
func (p *genesisParams) validateRewardWalletAndToken() error {
if p.rewardWallet == "" {
return errRewardWalletNotDefined
}

if !p.nativeTokenConfig.IsMintable && p.rewardTokenCode == "" {
return errRewardTokenOnNonMintable
}

premineInfo, err := helper.ParsePremineInfo(p.rewardWallet)
if err != nil {
return err
Expand All @@ -563,16 +521,41 @@ func (p *genesisParams) validateRewardWalletAndToken() error {

func (p *genesisParams) validateProxyContractsAdmin() error {
if strings.TrimSpace(p.proxyContractsAdmin) == "" {
return errors.New("proxy contracts admin address must be set")
return errProxyAdminNotProvided
}

if err := types.IsValidAddress(p.proxyContractsAdmin); err != nil {
return fmt.Errorf("proxy contracts admin address is not a valid address: %w", err)
}

proxyContractsAdminAddr := types.StringToAddress(p.proxyContractsAdmin)
if proxyContractsAdminAddr == types.ZeroAddress {
return errors.New("proxy contracts admin address must not be zero address")
return errProxyAdminIsZeroAddress
}

if proxyContractsAdminAddr == contracts.SystemCaller {
return errors.New("proxy contracts admin address must not be system caller address")
return errProxyAdminIsSystemCaller
}

return nil
}

func (p *genesisParams) validateBladeAdminFlag() error {
if strings.TrimSpace(p.bladeAdmin) == "" {
return errBladeAdminNotProvided
}

if err := types.IsValidAddress(p.bladeAdmin); err != nil {
return fmt.Errorf("blade admin address is not a valid address: %w", err)
}

bladeAdminAddr := types.StringToAddress(p.proxyContractsAdmin)
if bladeAdminAddr == types.ZeroAddress {
return errBladeAdminIsZeroAddress
}

if bladeAdminAddr == contracts.SystemCaller {
return errBladeAdminIsSystemCaller
}

return nil
Expand Down
Loading

0 comments on commit 013b5f2

Please sign in to comment.