Skip to content

Commit

Permalink
Extract reward token approve transaction to a separate function (#1594)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan-Ethernal committed Jun 8, 2023
1 parent c1d3a79 commit 52cae7e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 63 deletions.
73 changes: 46 additions & 27 deletions consensus/polybft/contracts_initializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const (
contractCallGasLimit = 100_000_000
)

// getInitValidatorSetInput builds input parameters for ValidatorSet SC initialization
func getInitValidatorSetInput(polyBFTConfig PolyBFTConfig) ([]byte, error) {
// initValidatorSet initializes ValidatorSet SC
func initValidatorSet(polyBFTConfig PolyBFTConfig, transition *state.Transition) error {
initialValidators := make([]*contractsapi.ValidatorInit, len(polyBFTConfig.InitialValidatorSet))
for i, validator := range polyBFTConfig.InitialValidatorSet {
initialValidators[i] = &contractsapi.ValidatorInit{
Expand All @@ -33,19 +33,31 @@ func getInitValidatorSetInput(polyBFTConfig PolyBFTConfig) ([]byte, error) {
InitialValidators: initialValidators,
}

return initFn.EncodeAbi()
input, err := initFn.EncodeAbi()
if err != nil {
return fmt.Errorf("ValidatorSet.initialize params encoding failed: %w", err)
}

return callContract(contracts.SystemCaller,
contracts.ValidatorSetContract, input, "ValidatorSet.initialize", transition)
}

// getInitRewardPoolInput builds input parameters for RewardPool SC initialization
func getInitRewardPoolInput(polybftConfig PolyBFTConfig) ([]byte, error) {
// initRewardPool initializes RewardPool SC
func initRewardPool(polybftConfig PolyBFTConfig, transition *state.Transition) error {
initFn := &contractsapi.InitializeRewardPoolFn{
NewRewardToken: polybftConfig.RewardConfig.TokenAddress,
NewRewardWallet: polybftConfig.RewardConfig.WalletAddress,
NewValidatorSet: contracts.ValidatorSetContract,
NewBaseReward: new(big.Int).SetUint64(polybftConfig.EpochReward),
}

return initFn.EncodeAbi()
input, err := initFn.EncodeAbi()
if err != nil {
return fmt.Errorf("RewardPool.initialize params encoding failed: %w", err)
}

return callContract(contracts.SystemCaller,
contracts.RewardPoolContract, input, "RewardPool.initialize", transition)
}

// getInitERC20PredicateInput builds initialization input parameters for child chain ERC20Predicate SC
Expand Down Expand Up @@ -205,24 +217,9 @@ func getInitERC1155PredicateACLInput(config *BridgeConfig, owner types.Address,
return params.EncodeAbi()
}

// mintRewardTokensToWalletAddress mints configured amount of reward tokens to reward wallet address
func mintRewardTokensToWalletAddress(polyBFTConfig *PolyBFTConfig, transition *state.Transition) error {
approveFn := &contractsapi.ApproveRootERC20Fn{
Spender: contracts.RewardPoolContract,
Amount: polyBFTConfig.RewardConfig.WalletAmount,
}

input, err := approveFn.EncodeAbi()
if err != nil {
return err
}

if err = callContract(polyBFTConfig.RewardConfig.WalletAddress,
polyBFTConfig.RewardConfig.TokenAddress, input, "RewardToken", transition); err != nil {
return err
}

if polyBFTConfig.RewardConfig.TokenAddress == contracts.NativeERC20TokenContract {
// mintRewardTokensToWallet mints configured amount of reward tokens to reward wallet address
func mintRewardTokensToWallet(polyBFTConfig PolyBFTConfig, transition *state.Transition) error {
if isNativeRewardToken(polyBFTConfig) {
// if reward token is a native erc20 token, we don't need to mint an amount of tokens
// for given wallet address to it since this is done in premine
return nil
Expand All @@ -233,13 +230,30 @@ func mintRewardTokensToWalletAddress(polyBFTConfig *PolyBFTConfig, transition *s
Amount: polyBFTConfig.RewardConfig.WalletAmount,
}

input, err = mintFn.EncodeAbi()
input, err := mintFn.EncodeAbi()
if err != nil {
return err
return fmt.Errorf("RewardToken.mint params encoding failed: %w", err)
}

return callContract(contracts.SystemCaller, polyBFTConfig.RewardConfig.TokenAddress, input,
"RewardToken", transition)
"RewardToken.mint", transition)
}

// approveRewardPoolAsSpender approves reward pool contract as reward token spender
// since reward pool distributes rewards.
func approveRewardPoolAsSpender(polyBFTConfig PolyBFTConfig, transition *state.Transition) error {
approveFn := &contractsapi.ApproveRootERC20Fn{
Spender: contracts.RewardPoolContract,
Amount: polyBFTConfig.RewardConfig.WalletAmount,
}

input, err := approveFn.EncodeAbi()
if err != nil {
return fmt.Errorf("RewardToken.approve params encoding failed: %w", err)
}

return callContract(polyBFTConfig.RewardConfig.WalletAddress,
polyBFTConfig.RewardConfig.TokenAddress, input, "RewardToken.approve", transition)
}

// callContract calls given smart contract function, encoded in input parameter
Expand All @@ -257,3 +271,8 @@ func callContract(from, to types.Address, input []byte, contractName string, tra

return nil
}

// isNativeRewardToken returns true in case a native token is used as a reward token as well
func isNativeRewardToken(cfg PolyBFTConfig) bool {
return cfg.RewardConfig.TokenAddress == contracts.NativeERC20TokenContract
}
22 changes: 8 additions & 14 deletions consensus/polybft/polybft.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,28 +131,22 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st
}

// initialize ValidatorSet SC
input, err := getInitValidatorSetInput(polyBFTConfig)
if err != nil {
if err = initValidatorSet(polyBFTConfig, transition); err != nil {
return err
}

if err = callContract(contracts.SystemCaller,
contracts.ValidatorSetContract, input, "ValidatorSet", transition); err != nil {
// approve reward pool
if err = approveRewardPoolAsSpender(polyBFTConfig, transition); err != nil {
return err
}

if err = mintRewardTokensToWalletAddress(&polyBFTConfig, transition); err != nil {
// mint reward tokens to reward wallet
if err = mintRewardTokensToWallet(polyBFTConfig, transition); err != nil {
return err
}

// initialize RewardPool SC
input, err = getInitRewardPoolInput(polyBFTConfig)
if err != nil {
return err
}

if err = callContract(contracts.SystemCaller,
contracts.RewardPoolContract, input, "RewardPool", transition); err != nil {
if err = initRewardPool(polyBFTConfig, transition); err != nil {
return err
}

Expand All @@ -179,7 +173,7 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st
}

// initialize ChildERC20PredicateAccessList SC
input, err = getInitERC20PredicateACLInput(polyBFTConfig.Bridge, owner, false)
input, err := getInitERC20PredicateACLInput(polyBFTConfig.Bridge, owner, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -245,7 +239,7 @@ func GenesisPostHookFactory(config *chain.Chain, engineName string) func(txn *st
}
} else {
// initialize ChildERC20Predicate SC
input, err = getInitERC20PredicateInput(bridgeCfg, false)
input, err := getInitERC20PredicateInput(bridgeCfg, false)
if err != nil {
return err
}
Expand Down
28 changes: 6 additions & 22 deletions consensus/polybft/sc_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,37 +335,21 @@ func TestIntegration_CommitEpoch(t *testing.T) {

transition := newTestTransition(t, alloc)

// get data for ChildValidatorSet initialization
initInput, err := getInitValidatorSetInput(polyBFTConfig)
require.NoError(t, err)

// init ChildValidatorSet
err = callContract(contracts.SystemCaller, contracts.ValidatorSetContract, initInput, "ChildValidatorSet", transition)
require.NoError(t, err)

initInput, err = getInitRewardPoolInput(polyBFTConfig)
// init ValidatorSet
err := initValidatorSet(polyBFTConfig, transition)
require.NoError(t, err)

// init RewardPool
err = callContract(contracts.SystemCaller, contracts.RewardPoolContract, initInput, "RewardPool", transition)
err = initRewardPool(polyBFTConfig, transition)
require.NoError(t, err)

// approve root token
approveFn := &contractsapi.ApproveRootERC20Fn{
Spender: contracts.RewardPoolContract,
Amount: polyBFTConfig.RewardConfig.WalletAmount,
}

input, err := approveFn.EncodeAbi()
require.NoError(t, err)

err = callContract(polyBFTConfig.RewardConfig.WalletAddress,
polyBFTConfig.RewardConfig.TokenAddress, input, "RewardToken", transition)
// approve reward pool as reward token spender
err = approveRewardPoolAsSpender(polyBFTConfig, transition)
require.NoError(t, err)

// create input for commit epoch
commitEpoch := createTestCommitEpochInput(t, 1, polyBFTConfig.EpochSize)
input, err = commitEpoch.EncodeAbi()
input, err := commitEpoch.EncodeAbi()
require.NoError(t, err)

// call commit epoch
Expand Down

0 comments on commit 52cae7e

Please sign in to comment.