diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 67e8abca6b..7a8fab3a3d 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -14,7 +14,7 @@
"300ms"
 

Default: "15s"Type: string

PollMinAllowedGasPriceInterval is the interval to poll the suggested min gas price for a tx


Examples:

"1m"
 
"300ms"
-

Default: 64Type: integer

AccountQueue represents the maximum number of non-executable transaction slots permitted per account


Default: 1024Type: integer

GlobalQueue represents the maximum number of non-executable transaction slots for all accounts


EffectiveGasPrice is the config for the effective gas price calculation
Default: falseType: boolean

Enabled is a flag to enable/disable the effective gas price


Default: 0.25Type: number

L1GasPriceFactor is the percentage of the L1 gas price that will be used as the L2 min gas price


Default: 16Type: integer

ByteGasCost is the gas cost per byte that is not 0


Default: 4Type: integer

ZeroByteGasCost is the gas cost per byte that is 0


Default: 1Type: number

NetProfit is the profit margin to apply to the calculated breakEvenGasPrice


Default: 1.1Type: number

BreakEvenFactor is the factor to apply to the calculated breakevenGasPrice when comparing it with the gasPriceSigned of a tx


Default: 10Type: integer

FinalDeviationPct is the max allowed deviation percentage BreakEvenGasPrice on re-calculation


Default: 0Type: integer

EthTransferGasPrice is the fixed gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0Type: number

EthTransferL1GasPriceFactor is the percentage of L1 gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0.5Type: number

L2GasPriceSuggesterFactor is the factor to apply to L1 gas price to get the suggested L2 gas price used in the
calculations when the effective gas price is disabled (testing/metrics purposes)


Default: 0Type: integer

ForkID is the current fork ID of the chain


Default: 1Type: number

TxFeeCap is the global transaction fee(price * gaslimit) cap for
send-transaction variants. The unit is ether. 0 means no cap.


Type: array of string

XLayer config
BlockedList is the blocked address list

Each item of this array must be:

Type: string

Default: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]Type: array of string

FreeGasAddress is the default free gas address

Each item of this array must be:

Type: string

Default: 150000Type: integer

FreeClaimGasLimit is the max gas allowed use to do a free claim


Type: array of string

BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

Each item of this array must be:

Type: string

Default: falseType: boolean

EnableFreeGasByNonce enable free gas


Type: array of string

FreeGasExAddress is the ex address which can be free gas for the transfer receiver

Each item of this array must be:

Type: string

Default: 0Type: integer

FreeGasCountPerAddr is the count limit of free gas tx per address


Default: 0Type: integer

FreeGasLimit is the max gas allowed use to do a free gas tx


Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the HTTP requests


Default: 8545Type: integer

Port defines the port to serve the endpoints via HTTP


Default: "1m0s"Type: string

ReadTimeout is the HTTP server read timeout
check net/http.server.ReadTimeout and net/http.server.ReadHeaderTimeout


Examples:

"1m"
+

Default: 64Type: integer

AccountQueue represents the maximum number of non-executable transaction slots permitted per account


Default: 1024Type: integer

GlobalQueue represents the maximum number of non-executable transaction slots for all accounts


EffectiveGasPrice is the config for the effective gas price calculation
Default: falseType: boolean

Enabled is a flag to enable/disable the effective gas price


Default: 0.25Type: number

L1GasPriceFactor is the percentage of the L1 gas price that will be used as the L2 min gas price


Default: 16Type: integer

ByteGasCost is the gas cost per byte that is not 0


Default: 4Type: integer

ZeroByteGasCost is the gas cost per byte that is 0


Default: 1Type: number

NetProfit is the profit margin to apply to the calculated breakEvenGasPrice


Default: 1.1Type: number

BreakEvenFactor is the factor to apply to the calculated breakevenGasPrice when comparing it with the gasPriceSigned of a tx


Default: 10Type: integer

FinalDeviationPct is the max allowed deviation percentage BreakEvenGasPrice on re-calculation


Default: 0Type: integer

EthTransferGasPrice is the fixed gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0Type: number

EthTransferL1GasPriceFactor is the percentage of L1 gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0.5Type: number

L2GasPriceSuggesterFactor is the factor to apply to L1 gas price to get the suggested L2 gas price used in the
calculations when the effective gas price is disabled (testing/metrics purposes)


Default: 0Type: integer

ForkID is the current fork ID of the chain


Default: 1Type: number

TxFeeCap is the global transaction fee(price * gaslimit) cap for
send-transaction variants. The unit is ether. 0 means no cap.


Type: array of string

XLayer config
BlockedList is the blocked address list

Each item of this array must be:


Default: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]Type: array of string

FreeGasAddress is the default free gas address

Each item of this array must be:


Default: 150000Type: integer

FreeClaimGasLimit is the max gas allowed use to do a free claim


Type: array of string

BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

Each item of this array must be:


Default: falseType: boolean

EnableFreeGasByNonce enable free gas


Type: array of string

FreeGasExAddress is the ex address which can be free gas for the transfer receiver

Each item of this array must be:


Default: 0Type: integer

FreeGasCountPerAddr is the count limit of free gas tx per address


Default: 0Type: integer

FreeGasLimit is the max gas allowed use to do a free gas tx


Default: falseType: boolean

EnableFreeGasList enable the special project of XLayer for free gas


Type: array of object

FreeGasList is the special project of XLayer

Each item of this array must be:


Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the HTTP requests


Default: 8545Type: integer

Port defines the port to serve the endpoints via HTTP


Default: "1m0s"Type: string

ReadTimeout is the HTTP server read timeout
check net/http.server.ReadTimeout and net/http.server.ReadHeaderTimeout


Examples:

"1m"
 
"300ms"
 

Default: "1m0s"Type: string

WriteTimeout is the HTTP server write timeout
check net/http.server.WriteTimeout


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 607bda00b9..8c8281c85c 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -715,6 +715,8 @@ SecretKey=""
 | - [FreeGasExAddress](#Pool_FreeGasExAddress )                                   | No      | array of string | No         | -          | FreeGasExAddress is the ex address which can be free gas for the transfer receiver                                                  |
 | - [FreeGasCountPerAddr](#Pool_FreeGasCountPerAddr )                             | No      | integer         | No         | -          | FreeGasCountPerAddr is the count limit of free gas tx per address                                                                   |
 | - [FreeGasLimit](#Pool_FreeGasLimit )                                           | No      | integer         | No         | -          | FreeGasLimit is the max gas allowed use to do a free gas tx                                                                         |
+| - [EnableFreeGasList](#Pool_EnableFreeGasList )                                 | No      | boolean         | No         | -          | EnableFreeGasList enable the special project of XLayer for free gas                                                                 |
+| - [FreeGasList](#Pool_FreeGasList )                                             | No      | array of object | No         | -          | FreeGasList is the special project of XLayer                                                                                        |
 
 ### 7.1. `Pool.IntervalToRefreshBlockedAddresses`
 
@@ -1321,6 +1323,70 @@ FreeGasCountPerAddr=0
 FreeGasLimit=0
 ```
 
+### 7.24. `Pool.EnableFreeGasList`
+
+**Type:** : `boolean`
+
+**Default:** `false`
+
+**Description:** EnableFreeGasList enable the special project of XLayer for free gas
+
+**Example setting the default value** (false):
+```
+[Pool]
+EnableFreeGasList=false
+```
+
+### 7.25. `Pool.FreeGasList`
+
+**Type:** : `array of object`
+**Description:** FreeGasList is the special project of XLayer
+
+|                      | Array restrictions |
+| -------------------- | ------------------ |
+| **Min items**        | N/A                |
+| **Max items**        | N/A                |
+| **Items unicity**    | False              |
+| **Additional items** | False              |
+| **Tuple validation** | See below          |
+
+| Each item of this array must be              | Description                                                 |
+| -------------------------------------------- | ----------------------------------------------------------- |
+| [FreeGasList items](#Pool_FreeGasList_items) | FreeGasInfo contains the details for what tx should be free |
+
+#### 7.25.1. [Pool.FreeGasList.FreeGasList items]
+
+**Type:** : `object`
+**Description:** FreeGasInfo contains the details for what tx should be free
+
+| Property                                                        | Pattern | Type            | Deprecated | Definition | Title/Description |
+| --------------------------------------------------------------- | ------- | --------------- | ---------- | ---------- | ----------------- |
+| - [Name](#Pool_FreeGasList_items_Name )                         | No      | string          | No         | -          | -                 |
+| - [FromList](#Pool_FreeGasList_items_FromList )                 | No      | array of string | No         | -          | -                 |
+| - [ToList](#Pool_FreeGasList_items_ToList )                     | No      | array of string | No         | -          | -                 |
+| - [MethodSigs](#Pool_FreeGasList_items_MethodSigs )             | No      | array of string | No         | -          | -                 |
+| - [GasPriceMultiple](#Pool_FreeGasList_items_GasPriceMultiple ) | No      | number          | No         | -          | -                 |
+
+##### 7.25.1.1. `Pool.FreeGasList.FreeGasList items.Name`
+
+**Type:** : `string`
+
+##### 7.25.1.2. `Pool.FreeGasList.FreeGasList items.FromList`
+
+**Type:** : `array of string`
+
+##### 7.25.1.3. `Pool.FreeGasList.FreeGasList items.ToList`
+
+**Type:** : `array of string`
+
+##### 7.25.1.4. `Pool.FreeGasList.FreeGasList items.MethodSigs`
+
+**Type:** : `array of string`
+
+##### 7.25.1.5. `Pool.FreeGasList.FreeGasList items.GasPriceMultiple`
+
+**Type:** : `number`
+
 ## 8. `[RPC]`
 
 **Type:** : `object`
@@ -2080,7 +2146,7 @@ SpecialApis=[]
 | ----------------------------------------------------- | ---------------------------------------------------------- |
 | [SpecialApis items](#RPC_RateLimit_SpecialApis_items) | RateLimitItem defines the special rate limit for some apis |
 
-##### 8.25.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items]
+##### 8.25.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items]
 
 **Type:** : `object`
 **Description:** RateLimitItem defines the special rate limit for some apis
@@ -2315,7 +2381,7 @@ ApiKeys=[]
 | ----------------------------------------------------- | --------------------------- |
 | [ApiKeys items](#RPC_ApiAuthentication_ApiKeys_items) | KeyItem is the api key item |
 
-##### 8.29.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items]
+##### 8.29.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items]
 
 **Type:** : `object`
 **Description:** KeyItem is the api key item
@@ -4633,7 +4699,7 @@ RollupManagerBlockNumber=0
 | ----------------------------------------------------- | ------------------------------------------------------------------------- |
 | [Actions items](#NetworkConfig_Genesis_Actions_items) | GenesisAction represents one of the values set on the SMT during genesis. |
 
-##### 13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
+##### 13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
 
 **Type:** : `object`
 **Description:** GenesisAction represents one of the values set on the SMT during genesis.
@@ -5513,7 +5579,7 @@ ChainID=0
 | ----------------------------------------------------- | ------------------------------------ |
 | [ForkIDIntervals items](#State_ForkIDIntervals_items) | ForkIDInterval is a fork id interval |
 
-#### 20.3.1. [State.ForkIDIntervals.ForkIDIntervals items]
+#### 20.3.1. [State.ForkIDIntervals.ForkIDIntervals items]
 
 **Type:** : `object`
 **Description:** ForkIDInterval is a fork id interval
diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json
index 847d43b296..9414fe86d0 100644
--- a/docs/config-file/node-config-schema.json
+++ b/docs/config-file/node-config-schema.json
@@ -505,6 +505,46 @@
 					"type": "integer",
 					"description": "FreeGasLimit is the max gas allowed use to do a free gas tx",
 					"default": 0
+				},
+				"EnableFreeGasList": {
+					"type": "boolean",
+					"description": "EnableFreeGasList enable the special project of XLayer for free gas",
+					"default": false
+				},
+				"FreeGasList": {
+					"items": {
+						"properties": {
+							"Name": {
+								"type": "string"
+							},
+							"FromList": {
+								"items": {
+									"type": "string"
+								},
+								"type": "array"
+							},
+							"ToList": {
+								"items": {
+									"type": "string"
+								},
+								"type": "array"
+							},
+							"MethodSigs": {
+								"items": {
+									"type": "string"
+								},
+								"type": "array"
+							},
+							"GasPriceMultiple": {
+								"type": "number"
+							}
+						},
+						"additionalProperties": false,
+						"type": "object",
+						"description": "FreeGasInfo contains the details for what tx should be free"
+					},
+					"type": "array",
+					"description": "FreeGasList is the special project of XLayer"
 				}
 			},
 			"additionalProperties": false,
diff --git a/pool/apollo_xlayer.go b/pool/apollo_xlayer.go
index bad98fad87..16ea4953cd 100644
--- a/pool/apollo_xlayer.go
+++ b/pool/apollo_xlayer.go
@@ -21,6 +21,11 @@ type apolloConfig struct {
 	FreeGasCountPerAddr  uint64
 	FreeGasLimit         uint64
 
+	// for special project
+	EnableFreeGasList  bool
+	FreeGasFromNameMap map[string]string       // map[from]projectName
+	FreeGasList        map[string]*FreeGasInfo // map[projectName]FreeGasInfo
+
 	BlockedList []string
 
 	sync.RWMutex
@@ -43,6 +48,21 @@ func (c *apolloConfig) enable() bool {
 	return c.EnableApollo
 }
 
+func (c *apolloConfig) setFreeGasList(freeGasList []FreeGasInfo) {
+	if c == nil || !c.EnableApollo {
+		return
+	}
+	c.FreeGasFromNameMap = make(map[string]string)
+	c.FreeGasList = make(map[string]*FreeGasInfo, len(freeGasList))
+	for _, info := range freeGasList {
+		for _, from := range info.FromList {
+			c.FreeGasFromNameMap[from] = info.Name
+		}
+		infoCopy := info
+		c.FreeGasList[info.Name] = &infoCopy
+	}
+}
+
 func (c *apolloConfig) setFreeGasAddresses(freeGasAddrs []string) {
 	if c == nil || !c.EnableApollo {
 		return
@@ -95,6 +115,8 @@ func UpdateConfig(apolloConfig Config) {
 	getApolloConfig().setFreeGasExAddresses(apolloConfig.FreeGasExAddress)
 	getApolloConfig().FreeGasCountPerAddr = apolloConfig.FreeGasCountPerAddr
 	getApolloConfig().FreeGasLimit = apolloConfig.FreeGasLimit
+	getApolloConfig().EnableFreeGasList = apolloConfig.EnableFreeGasList
+	getApolloConfig().setFreeGasList(apolloConfig.FreeGasList)
 
 	getApolloConfig().Unlock()
 }
@@ -119,10 +141,10 @@ func isFreeGasAddress(localFreeGasAddrs []string, address common.Address) bool {
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return contains(getApolloConfig().FreeGasAddresses, address)
+		return Contains(getApolloConfig().FreeGasAddresses, address)
 	}
 
-	return contains(localFreeGasAddrs, address)
+	return Contains(localFreeGasAddrs, address)
 }
 
 func getEnableFreeGasByNonce(enableFreeGasByNonce bool) bool {
@@ -139,10 +161,10 @@ func isFreeGasExAddress(localFreeGasExAddrs []string, address common.Address) bo
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return contains(getApolloConfig().FreeGasExAddress, address)
+		return Contains(getApolloConfig().FreeGasExAddress, address)
 	}
 
-	return contains(localFreeGasExAddrs, address)
+	return Contains(localFreeGasExAddrs, address)
 }
 
 func getFreeGasCountPerAddr(localFreeGasCountPerAddr uint64) uint64 {
@@ -197,8 +219,39 @@ func isBlockedAddress(localBlockedList []string, address common.Address) bool {
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return contains(getApolloConfig().BlockedList, address)
+		return Contains(getApolloConfig().BlockedList, address)
+	}
+
+	return Contains(localBlockedList, address)
+}
+
+// GetEnableSpecialFreeGasList returns enable flag of FreeGasList
+func GetEnableSpecialFreeGasList(enableFreeGasList bool) bool {
+	if getApolloConfig().enable() {
+		getApolloConfig().RLock()
+		defer getApolloConfig().RUnlock()
+		return getApolloConfig().EnableFreeGasList
+	}
+	return enableFreeGasList
+}
+
+// GetSpecialFreeGasList returns the special project in XLayer for free gas
+func GetSpecialFreeGasList(freeGasList []FreeGasInfo) (map[string]string, map[string]*FreeGasInfo) {
+	if getApolloConfig().enable() {
+		getApolloConfig().RLock()
+		defer getApolloConfig().RUnlock()
+		return getApolloConfig().FreeGasFromNameMap, getApolloConfig().FreeGasList
+	}
+
+	freeGasFromNameMap := make(map[string]string)
+	freeGasMap := make(map[string]*FreeGasInfo, len(freeGasList))
+	for _, info := range freeGasList {
+		for _, from := range info.FromList {
+			freeGasFromNameMap[from] = info.Name
+		}
+		infoCopy := info
+		freeGasMap[info.Name] = &infoCopy
 	}
 
-	return contains(localBlockedList, address)
+	return freeGasFromNameMap, freeGasMap
 }
diff --git a/pool/config.go b/pool/config.go
index 283788a706..a7cd61baa1 100644
--- a/pool/config.go
+++ b/pool/config.go
@@ -71,6 +71,19 @@ type Config struct {
 	FreeGasCountPerAddr uint64 `mapstructure:"FreeGasCountPerAddr"`
 	// FreeGasLimit is the max gas allowed use to do a free gas tx
 	FreeGasLimit uint64 `mapstructure:"FreeGasLimit"`
+	// EnableFreeGasList enable the special project of XLayer for free gas
+	EnableFreeGasList bool `mapstructure:"EnableFreeGasList"`
+	// FreeGasList is the special project of XLayer
+	FreeGasList []FreeGasInfo `mapstructure:"FreeGasList"`
+}
+
+// FreeGasInfo contains the details for what tx should be free
+type FreeGasInfo struct {
+	Name             string   `mapstructure:"Name"`
+	FromList         []string `mapstructure:"FromList"`
+	ToList           []string `mapstructure:"ToList"`
+	MethodSigs       []string `mapstructure:"MethodSigs"`
+	GasPriceMultiple float64  `mapstructure:"GasPriceMultiple"`
 }
 
 // EffectiveGasPriceCfg contains the configuration properties for the effective gas price
diff --git a/pool/pool_xlayer.go b/pool/pool_xlayer.go
index ce7b4f1f3a..e6d2e16713 100644
--- a/pool/pool_xlayer.go
+++ b/pool/pool_xlayer.go
@@ -31,7 +31,8 @@ const (
 	MainnetBridgeURL = "https://www.okx.com/xlayer/bridge"
 )
 
-func contains(s []string, ele common.Address) bool {
+// Contains returns if string[] contains ele string
+func Contains(s []string, ele common.Address) bool {
 	for _, e := range s {
 		if common.HexToAddress(e) == ele {
 			return true
@@ -40,6 +41,16 @@ func contains(s []string, ele common.Address) bool {
 	return false
 }
 
+// ContainsMethod returns if data has prefix of method sig
+func ContainsMethod(data string, methods []string) bool {
+	for _, m := range methods {
+		if strings.HasPrefix(data, m) {
+			return true
+		}
+	}
+	return false
+}
+
 // StartRefreshingWhiteAddressesPeriodically will make this instance of the pool
 // to check periodically(accordingly to the configuration) for updates regarding
 // the white address and update the in memory blocked addresses
@@ -113,9 +124,23 @@ func (p *Pool) GetDynamicGasPrice() *big.Int {
 }
 
 func (p *Pool) checkFreeGp(ctx context.Context, poolTx Transaction, from common.Address) (bool, error) {
-	if isFreeGasAddress(p.cfg.FreeGasAddress, from) && poolTx.IsClaims { // claim tx
+	// claim tx
+	if isFreeGasAddress(p.cfg.FreeGasAddress, from) && poolTx.IsClaims {
 		return true, nil
 	}
+
+	// special project
+	if GetEnableSpecialFreeGasList(p.cfg.EnableFreeGasList) {
+		fromToName, freeGpList := GetSpecialFreeGasList(p.cfg.FreeGasList)
+		info := freeGpList[fromToName[from.String()]]
+		if info != nil &&
+			Contains(info.ToList, *poolTx.To()) &&
+			ContainsMethod("0x"+common.Bytes2Hex(poolTx.Data()), info.MethodSigs) {
+			return true, nil
+		}
+	}
+
+	// new bridge address
 	if getEnableFreeGasByNonce(p.cfg.EnableFreeGasByNonce) && poolTx.GasPrice().Cmp(big.NewInt(0)) == 0 { // free-gas tx by count
 		isFreeAddr, err := p.storage.IsFreeGasAddr(ctx, from)
 		if err != nil {
diff --git a/sequencer/sequencer.go b/sequencer/sequencer.go
index 2ba8dfb96d..c99ef4f661 100644
--- a/sequencer/sequencer.go
+++ b/sequencer/sequencer.go
@@ -231,18 +231,19 @@ func (s *Sequencer) addTxToWorker(ctx context.Context, tx pool.Transaction) erro
 		return err
 	}
 
-	// XLayer claim tx
-	freeGp, isClaimTx := s.checkFreeGas(tx, txTracker)
+	// XLayer free gas tx
+	freeGp, isClaimTx, gp := s.checkFreeGas(tx, txTracker)
 	if freeGp {
 		defaultGp := s.pool.GetDynamicGasPrice()
-		baseGp := s.worker.getBaseClaimGp(defaultGp)
-		copyBaseGp := new(big.Int).Set(baseGp)
+		copyBaseGp := new(big.Int)
 		if isClaimTx {
 			txTracker.IsClaimTx = true
-			txTracker.GasPrice = copyBaseGp.Mul(copyBaseGp, new(big.Int).SetUint64(uint64(getGasPriceMultiple(s.cfg.GasPriceMultiple))))
+			baseGp := s.worker.getBaseClaimGp(defaultGp)
+			copyBaseGp.Set(baseGp)
 		} else {
-			txTracker.GasPrice = defaultGp.Mul(defaultGp, new(big.Int).SetUint64(uint64(getInitGasPriceMultiple(s.cfg.InitGasPriceMultiple))))
+			copyBaseGp.Set(defaultGp)
 		}
+		txTracker.GasPrice = copyBaseGp.Mul(copyBaseGp, new(big.Int).SetUint64(uint64(gp)))
 	}
 
 	replacedTx, dropReason := s.worker.AddTxTracker(ctx, txTracker)
diff --git a/sequencer/sequencer_xlayer.go b/sequencer/sequencer_xlayer.go
index 838c9a8e4e..3a27452f22 100644
--- a/sequencer/sequencer_xlayer.go
+++ b/sequencer/sequencer_xlayer.go
@@ -9,6 +9,7 @@ import (
 	"github.com/0xPolygonHermez/zkevm-node/pool"
 	pmetric "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics"
 	"github.com/0xPolygonHermez/zkevm-node/state"
+	"github.com/ethereum/go-ethereum/common"
 )
 
 var countinterval = 10
@@ -36,14 +37,29 @@ func (s *Sequencer) countReadyTx() {
 	state.InfiniteSafeRun(s.updateReadyTxCount, "error counting ready tx", time.Second)
 }
 
-func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (freeGp, claimTx bool) {
+func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (freeGp, claimTx bool, gpMul float64) {
 	// check if tx is init-free-gas and if it can be prior pack
 	freeGp = tx.GasPrice().Cmp(big.NewInt(0)) == 0
+	gpMul = getInitGasPriceMultiple(s.cfg.InitGasPriceMultiple)
 
 	// check if tx is bridge-claim
 	addrs := getPackBatchSpacialList(s.cfg.PackBatchSpacialList)
 	if addrs[txTracker.FromStr] {
 		claimTx = true
+		gpMul = getGasPriceMultiple(s.cfg.GasPriceMultiple)
+		return
+	}
+
+	// check if tx is from special project
+	if pool.GetEnableSpecialFreeGasList(s.poolCfg.EnableFreeGasList) {
+		fromToName, freeGpList := pool.GetSpecialFreeGasList(s.poolCfg.FreeGasList)
+		info := freeGpList[fromToName[txTracker.FromStr]]
+		if info != nil &&
+			pool.Contains(info.ToList, *tx.To()) &&
+			pool.ContainsMethod("0x"+common.Bytes2Hex(tx.Data()), info.MethodSigs) {
+			gpMul = info.GasPriceMultiple
+			return
+		}
 	}
 
 	return
diff --git a/test/Makefile b/test/Makefile
index d1df75cd76..01b7da898c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,4 +1,4 @@
-DOCKERCOMPOSE := docker-compose -f docker-compose.yml
+DOCKERCOMPOSE := docker compose -f docker-compose.yml
 DOCKERCOMPOSEAPPSEQ := xlayer-sequencer
 DOCKERCOMPOSEAPPSEQSENDER := xlayer-sequence-sender
 DOCKERCOMPOSEAPPSIGNER := xlayer-signer