Compare commits

...

22 Commits

Author SHA1 Message Date
georgehao
2fd6fea95f feat: debug performance 2024-03-26 13:34:53 +08:00
Steven
9e8c3432c3 fix(libzkp): upgrade to use prover v0.9.7 (#989)
Co-authored-by: silathdiir <silathdiir@users.noreply.github.com>
2023-10-13 02:34:56 -05:00
Xi Lin
ff380141a8 feat(contracts): update ScrollOwner initialization script (#987)
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-10-12 08:51:20 +02:00
HAOYUatHZ
2216ad4271 refactor: remove rpc-gateway submodule (#985) 2023-10-11 16:57:41 +08:00
colin
25d5fabac9 fix(gas-oracle): fetch block header (#984)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-10-10 17:25:39 +08:00
colin
d494f4419c feat(bridge-history-api): add USDC/LIDO/DAI gateways (#983)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-10-09 20:40:12 +08:00
colin
e843419397 fix(rollup-relayer): better estimate commit batch gas limit (#982)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-10-09 08:31:31 +02:00
colin
badde3cba5 fix(rollup-relayer): better handle commit batch revert (#981)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
2023-10-08 13:39:17 +02:00
colin
caa16e1676 fix(rollup-relayer): address underestimation of commitBatch gas in low-tx batches (#980)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-10-07 15:35:53 +02:00
Xi Lin
7c742da488 feat(contracts): add emergency role to pause L1/L2ScrollMessenger (#975)
Co-authored-by: Péter Garamvölgyi <peter@scroll.io>
2023-10-07 11:33:09 +02:00
Péter Garamvölgyi
0cdb0dc7a9 feat: remove DAI gateway from deployment script (#979) 2023-10-06 18:03:21 +02:00
Xi Lin
3143373f5f feat(contracts): remove rate limiter related codes (#978) 2023-10-05 21:16:01 +02:00
Steven
18ee6a67c5 fix(libzkp): upgrade libzkp to v0.9.5 (#977)
Co-authored-by: silathdiir <silathdiir@users.noreply.github.com>
2023-10-05 01:53:24 -05:00
Xi Lin
05da46a719 test(contracts): OZ-L01 Insufficient Tests When Using BitMaps (#956)
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-10-04 15:59:53 -07:00
Xi Lin
55e0b11d17 fix(contracts): OZ-N03 Inconsistent Usage of msg.sender (#906) 2023-10-04 15:45:17 -07:00
Steven
6f72d0447e fix(libzkp): upgrade libzkp to v0.9.4 (#973)
Co-authored-by: silathdiir <silathdiir@users.noreply.github.com>
Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com>
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-10-02 15:39:51 +08:00
georgehao
76d66eba58 feat: add chunk/batch get_task index (#976)
Co-authored-by: maskpp <maskpp266@gmail.com>
2023-09-29 08:55:10 -05:00
colin
c551609e17 feat(watcher&rollup): add block commit calldata size and commit/finalize batch revert metrics (#974)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-09-29 15:33:08 +08:00
colin
47e5a43646 fix(bridge-history): add cache hit tracing logs (#972) 2023-09-27 13:11:01 +08:00
colin
7604612581 refactor(bridge-history): rename metrics (#971)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-09-27 01:07:22 +08:00
colin
35d4ec5ad0 feat(bridge-history): add cache hit metrics and cache non-existent keys (#970)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-09-26 23:43:09 +08:00
colin
8f745e9836 fix(bridge-history): duplicated symbol and metric prefix (#969)
Co-authored-by: colinlyguo <colinlyguo@users.noreply.github.com>
2023-09-26 18:52:18 +08:00
86 changed files with 663 additions and 1119 deletions

3
.gitmodules vendored
View File

@@ -1,9 +1,6 @@
[submodule "l2geth"]
path = l2geth
url = git@github.com:scroll-tech/go-ethereum.git
[submodule "rpc-gateway"]
path = rpc-gateway
url = git@github.com:scroll-tech/rpc-gateway.git
[submodule "contracts/lib/ds-test"]
path = contracts/lib/ds-test
url = https://github.com/dapphub/ds-test

View File

@@ -82,6 +82,18 @@ func action(ctx *cli.Context) error {
common.HexToAddress(cfg.L1.WETHGatewayAddr),
}
if cfg.L1.USDCGatewayAddr != "" {
l1AddressList = append(l1AddressList, common.HexToAddress(cfg.L1.USDCGatewayAddr))
}
if cfg.L1.LIDOGatewayAddr != "" {
l1AddressList = append(l1AddressList, common.HexToAddress(cfg.L1.LIDOGatewayAddr))
}
if cfg.L2.DAIGatewayAddr != "" {
l1AddressList = append(l1AddressList, common.HexToAddress(cfg.L1.DAIGatewayAddr))
}
l2AddressList := []common.Address{
common.HexToAddress(cfg.L2.CustomERC20GatewayAddr),
common.HexToAddress(cfg.L2.ERC721GatewayAddr),
@@ -92,6 +104,18 @@ func action(ctx *cli.Context) error {
common.HexToAddress(cfg.L2.WETHGatewayAddr),
}
if cfg.L2.USDCGatewayAddr != "" {
l2AddressList = append(l2AddressList, common.HexToAddress(cfg.L2.USDCGatewayAddr))
}
if cfg.L2.LIDOGatewayAddr != "" {
l2AddressList = append(l2AddressList, common.HexToAddress(cfg.L2.LIDOGatewayAddr))
}
if cfg.L2.DAIGatewayAddr != "" {
l2AddressList = append(l2AddressList, common.HexToAddress(cfg.L2.DAIGatewayAddr))
}
l1crossMsgFetcher, err := crossmsg.NewMsgFetcher(subCtx, cfg.L1, db, l1client, l1worker, l1AddressList, crossmsg.L1ReorgHandling)
if err != nil {
log.Crit("failed to create l1 cross message fetcher", "error", err)

View File

@@ -1,33 +1,39 @@
{
"batchInfoFetcher": {
"batchIndexStartBlock": 9091265,
"ScrollChainAddr": "0xcD00DB804C819175B381b2B44Aa16A391c8a01D6"
"ScrollChainAddr": "0x1799c3Df650caB9DFBb228C971016707D8f8721D"
},
"l1": {
"confirmation": 64,
"endpoint": "https://rpc.ankr.com/eth_goerli",
"startHeight": 9090194 ,
"endpoint": "https://rpc.ankr.com/eth",
"startHeight": 18310747,
"blockTime": 10,
"MessengerAddr": "0x326517Eb8eB1Ce5eaB5b513C2e9A24839b402d90",
"ETHGatewayAddr": "0x8305cB7B8448677736095965B63d7431017328fe",
"WETHGatewayAddr": "0xe3bA3c60d99a2d9a5f817734bC85353470b23931",
"StandardERC20Gateway": "0x16c1079B27eD9c363B7D08aC5Ae937A398972A5C",
"CustomERC20GatewayAddr": "0x61f08caD3d6F77801167d3bA8669433701586643",
"ERC721GatewayAddr": "0x4A73D25A4C99CB912acaf6C5B5e554f2982201c5",
"ERC1155GatewayAddr": "0xa3F5DD3033698c2832C53f3C3Fe6E062F58cD808"
"MessengerAddr": "0x7318152B19c3c97c886D5ee6C2525E62ce8e2abA",
"ETHGatewayAddr": "0xd165b42d857eae2915625819464a2a1f91E5d0A5",
"WETHGatewayAddr": "0xb0255e4C1a919619D1CafBA51021d638c4F71b89",
"StandardERC20Gateway": "0x00fEc01A9b975bA37466B4E9006dF2C71BFE0e48",
"CustomERC20GatewayAddr": "0xD8874B0E6C3CC43C00B69D60c21Ef452d1159bDe",
"ERC721GatewayAddr": "0x131B46649F6882d686a766cb8b68c4cB0ACdeb24",
"ERC1155GatewayAddr": "0xCeE721789FAA05c7F4463efB664520656aB7C7d5",
"USDCGatewayAddr": "0x37ba659D6CC380D12Fb96567CC52FC8e1DF4E334",
"LIDOGatewayAddr": "0x892dDB2899325aBBA1fD00FDA8249B40Cbbc33F9",
"DAIGatewayAddr": "0xD8dD7787f89c7E6243AD32E0d0cCf460243C8130"
},
"l2": {
"confirmation": 1,
"endpoint": "http://staging-l2geth-rpc0.scroll.tech:8545",
"endpoint": "http://mainnet-l2geth-internal-1.mainnet.scroll.tech:8545",
"blockTime": 3,
"startHeight": 0,
"CustomERC20GatewayAddr": "0x905db21f836749fEeD12de781afc4A5Ab4Dd0d51",
"ERC721GatewayAddr": "0xC53D835514780664BCd7eCfcE7c2E5d9554dc41B",
"StandardERC20Gateway": "0x90271634BCB020e06ea4840C3f7aa61b8F860651",
"MessengerAddr": "0xE8b0956Ac75c65Aa1669e83888DA13afF2E108f4",
"ETHGatewayAddr": "0xD5938590D5dD8ce95812D4D515a219C12C551D67",
"WETHGatewayAddr": "0xb0aaA582564fade4232a16fdB1383004A6A7247F",
"ERC1155GatewayAddr": "0x4f33B1655619c2C0B7C450128Df760B4365Cb549"
"MessengerAddr": "0xda7c91Ed60DACD28Cb97B180108958c9ACC7698a",
"ETHGatewayAddr": "0x567671187b5FFbcDFe0B6EcF3e56C05508a31A87",
"WETHGatewayAddr": "0x3b03aE2F27d62E0B2b6740CA20Fc07Af4338B791",
"StandardERC20Gateway": "0xb00cb1F6f7C43D2EE8C4e2163a6bEA22441A5B7c",
"CustomERC20GatewayAddr": "0x63CCb38E9d21A72777b203267F2e4ba5C974fC62",
"ERC721GatewayAddr": "0xE2c36a2D8B5528719aE7A42A778b2D08b18d134a",
"ERC1155GatewayAddr": "0xfF14870512e42BFb85a9B7bEfDc06e9aB5A37269",
"USDCGatewayAddr": "0x97D5799CDC8eE2A7452913d7548c7cEE285719FA",
"LIDOGatewayAddr": "0xE9c5C9f67ec7B773fC76440845751F657bb953FF",
"DAIGatewayAddr": "0xC5034eB8F682b73F93C9246aa95A8eBbF82793aA"
},
"db": {
"dsn": "postgres://postgres:1234@localhost:5444/test?sslmode=disable",

View File

@@ -31,6 +31,9 @@ type LayerConfig struct {
MessengerAddr string `json:"MessengerAddr"`
ETHGatewayAddr string `json:"ETHGatewayAddr"`
WETHGatewayAddr string `json:"WETHGatewayAddr"`
USDCGatewayAddr string `json:"USDCGatewayAddr"`
LIDOGatewayAddr string `json:"LIDOGatewayAddr"`
DAIGatewayAddr string `json:"DAIGatewayAddr"`
StandardERC20Gateway string `json:"StandardERC20Gateway"`
ERC721GatewayAddr string `json:"ERC721GatewayAddr"`
ERC1155GatewayAddr string `json:"ERC1155GatewayAddr"`

View File

@@ -11,10 +11,6 @@ var (
HistoryCtrler *HistoryController
// BatchCtrler is controller instance
BatchCtrler *BatchController
// HealthCheck the health check controller
HealthCheck *HealthCheckController
// Ready the ready controller
Ready *ReadyController
initControllerOnce sync.Once
)
@@ -24,7 +20,5 @@ func InitController(db *gorm.DB) {
initControllerOnce.Do(func() {
HistoryCtrler = NewHistoryController(db)
BatchCtrler = NewBatchController(db)
HealthCheck = NewHealthCheckController(db)
Ready = NewReadyController()
})
}

View File

@@ -1,30 +0,0 @@
package controller
import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"bridge-history-api/internal/types"
"bridge-history-api/utils"
)
// HealthCheckController is health check API
type HealthCheckController struct {
db *gorm.DB
}
// NewHealthCheckController returns an HealthCheckController instance
func NewHealthCheckController(db *gorm.DB) *HealthCheckController {
return &HealthCheckController{
db: db,
}
}
// HealthCheck the api controller for coordinator health check
func (a *HealthCheckController) HealthCheck(c *gin.Context) {
if _, err := utils.Ping(a.db); err != nil {
types.RenderFatal(c, err)
return
}
types.RenderSuccess(c, nil)
}

View File

@@ -26,6 +26,7 @@ type HistoryController struct {
historyLogic *logic.HistoryLogic
cache *cache.Cache
singleFlight singleflight.Group
cacheMetrics *cacheMetrics
}
// NewHistoryController return HistoryController instance
@@ -33,6 +34,7 @@ func NewHistoryController(db *gorm.DB) *HistoryController {
return &HistoryController{
historyLogic: logic.NewHistoryLogic(db),
cache: cache.New(30*time.Second, 10*time.Minute),
cacheMetrics: initCacheMetrics(),
}
}
@@ -46,12 +48,22 @@ func (c *HistoryController) GetAllClaimableTxsByAddr(ctx *gin.Context) {
cacheKey := cacheKeyPrefixClaimableTxsByAddr + req.Address
if cachedData, found := c.cache.Get(cacheKey); found {
if resultData, ok := cachedData.(*types.ResultData); ok {
c.cacheMetrics.cacheHits.WithLabelValues("GetAllClaimableTxsByAddr").Inc()
// Log cache hit along with request param.
log.Info("cache hit", "request", req)
if cachedData == nil {
types.RenderSuccess(ctx, &types.ResultData{})
return
} else if resultData, ok := cachedData.(*types.ResultData); ok {
types.RenderSuccess(ctx, resultData)
return
}
// Log error for unexpected type, then fetch data from the database.
log.Error("unexpected type in cache", "expected", "*types.ResultData", "got", reflect.TypeOf(cachedData))
} else {
c.cacheMetrics.cacheMisses.WithLabelValues("GetAllClaimableTxsByAddr").Inc()
// Log cache miss along with request param.
log.Info("cache miss", "request", req)
}
result, err, _ := c.singleFlight.Do(cacheKey, func() (interface{}, error) {
@@ -86,7 +98,7 @@ func (c *HistoryController) PostQueryTxsByHash(ctx *gin.Context) {
}
if len(req.Txs) > 10 {
types.RenderFailure(ctx, types.ErrParameterInvalidNo, errors.New("the number of hashes in the request exceeds the allowed maximum"))
types.RenderFailure(ctx, types.ErrParameterInvalidNo, errors.New("the number of hashes in the request exceeds the allowed maximum of 10"))
return
}
hashesMap := make(map[string]struct{}, len(req.Txs))
@@ -101,13 +113,21 @@ func (c *HistoryController) PostQueryTxsByHash(ctx *gin.Context) {
cacheKey := cacheKeyPrefixQueryTxsByHash + hash
if cachedData, found := c.cache.Get(cacheKey); found {
if txInfo, ok := cachedData.(*types.TxHistoryInfo); ok {
c.cacheMetrics.cacheHits.WithLabelValues("PostQueryTxsByHash").Inc()
// Log cache hit along with tx hash.
log.Info("cache hit", "tx hash", hash)
if cachedData == nil {
continue
} else if txInfo, ok := cachedData.(*types.TxHistoryInfo); ok {
results = append(results, txInfo)
} else {
log.Error("unexpected type in cache", "expected", "*types.TxHistoryInfo", "got", reflect.TypeOf(cachedData))
uncachedHashes = append(uncachedHashes, hash)
}
} else {
c.cacheMetrics.cacheMisses.WithLabelValues("PostQueryTxsByHash").Inc()
// Log cache miss along with tx hash.
log.Info("cache miss", "tx hash", hash)
uncachedHashes = append(uncachedHashes, hash)
}
}
@@ -119,10 +139,20 @@ func (c *HistoryController) PostQueryTxsByHash(ctx *gin.Context) {
return
}
resultMap := make(map[string]*types.TxHistoryInfo)
for _, result := range dbResults {
results = append(results, result)
cacheKey := cacheKeyPrefixQueryTxsByHash + result.Hash
c.cache.Set(cacheKey, result, cache.DefaultExpiration)
resultMap[result.Hash] = result
}
for _, hash := range uncachedHashes {
cacheKey := cacheKeyPrefixQueryTxsByHash + hash
result, found := resultMap[hash]
if found {
c.cache.Set(cacheKey, result, cache.DefaultExpiration)
} else {
c.cache.Set(cacheKey, nil, cache.DefaultExpiration)
}
}
}

View File

@@ -0,0 +1,40 @@
package controller
import (
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
type cacheMetrics struct {
cacheHits *prometheus.CounterVec
cacheMisses *prometheus.CounterVec
}
var (
initMetricsOnce sync.Once
cm *cacheMetrics
)
func initCacheMetrics() *cacheMetrics {
initMetricsOnce.Do(func() {
cm = &cacheMetrics{
cacheHits: promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "bridge_history_api_cache_hits_total",
Help: "The total number of cache hits",
},
[]string{"api"},
),
cacheMisses: promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "bridge_history_api_cache_misses_total",
Help: "The total number of cache misses",
},
[]string{"api"},
),
}
})
return cm
}

View File

@@ -1,21 +0,0 @@
package controller
import (
"github.com/gin-gonic/gin"
"bridge-history-api/internal/types"
)
// ReadyController ready API
type ReadyController struct {
}
// NewReadyController returns an ReadyController instance
func NewReadyController() *ReadyController {
return &ReadyController{}
}
// Ready the api controller for coordinator ready
func (r *ReadyController) Ready(c *gin.Context) {
types.RenderSuccess(c, nil)
}

View File

@@ -22,7 +22,7 @@ func Route(router *gin.Engine, conf *config.Config, reg prometheus.Registerer) {
MaxAge: 12 * time.Hour,
}))
observability.Use(router, "bridge-history", reg)
observability.Use(router, "bridge_history_api", reg)
r := router.Group("api/")
r.POST("/txsbyhashes", controller.HistoryCtrler.PostQueryTxsByHash)

View File

@@ -26,9 +26,7 @@ const (
// QueryByAddressRequest the request parameter of address api
type QueryByAddressRequest struct {
Address string `form:"address" binding:"required"`
Page int `form:"page,default=1"`
PageSize int `form:"page_size,default=10"`
Address string `form:"address" binding:"required"`
}
// QueryByHashRequest the request parameter of hash api

View File

@@ -4,7 +4,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus"
"scroll-tech/common/observability/ginmetrics"
"bridge-history-api/observability/ginmetrics"
)
// Use register the gin metric

View File

@@ -4,8 +4,8 @@ import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"scroll-tech/common/database"
"scroll-tech/common/types"
"bridge-history-api/internal/types"
"bridge-history-api/utils"
)
// ProbesController probe check controller
@@ -22,7 +22,7 @@ func NewProbesController(db *gorm.DB) *ProbesController {
// HealthCheck the api controller for health check
func (a *ProbesController) HealthCheck(c *gin.Context) {
if _, err := database.Ping(a.db); err != nil {
if _, err := utils.Ping(a.db); err != nil {
types.RenderFatal(c, err)
return
}

View File

@@ -16,7 +16,7 @@ import (
"github.com/urfave/cli/v2"
"gorm.io/gorm"
"scroll-tech/common/utils"
"bridge-history-api/utils"
)
// Server starts the metrics server on the given address, will be closed when the given

View File

@@ -31,7 +31,7 @@ dependencies = [
[[package]]
name = "aggregator"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"ark-std",
"env_logger 0.10.0",
@@ -333,7 +333,7 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "bus-mapping"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"eth-types",
"ethers-core",
@@ -959,7 +959,7 @@ dependencies = [
[[package]]
name = "eth-types"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"ethers-core",
"ethers-signers",
@@ -1116,7 +1116,7 @@ dependencies = [
[[package]]
name = "external-tracer"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"eth-types",
"geth-utils",
@@ -1296,7 +1296,7 @@ dependencies = [
[[package]]
name = "gadgets"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"digest 0.7.6",
"eth-types",
@@ -1328,7 +1328,7 @@ dependencies = [
[[package]]
name = "geth-utils"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"env_logger 0.9.3",
"gobuild 0.1.0-alpha.2 (git+https://github.com/scroll-tech/gobuild.git)",
@@ -1497,7 +1497,7 @@ dependencies = [
[[package]]
name = "halo2-mpt-circuits"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/mpt-circuit.git?tag=v0.6.5#0bae9eeb813583c11f6db1f961a7e92f8c9bda82"
source = "git+https://github.com/scroll-tech/mpt-circuit.git?tag=v0.7.0#578c210ceb88d3c143ee2a013ad836d19285d9c1"
dependencies = [
"ethers-core",
"halo2_proofs",
@@ -1519,7 +1519,7 @@ dependencies = [
[[package]]
name = "halo2_proofs"
version = "0.2.0"
source = "git+https://github.com/scroll-tech/halo2.git?branch=develop#aa86c107aeb62282d81ebce5c4930ec0c0aa540b"
source = "git+https://github.com/scroll-tech/halo2.git?branch=develop#e3fe25eadd714fd991f35190d17ff0b8fb031188"
dependencies = [
"ark-std",
"blake2b_simd",
@@ -1937,7 +1937,7 @@ dependencies = [
[[package]]
name = "keccak256"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"env_logger 0.9.3",
"eth-types",
@@ -2135,7 +2135,7 @@ dependencies = [
[[package]]
name = "mock"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"eth-types",
"ethers-core",
@@ -2151,7 +2151,7 @@ dependencies = [
[[package]]
name = "mpt-zktrie"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"eth-types",
"halo2-mpt-circuits",
@@ -2582,7 +2582,7 @@ dependencies = [
[[package]]
name = "prover"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"aggregator",
"anyhow",
@@ -4125,7 +4125,7 @@ checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
[[package]]
name = "zkevm-circuits"
version = "0.1.0"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.3#f7fb2900514c38b0ee15b1666c696df4b75a61ca"
source = "git+https://github.com/scroll-tech/zkevm-circuits.git?tag=v0.9.7#2055cc0bb970aa28d597c945b6078e2469af8862"
dependencies = [
"array-init",
"bus-mapping",

View File

@@ -21,7 +21,7 @@ halo2curves = { git = "https://github.com/scroll-tech/halo2curves.git", branch =
[dependencies]
halo2_proofs = { git = "https://github.com/scroll-tech/halo2.git", branch = "develop" }
prover = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.9.3", default-features = false, features = ["parallel_syn", "scroll", "shanghai"] }
prover = { git = "https://github.com/scroll-tech/zkevm-circuits.git", tag = "v0.9.7", default-features = false, features = ["parallel_syn", "scroll", "shanghai"] }
base64 = "0.13.0"
env_logger = "0.9.0"

View File

@@ -15,9 +15,16 @@ import (
// CalldataNonZeroByteGas is the gas consumption per non zero byte in calldata.
const CalldataNonZeroByteGas = 16
// GetKeccak256Gas calculates keccak256 hash gas.
// GetKeccak256Gas calculates the gas cost for computing the keccak256 hash of a given size.
func GetKeccak256Gas(size uint64) uint64 {
return 30 + 6*((size+31)/32) // 30 + 6 * ceil(size / 32)
return GetMemoryExpansionCost(size) + 30 + 6*((size+31)/32)
}
// GetMemoryExpansionCost calculates the cost of memory expansion for a given memoryByteSize.
func GetMemoryExpansionCost(memoryByteSize uint64) uint64 {
memorySizeWord := (memoryByteSize + 31) / 32
memoryCost := (memorySizeWord*memorySizeWord)/512 + (3 * memorySizeWord)
return memoryCost
}
// WrappedBlock contains the block's Header, Transactions and WithdrawTrieRoot hash.
@@ -131,6 +138,12 @@ func (w *WrappedBlock) EstimateL1CommitGas() uint64 {
total += 100 * numL1Messages // numL1Messages times call to L1MessageQueue
total += 100 * numL1Messages // numL1Messages times warm address access to L1MessageQueue
total += GetMemoryExpansionCost(36) * numL1Messages // staticcall to proxy
total += 100 * numL1Messages // read admin in proxy
total += 100 * numL1Messages // read impl in proxy
total += 100 * numL1Messages // access impl
total += GetMemoryExpansionCost(36) * numL1Messages // delegatecall to impl
return total
}

View File

@@ -46,7 +46,7 @@ func TestChunkEncode(t *testing.T) {
},
}
assert.Equal(t, uint64(0), chunk.NumL1Messages(0))
assert.Equal(t, uint64(6006), chunk.EstimateL1CommitGas())
assert.Equal(t, uint64(6042), chunk.EstimateL1CommitGas())
bytes, err = chunk.Encode(0)
hexString := hex.EncodeToString(bytes)
assert.NoError(t, err)
@@ -68,7 +68,7 @@ func TestChunkEncode(t *testing.T) {
},
}
assert.Equal(t, uint64(11), chunk.NumL1Messages(0))
assert.Equal(t, uint64(5002), chunk.EstimateL1CommitGas())
assert.Equal(t, uint64(5329), chunk.EstimateL1CommitGas())
bytes, err = chunk.Encode(0)
hexString = hex.EncodeToString(bytes)
assert.NoError(t, err)
@@ -84,7 +84,7 @@ func TestChunkEncode(t *testing.T) {
},
}
assert.Equal(t, uint64(11), chunk.NumL1Messages(0))
assert.Equal(t, uint64(9958), chunk.EstimateL1CommitGas())
assert.Equal(t, uint64(10612), chunk.EstimateL1CommitGas())
bytes, err = chunk.Encode(0)
hexString = hex.EncodeToString(bytes)
assert.NoError(t, err)

View File

@@ -5,7 +5,7 @@ import (
"runtime/debug"
)
var tag = "v4.3.22"
var tag = "v4.3.35"
var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {

View File

@@ -260,23 +260,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -371,22 +354,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### updateTokenMapping
```solidity
@@ -563,23 +530,6 @@ Emitted when some ERC1155 token is refunded.
| tokenId | uint256 | undefined |
| amount | uint256 | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |
### UpdateTokenMapping
```solidity

View File

@@ -227,23 +227,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -316,22 +299,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### updateTokenMapping
```solidity
@@ -502,23 +469,6 @@ Emitted when some ERC721 token is refunded.
| recipient `indexed` | address | undefined |
| tokenId | uint256 | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |
### UpdateTokenMapping
```solidity

View File

@@ -239,23 +239,6 @@ Mapping from queue index to previous replay queue index.
|---|---|---|
| _0 | uint256 | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of ETH rate limiter contract.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### relayMessageWithProof
```solidity
@@ -453,22 +436,6 @@ Update max replay times.
|---|---|---|
| _newMaxReplayTimes | uint256 | The new max replay times. |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### xDomainMessageSender
```solidity
@@ -642,22 +609,5 @@ Emitted when the maximum number of times each message can be replayed is updated
| oldMaxReplayTimes | uint256 | undefined |
| newMaxReplayTimes | uint256 | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |

View File

@@ -225,23 +225,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -292,22 +275,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
## Events
@@ -405,22 +372,5 @@ Emitted when some ERC20 token is refunded.
| recipient `indexed` | address | undefined |
| amount | uint256 | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |

View File

@@ -223,23 +223,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -290,22 +273,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
## Events
@@ -403,22 +370,5 @@ Emitted when some ERC20 token is refunded.
| recipient `indexed` | address | undefined |
| amount | uint256 | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |

View File

@@ -205,23 +205,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -316,22 +299,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### updateTokenMapping
```solidity
@@ -488,23 +455,6 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |
### UpdateTokenMapping
```solidity

View File

@@ -174,23 +174,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -263,22 +246,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### updateTokenMapping
```solidity
@@ -430,23 +397,6 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |
### UpdateTokenMapping
```solidity

View File

@@ -155,23 +155,6 @@ function paused() external view returns (bool)
|---|---|---|
| _0 | bool | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of ETH rate limiter contract.
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### relayMessage
```solidity
@@ -290,22 +273,6 @@ Update fee vault contract.
|---|---|---|
| _newFeeVault | address | The address of new fee vault contract. |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### xDomainMessageSender
```solidity
@@ -479,22 +446,5 @@ Emitted when the maximum number of times each message can fail in L2 is updated.
| oldMaxFailedExecutionTimes | uint256 | undefined |
| newMaxFailedExecutionTimes | uint256 | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |

View File

@@ -139,23 +139,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -223,22 +206,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### withdrawERC20
```solidity
@@ -354,23 +321,6 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |
### WithdrawERC20
```solidity

View File

@@ -172,23 +172,6 @@ function owner() external view returns (address)
*Returns the address of the current owner.*
#### Returns
| Name | Type | Description |
|---|---|---|
| _0 | address | undefined |
### rateLimiter
```solidity
function rateLimiter() external view returns (address)
```
The address of token rate limiter contract.
#### Returns
| Name | Type | Description |
@@ -239,22 +222,6 @@ function transferOwnership(address newOwner) external nonpayable
|---|---|---|
| newOwner | address | undefined |
### updateRateLimiter
```solidity
function updateRateLimiter(address _newRateLimiter) external nonpayable
```
Update rate limiter contract.
*This function can only called by contract owner.*
#### Parameters
| Name | Type | Description |
|---|---|---|
| _newRateLimiter | address | The address of new rate limiter contract. |
### withdrawERC20
```solidity
@@ -370,23 +337,6 @@ event OwnershipTransferred(address indexed previousOwner, address indexed newOwn
| previousOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
### UpdateRateLimiter
```solidity
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter)
```
Emitted when owner updates rate limiter contract.
#### Parameters
| Name | Type | Description |
|---|---|---|
| _oldRateLimiter `indexed` | address | undefined |
| _newRateLimiter `indexed` | address | undefined |
### WithdrawERC20
```solidity

View File

@@ -318,6 +318,53 @@ describe("L1MessageQueue", async () => {
expect(await queue.isMessageDropped(i)).to.eq(false);
}
});
// @note skip this random benchmark tests
for (const count1 of [1, 2, 128, 129, 256]) {
for (const count2 of [1, 2, 128, 129, 256]) {
for (const count3 of [1, 2, 128, 129, 256]) {
it.skip(`should succeed on random tests, pop three times each with ${count1} ${count2} ${count3} msgs`, async () => {
// append count1 + count2 + count3 messages
for (let i = 0; i < count1 + count2 + count3; i++) {
await queue.connect(messenger).appendCrossDomainMessage(constants.AddressZero, 1000000, "0x");
}
// first pop `count1` messages
const bitmap1 = BigNumber.from(randomBytes(32));
let tx = await queue.connect(scrollChain).popCrossDomainMessage(0, count1, bitmap1);
await expect(tx)
.to.emit(queue, "DequeueTransaction")
.withArgs(0, count1, bitmap1.and(constants.One.shl(count1).sub(1)));
for (let i = 0; i < count1; i++) {
expect(await queue.isMessageSkipped(i)).to.eq(bitmap1.shr(i).and(1).eq(1));
expect(await queue.isMessageDropped(i)).to.eq(false);
}
// then pop `count2` messages
const bitmap2 = BigNumber.from(randomBytes(32));
tx = await queue.connect(scrollChain).popCrossDomainMessage(count1, count2, bitmap2);
await expect(tx)
.to.emit(queue, "DequeueTransaction")
.withArgs(count1, count2, bitmap2.and(constants.One.shl(count2).sub(1)));
for (let i = 0; i < count2; i++) {
expect(await queue.isMessageSkipped(i + count1)).to.eq(bitmap2.shr(i).and(1).eq(1));
expect(await queue.isMessageDropped(i + count1)).to.eq(false);
}
// last pop `count3` messages
const bitmap3 = BigNumber.from(randomBytes(32));
tx = await queue.connect(scrollChain).popCrossDomainMessage(count1 + count2, count3, bitmap3);
await expect(tx)
.to.emit(queue, "DequeueTransaction")
.withArgs(count1 + count2, count3, bitmap3.and(constants.One.shl(count3).sub(1)));
for (let i = 0; i < count3; i++) {
expect(await queue.isMessageSkipped(i + count1 + count2)).to.eq(bitmap3.shr(i).and(1).eq(1));
expect(await queue.isMessageDropped(i + count1 + count2)).to.eq(false);
}
});
}
}
}
});
context("#dropCrossDomainMessage", async () => {

View File

@@ -17,7 +17,6 @@ import {L1MessageQueue} from "../../src/L1/rollup/L1MessageQueue.sol";
import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol";
import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol";
import {L1DAIGateway} from "../../src/L1/gateways/L1DAIGateway.sol";
import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol";
import {MultipleVersionRollupVerifier} from "../../src/L1/rollup/MultipleVersionRollupVerifier.sol";
import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol";
@@ -27,7 +26,7 @@ import {ZkEvmVerifierV1} from "../../src/libraries/verifier/ZkEvmVerifierV1.sol"
contract DeployL1BridgeContracts is Script {
uint256 L1_DEPLOYER_PRIVATE_KEY = vm.envUint("L1_DEPLOYER_PRIVATE_KEY");
uint32 CHAIN_ID_L2 = uint32(vm.envUint("CHAIN_ID_L2"));
uint64 CHAIN_ID_L2 = uint64(vm.envUint("CHAIN_ID_L2"));
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
@@ -56,7 +55,6 @@ contract DeployL1BridgeContracts is Script {
deployL1CustomERC20Gateway();
deployL1ERC721Gateway();
deployL1ERC1155Gateway();
deployL1DAIGateway();
vm.stopBroadcast();
}
@@ -204,18 +202,6 @@ contract DeployL1BridgeContracts is Script {
logAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1DAIGateway() internal {
L1DAIGateway impl = new L1DAIGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L1_DAI_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L1_DAI_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL1ERC721Gateway() internal {
L1ERC721Gateway impl = new L1ERC721Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(

View File

@@ -15,7 +15,6 @@ import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol";
import {L2ScrollMessenger} from "../../src/L2/L2ScrollMessenger.sol";
import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol";
import {L2DAIGateway} from "../../src/L2/gateways/L2DAIGateway.sol";
import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol";
import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol";
import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol";
@@ -60,7 +59,6 @@ contract DeployL2BridgeContracts is Script {
deployL2CustomERC20Gateway();
deployL2ERC721Gateway();
deployL2ERC1155Gateway();
deployL2DAIGateway();
vm.stopBroadcast();
}
@@ -201,18 +199,6 @@ contract DeployL2BridgeContracts is Script {
logAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2DAIGateway() internal {
L2DAIGateway impl = new L2DAIGateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),
new bytes(0)
);
logAddress("L2_DAI_GATEWAY_IMPLEMENTATION_ADDR", address(impl));
logAddress("L2_DAI_GATEWAY_PROXY_ADDR", address(proxy));
}
function deployL2ERC721Gateway() internal {
L2ERC721Gateway impl = new L2ERC721Gateway();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(

View File

@@ -1,49 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import {ScrollGatewayBase} from "../../src/libraries/gateway/ScrollGatewayBase.sol";
import {ScrollMessengerBase} from "../../src/libraries/ScrollMessengerBase.sol";
import {ETHRateLimiter} from "../../src/rate-limiter/ETHRateLimiter.sol";
import {TokenRateLimiter} from "../../src/rate-limiter/TokenRateLimiter.sol";
contract DeployL2RateLimiter is Script {
uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
uint256 RATE_LIMITER_PERIOD_LENGTH = vm.envUint("RATE_LIMITER_PERIOD_LENGTH");
uint104 ETH_TOTAL_LIMIT = uint104(vm.envUint("ETH_TOTAL_LIMIT"));
function run() external {
vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY);
deployETHRateLimiter();
deployTokenRateLimiter();
vm.stopBroadcast();
}
function deployETHRateLimiter() internal {
ETHRateLimiter limiter = new ETHRateLimiter(
RATE_LIMITER_PERIOD_LENGTH,
L2_SCROLL_MESSENGER_PROXY_ADDR,
ETH_TOTAL_LIMIT
);
logAddress("L2_ETH_RATE_LIMITER_ADDR", address(limiter));
}
function deployTokenRateLimiter() internal {
TokenRateLimiter limiter = new TokenRateLimiter(RATE_LIMITER_PERIOD_LENGTH);
logAddress("L2_TOKEN_RATE_LIMITER_ADDR", address(limiter));
}
function logAddress(string memory name, address addr) internal view {
console.log(string(abi.encodePacked(name, "=", vm.toString(address(addr)))));
}
}

View File

@@ -11,7 +11,6 @@ import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol";
import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol";
import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol";
import {L1DAIGateway} from "../../src/L1/gateways/L1DAIGateway.sol";
import {MultipleVersionRollupVerifier} from "../../src/L1/rollup/MultipleVersionRollupVerifier.sol";
import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol";
import {L1MessageQueue} from "../../src/L1/rollup/L1MessageQueue.sol";
@@ -29,9 +28,6 @@ contract InitializeL1BridgeContracts is Script {
address L1_FEE_VAULT_ADDR = vm.envAddress("L1_FEE_VAULT_ADDR");
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L1_DAI_ADDR = vm.envAddress("L1_DAI_ADDR");
address L2_DAI_ADDR = vm.envAddress("L2_DAI_ADDR");
address L1_WHITELIST_ADDR = vm.envAddress("L1_WHITELIST_ADDR");
address L1_SCROLL_CHAIN_PROXY_ADDR = vm.envAddress("L1_SCROLL_CHAIN_PROXY_ADDR");
address L1_MESSAGE_QUEUE_PROXY_ADDR = vm.envAddress("L1_MESSAGE_QUEUE_PROXY_ADDR");
@@ -44,7 +40,6 @@ contract InitializeL1BridgeContracts is Script {
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address L1_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L1_DAI_GATEWAY_PROXY_ADDR");
address L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR = vm.envAddress("L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR");
address L1_ENFORCED_TX_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ENFORCED_TX_GATEWAY_PROXY_ADDR");
@@ -56,7 +51,6 @@ contract InitializeL1BridgeContracts is Script {
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L2_DAI_GATEWAY_PROXY_ADDR");
address L2_SCROLL_STANDARD_ERC20_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_ADDR");
address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR");
@@ -155,22 +149,12 @@ contract InitializeL1BridgeContracts is Script {
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1DAIGateway
L1DAIGateway(L1_DAI_GATEWAY_PROXY_ADDR).initialize(
L2_DAI_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
L1DAIGateway(L1_DAI_GATEWAY_PROXY_ADDR).updateTokenMapping(L1_DAI_ADDR, L2_DAI_ADDR);
// set WETH and DAI gateways in router
// set WETH gateway in router
{
address[] memory _tokens = new address[](2);
address[] memory _tokens = new address[](1);
_tokens[0] = L1_WETH_ADDR;
_tokens[1] = L1_DAI_ADDR;
address[] memory _gateways = new address[](2);
address[] memory _gateways = new address[](1);
_gateways[0] = L1_WETH_GATEWAY_PROXY_ADDR;
_gateways[1] = L1_DAI_GATEWAY_PROXY_ADDR;
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways);
}

View File

@@ -30,12 +30,14 @@ contract InitializeL1ScrollOwner is Script {
bytes32 constant SECURITY_COUNCIL_NO_DELAY_ROLE = keccak256("SECURITY_COUNCIL_NO_DELAY_ROLE");
bytes32 constant SCROLL_MULTISIG_NO_DELAY_ROLE = keccak256("SCROLL_MULTISIG_NO_DELAY_ROLE");
bytes32 constant EMERGENCY_MULTISIG_NO_DELAY_ROLE = keccak256("EMERGENCY_MULTISIG_NO_DELAY_ROLE");
bytes32 constant TIMELOCK_1DAY_DELAY_ROLE = keccak256("TIMELOCK_1DAY_DELAY_ROLE");
bytes32 constant TIMELOCK_7DAY_DELAY_ROLE = keccak256("TIMELOCK_7DAY_DELAY_ROLE");
address SCROLL_MULTISIG_ADDR = vm.envAddress("L1_SCROLL_MULTISIG_ADDR");
address SECURITY_COUNCIL_ADDR = vm.envAddress("L1_SECURITY_COUNCIL_ADDR");
address EMERGENCY_MULTISIG_ADDR = vm.envAddress("L1_EMERGENCY_MULTISIG_ADDR");
address L1_SCROLL_OWNER_ADDR = vm.envAddress("L1_SCROLL_OWNER_ADDR");
address L1_1D_TIMELOCK_ADDR = vm.envAddress("L1_1D_TIMELOCK_ADDR");
@@ -49,14 +51,16 @@ contract InitializeL1ScrollOwner is Script {
address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR");
address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR");
address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L1_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L1_DAI_GATEWAY_PROXY_ADDR");
address L1_LIDO_GATEWAY_PROXY_ADDR = vm.envAddress("L1_LIDO_GATEWAY_PROXY_ADDR");
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
// address L1_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L1_USDC_GATEWAY_PROXY_ADDR");
address L1_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L1_USDC_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address L1_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC721_GATEWAY_PROXY_ADDR");
address L1_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ERC1155_GATEWAY_PROXY_ADDR");
address L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR = vm.envAddress("L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR");
// address L1_ENFORCED_TX_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ENFORCED_TX_GATEWAY_PROXY_ADDR");
address L1_ENFORCED_TX_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ENFORCED_TX_GATEWAY_PROXY_ADDR");
address L1_WHITELIST_ADDR = vm.envAddress("L1_WHITELIST_ADDR");
ScrollOwner owner;
@@ -79,9 +83,8 @@ contract InitializeL1ScrollOwner is Script {
configL1ERC721Gateway();
configL1ERC1155Gateway();
// @note comments out for testnet
// configEnforcedTxGateway();
// configL1USDCGateway();
configL1USDCGateway();
configEnforcedTxGateway();
grantRoles();
transferOwnership();
@@ -94,15 +97,17 @@ contract InitializeL1ScrollOwner is Script {
Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(address(owner));
// Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_WHITELIST_ADDR).transferOwnership(address(owner));
Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).transferOwnership(address(owner));
Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_DAI_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_LIDO_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_ETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
// Ownable(L1_USDC_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_USDC_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_WETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
@@ -111,6 +116,7 @@ contract InitializeL1ScrollOwner is Script {
function grantRoles() internal {
owner.grantRole(SECURITY_COUNCIL_NO_DELAY_ROLE, SECURITY_COUNCIL_ADDR);
owner.grantRole(SCROLL_MULTISIG_NO_DELAY_ROLE, SCROLL_MULTISIG_ADDR);
owner.grantRole(EMERGENCY_MULTISIG_NO_DELAY_ROLE, EMERGENCY_MULTISIG_ADDR);
owner.grantRole(TIMELOCK_1DAY_DELAY_ROLE, L1_1D_TIMELOCK_ADDR);
owner.grantRole(TIMELOCK_7DAY_DELAY_ROLE, L1_7D_TIMELOCK_ADDR);
@@ -131,20 +137,25 @@ contract InitializeL1ScrollOwner is Script {
function configScrollChain() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
_selectors = new bytes4[](5);
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](4);
_selectors[0] = ScrollChain.revertBatch.selector;
_selectors[1] = ScrollChain.removeSequencer.selector;
_selectors[2] = ScrollChain.removeProver.selector;
_selectors[3] = ScrollChain.updateMaxNumTxInChunk.selector;
_selectors[4] = ScrollChain.setPause.selector;
_selectors[3] = ScrollChain.setPause.selector;
owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
// delay 1 day, scroll multisig
_selectors = new bytes4[](2);
_selectors[0] = ScrollChain.addSequencer.selector;
_selectors[1] = ScrollChain.addProver.selector;
owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true);
// delay 7 day, scroll multisig
_selectors = new bytes4[](1);
_selectors[0] = ScrollChain.updateMaxNumTxInChunk.selector;
owner.updateAccess(L1_SCROLL_CHAIN_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true);
}
function configL1MessageQueue() internal {
@@ -160,10 +171,11 @@ contract InitializeL1ScrollOwner is Script {
function configL1ScrollMessenger() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](1);
_selectors[0] = ScrollMessengerBase.setPause.selector;
owner.updateAccess(L1_SCROLL_MESSENGER_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L1_SCROLL_MESSENGER_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
// delay 1 day, scroll multisig
_selectors = new bytes4[](1);
@@ -174,10 +186,11 @@ contract InitializeL1ScrollOwner is Script {
function configL2GasPriceOracle() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](1);
_selectors[0] = L2GasPriceOracle.setIntrinsicParams.selector;
owner.updateAccess(L2_GAS_PRICE_ORACLE_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L2_GAS_PRICE_ORACLE_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
}
function configL1Whitelist() internal {
@@ -239,7 +252,6 @@ contract InitializeL1ScrollOwner is Script {
owner.updateAccess(L1_ERC1155_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true);
}
/*
function configL1USDCGateway() internal {
bytes4[] memory _selectors;
@@ -254,10 +266,10 @@ contract InitializeL1ScrollOwner is Script {
function configEnforcedTxGateway() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](1);
_selectors[0] = EnforcedTxGateway.setPause.selector;
owner.updateAccess(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
}
*/
}

View File

@@ -11,7 +11,6 @@ import {L2ETHGateway} from "../../src/L2/gateways/L2ETHGateway.sol";
import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol";
import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol";
import {L2DAIGateway} from "../../src/L2/gateways/L2DAIGateway.sol";
import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol";
import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol";
import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol";
@@ -23,9 +22,6 @@ contract InitializeL2BridgeContracts is Script {
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
address L1_DAI_ADDR = vm.envAddress("L1_DAI_ADDR");
address L2_DAI_ADDR = vm.envAddress("L2_DAI_ADDR");
address L1_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L1_SCROLL_MESSENGER_PROXY_ADDR");
address L1_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L1_GATEWAY_ROUTER_PROXY_ADDR");
address L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
@@ -34,7 +30,6 @@ contract InitializeL2BridgeContracts is Script {
address L1_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_ETH_GATEWAY_PROXY_ADDR");
address L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L1_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L1_WETH_GATEWAY_PROXY_ADDR");
address L1_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L1_DAI_GATEWAY_PROXY_ADDR");
address L2_TX_FEE_VAULT_ADDR = vm.envAddress("L2_TX_FEE_VAULT_ADDR");
address L1_GAS_PRICE_ORACLE_ADDR = vm.envAddress("L1_GAS_PRICE_ORACLE_ADDR");
@@ -49,7 +44,6 @@ contract InitializeL2BridgeContracts is Script {
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L2_DAI_GATEWAY_PROXY_ADDR");
address L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR = vm.envAddress("L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR");
function run() external {
@@ -114,22 +108,12 @@ contract InitializeL2BridgeContracts is Script {
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2DAIGateway
L2DAIGateway(L2_DAI_GATEWAY_PROXY_ADDR).initialize(
L1_DAI_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
L2DAIGateway(L2_DAI_GATEWAY_PROXY_ADDR).updateTokenMapping(L2_DAI_ADDR, L1_DAI_ADDR);
// set WETH and DAI gateways in router
// set WETH gateway in router
{
address[] memory _tokens = new address[](2);
address[] memory _tokens = new address[](1);
_tokens[0] = L2_WETH_ADDR;
_tokens[1] = L2_DAI_ADDR;
address[] memory _gateways = new address[](2);
address[] memory _gateways = new address[](1);
_gateways[0] = L2_WETH_GATEWAY_PROXY_ADDR;
_gateways[1] = L2_DAI_GATEWAY_PROXY_ADDR;
L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways);
}

View File

@@ -1,55 +0,0 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import {Script} from "forge-std/Script.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {AccessControlEnumerable} from "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {ScrollMessengerBase} from "../../src/libraries/ScrollMessengerBase.sol";
import {ScrollGatewayBase} from "../../src/libraries/gateway/ScrollGatewayBase.sol";
import {ETHRateLimiter} from "../../src/rate-limiter/ETHRateLimiter.sol";
import {TokenRateLimiter} from "../../src/rate-limiter/TokenRateLimiter.sol";
// solhint-disable max-states-count
// solhint-disable state-visibility
// solhint-disable var-name-mixedcase
contract InitializeL2RateLimiter is Script {
uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
address L2_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L2_DAI_GATEWAY_PROXY_ADDR");
// address L2_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L2_USDC_GATEWAY_PROXY_ADDR");
address L2_ETH_RATE_LIMITER_ADDR = vm.envAddress("L2_ETH_RATE_LIMITER_ADDR");
address L2_TOKEN_RATE_LIMITER_ADDR = vm.envAddress("L2_TOKEN_RATE_LIMITER_ADDR");
function run() external {
vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY);
ScrollMessengerBase(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).updateRateLimiter(L2_ETH_RATE_LIMITER_ADDR);
bytes32 TOKEN_SPENDER_ROLE = TokenRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR).TOKEN_SPENDER_ROLE();
TokenRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR).grantRole(TOKEN_SPENDER_ROLE, L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR);
TokenRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR).grantRole(
TOKEN_SPENDER_ROLE,
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR
);
TokenRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR).grantRole(TOKEN_SPENDER_ROLE, L2_DAI_GATEWAY_PROXY_ADDR);
ScrollGatewayBase(payable(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR)).updateRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR);
ScrollGatewayBase(payable(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR)).updateRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR);
ScrollGatewayBase(payable(L2_DAI_GATEWAY_PROXY_ADDR)).updateRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR);
// @note comments out for now
// limiter.grantRole(TOKEN_SPENDER_ROLE, L2_USDC_GATEWAY_PROXY_ADDR);
// ScrollGatewayBase(payable(L2_USDC_GATEWAY_PROXY_ADDR)).updateRateLimiter(address(limiter));
vm.stopBroadcast();
}
}

View File

@@ -19,8 +19,6 @@ import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol";
import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol";
import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol";
import {ScrollOwner} from "../../src/misc/ScrollOwner.sol";
import {ETHRateLimiter} from "../../src/rate-limiter/ETHRateLimiter.sol";
import {TokenRateLimiter} from "../../src/rate-limiter/TokenRateLimiter.sol";
// solhint-disable max-states-count
// solhint-disable state-visibility
@@ -31,12 +29,14 @@ contract InitializeL2ScrollOwner is Script {
bytes32 constant SECURITY_COUNCIL_NO_DELAY_ROLE = keccak256("SECURITY_COUNCIL_NO_DELAY_ROLE");
bytes32 constant SCROLL_MULTISIG_NO_DELAY_ROLE = keccak256("SCROLL_MULTISIG_NO_DELAY_ROLE");
bytes32 constant EMERGENCY_MULTISIG_NO_DELAY_ROLE = keccak256("EMERGENCY_MULTISIG_NO_DELAY_ROLE");
bytes32 constant TIMELOCK_1DAY_DELAY_ROLE = keccak256("TIMELOCK_1DAY_DELAY_ROLE");
bytes32 constant TIMELOCK_7DAY_DELAY_ROLE = keccak256("TIMELOCK_7DAY_DELAY_ROLE");
address SCROLL_MULTISIG_ADDR = vm.envAddress("L2_SCROLL_MULTISIG_ADDR");
address SECURITY_COUNCIL_ADDR = vm.envAddress("L2_SECURITY_COUNCIL_ADDR");
address EMERGENCY_MULTISIG_ADDR = vm.envAddress("L2_EMERGENCY_MULTISIG_ADDR");
address L2_SCROLL_OWNER_ADDR = vm.envAddress("L2_SCROLL_OWNER_ADDR");
address L2_1D_TIMELOCK_ADDR = vm.envAddress("L2_1D_TIMELOCK_ADDR");
@@ -52,15 +52,17 @@ contract InitializeL2ScrollOwner is Script {
address L2_SCROLL_MESSENGER_PROXY_ADDR = vm.envAddress("L2_SCROLL_MESSENGER_PROXY_ADDR");
address L2_GATEWAY_ROUTER_PROXY_ADDR = vm.envAddress("L2_GATEWAY_ROUTER_PROXY_ADDR");
address L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR");
address L2_DAI_GATEWAY_PROXY_ADDR = vm.envAddress("L2_DAI_GATEWAY_PROXY_ADDR");
address L2_LIDO_GATEWAY_PROXY_ADDR = vm.envAddress("L2_LIDO_GATEWAY_PROXY_ADDR");
address L2_ETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ETH_GATEWAY_PROXY_ADDR");
address L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR = vm.envAddress("L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR");
// address L2_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L2_USDC_GATEWAY_PROXY_ADDR");
address L2_USDC_GATEWAY_PROXY_ADDR = vm.envAddress("L2_USDC_GATEWAY_PROXY_ADDR");
address L2_WETH_GATEWAY_PROXY_ADDR = vm.envAddress("L2_WETH_GATEWAY_PROXY_ADDR");
address L2_ERC721_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC721_GATEWAY_PROXY_ADDR");
address L2_ERC1155_GATEWAY_PROXY_ADDR = vm.envAddress("L2_ERC1155_GATEWAY_PROXY_ADDR");
address L2_ETH_RATE_LIMITER_ADDR = vm.envAddress("L2_ETH_RATE_LIMITER_ADDR");
address L2_TOKEN_RATE_LIMITER_ADDR = vm.envAddress("L2_TOKEN_RATE_LIMITER_ADDR");
address L2_USDC_PROXY_ADDR = vm.envAddress("L2_USDC_PROXY_ADDR");
address L2_USDC_MASTER_MINTER_ADDR = vm.envAddress("L2_USDC_MASTER_MINTER_ADDR");
ScrollOwner owner;
@@ -79,11 +81,8 @@ contract InitializeL2ScrollOwner is Script {
configL2CustomERC20Gateway();
configL2ERC721Gateway();
configL2ERC1155Gateway();
configETHRateLimiter();
configTokenRateLimiter();
// @note comments out for testnet
// configL2USDCGateway();
configL2USDCGateway();
grantRoles();
transferOwnership();
@@ -100,24 +99,23 @@ contract InitializeL2ScrollOwner is Script {
Ownable(L2_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_DAI_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_LIDO_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_ETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_WETH_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
// Ownable(L2_USDC_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_ETH_RATE_LIMITER_ADDR).transferOwnership(address(owner));
TokenRateLimiter tokenRateLimiter = TokenRateLimiter(L2_TOKEN_RATE_LIMITER_ADDR);
tokenRateLimiter.grantRole(tokenRateLimiter.DEFAULT_ADMIN_ROLE(), address(owner));
tokenRateLimiter.revokeRole(tokenRateLimiter.DEFAULT_ADMIN_ROLE(), vm.addr(L2_DEPLOYER_PRIVATE_KEY));
Ownable(L2_USDC_GATEWAY_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_USDC_PROXY_ADDR).transferOwnership(address(owner));
Ownable(L2_USDC_MASTER_MINTER_ADDR).transferOwnership(address(owner));
}
function grantRoles() internal {
owner.grantRole(SECURITY_COUNCIL_NO_DELAY_ROLE, SECURITY_COUNCIL_ADDR);
owner.grantRole(SCROLL_MULTISIG_NO_DELAY_ROLE, SCROLL_MULTISIG_ADDR);
owner.grantRole(EMERGENCY_MULTISIG_NO_DELAY_ROLE, EMERGENCY_MULTISIG_ADDR);
owner.grantRole(TIMELOCK_1DAY_DELAY_ROLE, L2_1D_TIMELOCK_ADDR);
owner.grantRole(TIMELOCK_7DAY_DELAY_ROLE, L2_7D_TIMELOCK_ADDR);
@@ -138,20 +136,22 @@ contract InitializeL2ScrollOwner is Script {
function configL1GasPriceOracle() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](2);
_selectors[0] = L1GasPriceOracle.setOverhead.selector;
_selectors[1] = L1GasPriceOracle.setScalar.selector;
owner.updateAccess(L1_GAS_PRICE_ORACLE_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L1_GAS_PRICE_ORACLE_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
}
function configL2TxFeeVault() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](1);
_selectors[0] = L2TxFeeVault.updateMinWithdrawAmount.selector;
owner.updateAccess(L2_TX_FEE_VAULT_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L2_TX_FEE_VAULT_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
}
function configL2Whitelist() internal {
@@ -166,10 +166,11 @@ contract InitializeL2ScrollOwner is Script {
function configL2ScrollMessenger() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
// no delay, scroll multisig and emergency multisig
_selectors = new bytes4[](1);
_selectors[0] = ScrollMessengerBase.setPause.selector;
owner.updateAccess(L2_SCROLL_MESSENGER_PROXY_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
owner.updateAccess(L2_SCROLL_MESSENGER_PROXY_ADDR, _selectors, EMERGENCY_MULTISIG_NO_DELAY_ROLE, true);
}
function configL2GatewayRouter() internal {
@@ -208,31 +209,6 @@ contract InitializeL2ScrollOwner is Script {
owner.updateAccess(L2_ERC1155_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_1DAY_DELAY_ROLE, true);
}
function configETHRateLimiter() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
_selectors = new bytes4[](1);
_selectors[0] = ETHRateLimiter.updateTotalLimit.selector;
owner.updateAccess(L2_ETH_RATE_LIMITER_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
}
function configTokenRateLimiter() internal {
bytes4[] memory _selectors;
// no delay, scroll multisig
_selectors = new bytes4[](2);
_selectors[0] = TokenRateLimiter.updateTotalLimit.selector;
_selectors[1] = AccessControl.grantRole.selector;
owner.updateAccess(L2_TOKEN_RATE_LIMITER_ADDR, _selectors, SCROLL_MULTISIG_NO_DELAY_ROLE, true);
// delay 7 day, scroll multisig
_selectors = new bytes4[](1);
_selectors[0] = AccessControl.revokeRole.selector;
owner.updateAccess(L2_TOKEN_RATE_LIMITER_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true);
}
/*
function configL2USDCGateway() internal {
bytes4[] memory _selectors;
@@ -242,6 +218,11 @@ contract InitializeL2ScrollOwner is Script {
_selectors[1] = L2USDCGateway.pauseDeposit.selector;
_selectors[2] = L2USDCGateway.pauseWithdraw.selector;
owner.updateAccess(L2_USDC_GATEWAY_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true);
// delay 7 day, scroll multisig
_selectors = new bytes4[](1);
_selectors[0] = Ownable.transferOwnership.selector;
owner.updateAccess(L2_USDC_PROXY_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true);
owner.updateAccess(L2_USDC_MASTER_MINTER_ADDR, _selectors, TIMELOCK_7DAY_DELAY_ROLE, true);
}
*/
}

View File

@@ -115,7 +115,7 @@ contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger {
bytes memory _message,
uint256 _gasLimit
) external payable override whenNotPaused {
_sendMessage(_to, _value, _message, _gasLimit, msg.sender);
_sendMessage(_to, _value, _message, _gasLimit, _msgSender());
}
/// @inheritdoc IScrollMessenger
@@ -316,14 +316,12 @@ contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger {
uint256 _gasLimit,
address _refundAddress
) internal nonReentrant {
_addUsedAmount(_value);
address _messageQueue = messageQueue; // gas saving
address _counterpart = counterpart; // gas saving
// compute the actual cross domain message calldata.
uint256 _messageNonce = IL1MessageQueue(_messageQueue).nextCrossDomainMessageIndex();
bytes memory _xDomainCalldata = _encodeXDomainCalldata(msg.sender, _to, _value, _messageNonce, _message);
bytes memory _xDomainCalldata = _encodeXDomainCalldata(_msgSender(), _to, _value, _messageNonce, _message);
// compute and deduct the messaging fee to fee vault.
uint256 _fee = IL1MessageQueue(_messageQueue).estimateCrossDomainMessageFee(_gasLimit);
@@ -343,7 +341,7 @@ contract L1ScrollMessenger is ScrollMessengerBase, IL1ScrollMessenger {
require(messageSendTimestamp[_xDomainCalldataHash] == 0, "Duplicated message");
messageSendTimestamp[_xDomainCalldataHash] = block.timestamp;
emit SentMessage(msg.sender, _to, _value, _messageNonce, _gasLimit, _message);
emit SentMessage(_msgSender(), _to, _value, _messageNonce, _gasLimit, _message);
// refund fee to `_refundAddress`
unchecked {

134
contracts/src/L1/ecc.sol Normal file
View File

@@ -0,0 +1,134 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Ecc {
/* ECC Functions */
// https://etherscan.io/address/0x41bf00f080ed41fa86201eac56b8afb170d9e36d#code
function ecAdd(uint256[2] memory p0, uint256[2] memory p1) public view
returns (uint256[2] memory retP)
{
uint256[4] memory i = [p0[0], p0[1], p1[0], p1[1]];
assembly {
// call ecadd precompile
// inputs are: x1, y1, x2, y2
if iszero(staticcall(not(0), 0x06, i, 0x80, retP, 0x40)) {
revert(0, 0)
}
}
}
// https://etherscan.io/address/0x41bf00f080ed41fa86201eac56b8afb170d9e36d#code
function ecMul(uint256[2] memory p, uint256 s) public view
returns (uint256[2] memory retP)
{
// With a public key (x, y), this computes p = scalar * (x, y).
uint256[3] memory i = [p[0], p[1], s];
assembly {
// call ecmul precompile
// inputs are: x, y, scalar
if iszero(staticcall(not(0), 0x07, i, 0x60, retP, 0x40)) {
revert(0, 0)
}
}
}
// scroll-tech/scroll/contracts/src/libraries/verifier/RollupVerifier.sol
struct G1Point {
uint256 x;
uint256 y;
}
struct G2Point {
uint256[2] x;
uint256[2] y;
}
function ecPairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {
uint256 length = p1.length * 6;
uint256[] memory input = new uint256[](length);
uint256[1] memory result;
bool ret;
require(p1.length == p2.length);
for (uint256 i = 0; i < p1.length; i++) {
input[0 + i * 6] = p1[i].x;
input[1 + i * 6] = p1[i].y;
input[2 + i * 6] = p2[i].x[0];
input[3 + i * 6] = p2[i].x[1];
input[4 + i * 6] = p2[i].y[0];
input[5 + i * 6] = p2[i].y[1];
}
assembly {
ret := staticcall(gas(), 8, add(input, 0x20), mul(length, 0x20), result, 0x20)
}
require(ret);
return result[0] != 0;
}
/* Bench */
function ecAdds(uint256 n) public
{
uint256[2] memory p0;
p0[0] = 1;
p0[1] = 2;
uint256[2] memory p1;
p1[0] = 1;
p1[1] = 2;
for (uint i = 0; i < n; i++) {
ecAdd(p0, p1);
}
}
function ecMuls(uint256 n) public
{
uint256[2] memory p0;
p0[0] = 1;
p0[1] = 2;
for (uint i = 0; i < n; i++) {
ecMul(p0, 3);
}
}
function ecPairings(uint256 n) public
{
G1Point[] memory g1_points = new G1Point[](2);
G2Point[] memory g2_points = new G2Point[](2);
g1_points[0].x = 0x0000000000000000000000000000000000000000000000000000000000000001;
g1_points[0].y = 0x0000000000000000000000000000000000000000000000000000000000000002;
g2_points[0].x[1] = 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed;
g2_points[0].x[0] = 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2;
g2_points[0].y[1] = 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa;
g2_points[0].y[0] = 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b;
g1_points[1].x = 0x1aa125a22bd902874034e67868aed40267e5575d5919677987e3bc6dd42a32fe;
g1_points[1].y = 0x1bacc186725464068956d9a191455c2d6f6db282d83645c610510d8d4efbaee0;
g2_points[1].x[1] = 0x1b7734c80605f71f1e2de61e998ce5854ff2abebb76537c3d67e50d71422a852;
g2_points[1].x[0] = 0x10d5a1e34b2388a5ebe266033a5e0e63c89084203784da0c6bd9b052a78a2cac;
g2_points[1].y[1] = 0x275739c5c2cdbc72e37c689e2ab441ea76c1d284b9c46ae8f5c42ead937819e1;
g2_points[1].y[0] = 0x018de34c5b7c3d3d75428bbe050f1449ea3d9961d563291f307a1874f7332e65;
for (uint i = 0; i < n; i++) {
ecPairing(g1_points, g2_points);
// bool checked = false;
// checked = ecPairing(g1_points, g2_points);
// require(checked);
}
}
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/8a0b7bed82d6b8053872c3fd40703efd58f5699d/test/utils/cryptography/ECDSA.test.js#L230
function ecRecovers(uint256 n) public
{
bytes32 hash = 0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9;
bytes32 r = 0xe742ff452d41413616a5bf43fe15dd88294e983d3d36206c2712f39083d638bd;
uint8 v = 0x1b;
bytes32 s = 0xe0a0fc89be718fbc1033e1d30d78be1c68081562ed2e97af876f286f3453231d;
for (uint i = 0; i < n; i++) {
ecrecover(hash, v, r, s);
}
}
}

View File

@@ -66,7 +66,7 @@ contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC
uint256 _amount,
uint256 _gasLimit
) external payable override {
_depositERC1155(_token, msg.sender, _tokenId, _amount, _gasLimit);
_depositERC1155(_token, _msgSender(), _tokenId, _amount, _gasLimit);
}
/// @inheritdoc IL1ERC1155Gateway
@@ -87,7 +87,7 @@ contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC
uint256[] calldata _amounts,
uint256 _gasLimit
) external payable override {
_batchDepositERC1155(_token, msg.sender, _tokenIds, _amounts, _gasLimit);
_batchDepositERC1155(_token, _msgSender(), _tokenIds, _amounts, _gasLimit);
}
/// @inheritdoc IL1ERC1155Gateway
@@ -198,19 +198,21 @@ contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "no corresponding l2 token");
address _sender = _msgSender();
// 1. transfer token to this contract
IERC1155Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _tokenId, _amount, "");
IERC1155Upgradeable(_token).safeTransferFrom(_sender, address(this), _tokenId, _amount, "");
// 2. Generate message passed to L2ERC1155Gateway.
bytes memory _message = abi.encodeCall(
IL2ERC1155Gateway.finalizeDepositERC1155,
(_token, _l2Token, msg.sender, _to, _tokenId, _amount)
(_token, _l2Token, _sender, _to, _tokenId, _amount)
);
// 3. Send message to L1ScrollMessenger.
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, msg.sender);
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender);
emit DepositERC1155(_token, _l2Token, msg.sender, _to, _tokenId, _amount);
emit DepositERC1155(_token, _l2Token, _sender, _to, _tokenId, _amount);
}
/// @dev Internal function to batch deposit ERC1155 NFT to layer 2.
@@ -236,18 +238,20 @@ contract L1ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL1ERC
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "no corresponding l2 token");
address _sender = _msgSender();
// 1. transfer token to this contract
IERC1155Upgradeable(_token).safeBatchTransferFrom(msg.sender, address(this), _tokenIds, _amounts, "");
IERC1155Upgradeable(_token).safeBatchTransferFrom(_sender, address(this), _tokenIds, _amounts, "");
// 2. Generate message passed to L2ERC1155Gateway.
bytes memory _message = abi.encodeCall(
IL2ERC1155Gateway.finalizeBatchDepositERC1155,
(_token, _l2Token, msg.sender, _to, _tokenIds, _amounts)
(_token, _l2Token, _sender, _to, _tokenIds, _amounts)
);
// 3. Send message to L1ScrollMessenger.
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, msg.sender);
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender);
emit BatchDepositERC1155(_token, _l2Token, msg.sender, _to, _tokenIds, _amounts);
emit BatchDepositERC1155(_token, _l2Token, _sender, _to, _tokenIds, _amounts);
}
}

View File

@@ -35,7 +35,7 @@ abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, Scrol
uint256 _amount,
uint256 _gasLimit
) external payable override {
_deposit(_token, msg.sender, _amount, new bytes(0), _gasLimit);
_deposit(_token, _msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL1ERC20Gateway
@@ -144,11 +144,12 @@ abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, Scrol
bytes memory
)
{
address _from = msg.sender;
if (router == msg.sender) {
address _sender = _msgSender();
address _from = _sender;
if (router == _sender) {
// Extract real sender if this call is from L1GatewayRouter.
(_from, _data) = abi.decode(_data, (address, bytes));
_amount = IL1GatewayRouter(msg.sender).requestERC20(_from, _token, _amount);
_amount = IL1GatewayRouter(_sender).requestERC20(_from, _token, _amount);
} else {
// common practice to handle fee on transfer token.
uint256 _before = IERC20Upgradeable(_token).balanceOf(address(this));
@@ -160,9 +161,6 @@ abstract contract L1ERC20Gateway is IL1ERC20Gateway, IMessageDropCallback, Scrol
// ignore weird fee on transfer token
require(_amount > 0, "deposit zero amount");
// rate limit
_addUsedAmount(_token, _amount);
return (_from, _amount, _data);
}

View File

@@ -64,7 +64,7 @@ contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC72
uint256 _tokenId,
uint256 _gasLimit
) external payable override {
_depositERC721(_token, msg.sender, _tokenId, _gasLimit);
_depositERC721(_token, _msgSender(), _tokenId, _gasLimit);
}
/// @inheritdoc IL1ERC721Gateway
@@ -83,7 +83,7 @@ contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC72
uint256[] calldata _tokenIds,
uint256 _gasLimit
) external payable override {
_batchDepositERC721(_token, msg.sender, _tokenIds, _gasLimit);
_batchDepositERC721(_token, _msgSender(), _tokenIds, _gasLimit);
}
/// @inheritdoc IL1ERC721Gateway
@@ -190,19 +190,21 @@ contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC72
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "no corresponding l2 token");
address _sender = _msgSender();
// 1. transfer token to this contract
IERC721Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _tokenId);
IERC721Upgradeable(_token).safeTransferFrom(_sender, address(this), _tokenId);
// 2. Generate message passed to L2ERC721Gateway.
bytes memory _message = abi.encodeCall(
IL2ERC721Gateway.finalizeDepositERC721,
(_token, _l2Token, msg.sender, _to, _tokenId)
(_token, _l2Token, _sender, _to, _tokenId)
);
// 3. Send message to L1ScrollMessenger.
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, msg.sender);
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender);
emit DepositERC721(_token, _l2Token, msg.sender, _to, _tokenId);
emit DepositERC721(_token, _l2Token, _sender, _to, _tokenId);
}
/// @dev Internal function to batch deposit ERC721 NFT to layer 2.
@@ -221,20 +223,22 @@ contract L1ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL1ERC72
address _l2Token = tokenMapping[_token];
require(_l2Token != address(0), "no corresponding l2 token");
address _sender = _msgSender();
// 1. transfer token to this contract
for (uint256 i = 0; i < _tokenIds.length; i++) {
IERC721Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _tokenIds[i]);
IERC721Upgradeable(_token).safeTransferFrom(_sender, address(this), _tokenIds[i]);
}
// 2. Generate message passed to L2ERC721Gateway.
bytes memory _message = abi.encodeCall(
IL2ERC721Gateway.finalizeBatchDepositERC721,
(_token, _l2Token, msg.sender, _to, _tokenIds)
(_token, _l2Token, _sender, _to, _tokenIds)
);
// 3. Send message to L1ScrollMessenger.
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, msg.sender);
IL1ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit, _sender);
emit BatchDepositERC721(_token, _l2Token, msg.sender, _to, _tokenIds);
emit BatchDepositERC721(_token, _l2Token, _sender, _to, _tokenIds);
}
}

View File

@@ -44,7 +44,7 @@ contract L1ETHGateway is ScrollGatewayBase, IL1ETHGateway, IMessageDropCallback
/// @inheritdoc IL1ETHGateway
function depositETH(uint256 _amount, uint256 _gasLimit) external payable override {
_deposit(msg.sender, _amount, new bytes(0), _gasLimit);
_deposit(_msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL1ETHGateway
@@ -119,8 +119,8 @@ contract L1ETHGateway is ScrollGatewayBase, IL1ETHGateway, IMessageDropCallback
require(_amount > 0, "deposit zero eth");
// 1. Extract real sender if this call is from L1GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}

View File

@@ -45,7 +45,7 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
}
modifier onlyInContext() {
require(msg.sender == gatewayInContext, "Only in deposit context");
require(_msgSender() == gatewayInContext, "Only in deposit context");
_;
}
@@ -110,9 +110,10 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
address _token,
uint256 _amount
) external onlyInContext returns (uint256) {
uint256 _balance = IERC20Upgradeable(_token).balanceOf(msg.sender);
IERC20Upgradeable(_token).safeTransferFrom(_sender, msg.sender, _amount);
_amount = IERC20Upgradeable(_token).balanceOf(msg.sender) - _balance;
address _caller = _msgSender();
uint256 _balance = IERC20Upgradeable(_token).balanceOf(_caller);
IERC20Upgradeable(_token).safeTransferFrom(_sender, _caller, _amount);
_amount = IERC20Upgradeable(_token).balanceOf(_caller) - _balance;
return _amount;
}
@@ -126,7 +127,7 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
uint256 _amount,
uint256 _gasLimit
) external payable override {
depositERC20AndCall(_token, msg.sender, _amount, new bytes(0), _gasLimit);
depositERC20AndCall(_token, _msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL1ERC20Gateway
@@ -154,7 +155,7 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
gatewayInContext = _gateway;
// encode msg.sender with _data
bytes memory _routerData = abi.encode(msg.sender, _data);
bytes memory _routerData = abi.encode(_msgSender(), _data);
IL1ERC20Gateway(_gateway).depositERC20AndCall{value: msg.value}(_token, _to, _amount, _routerData, _gasLimit);
@@ -180,7 +181,7 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
/// @inheritdoc IL1ETHGateway
function depositETH(uint256 _amount, uint256 _gasLimit) external payable override {
depositETHAndCall(msg.sender, _amount, new bytes(0), _gasLimit);
depositETHAndCall(_msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL1ETHGateway
@@ -203,7 +204,7 @@ contract L1GatewayRouter is OwnableUpgradeable, IL1GatewayRouter {
require(_gateway != address(0), "eth gateway available");
// encode msg.sender with _data
bytes memory _routerData = abi.encode(msg.sender, _data);
bytes memory _routerData = abi.encode(_msgSender(), _data);
IL1ETHGateway(_gateway).depositETHAndCall{value: msg.value}(_to, _amount, _routerData, _gasLimit);
}

View File

@@ -54,7 +54,7 @@ contract L1WETHGateway is L1ERC20Gateway {
}
receive() external payable {
require(msg.sender == WETH, "only WETH");
require(_msgSender() == WETH, "only WETH");
}
/*************************

View File

@@ -84,7 +84,7 @@ contract L1USDCGateway is L1ERC20Gateway, IUSDCBurnableSourceBridge {
/// @inheritdoc IUSDCBurnableSourceBridge
function burnAllLockedUSDC() external override {
require(msg.sender == circleCaller, "only circle caller");
require(_msgSender() == circleCaller, "only circle caller");
// @note Only bridged USDC will be burned. We may refund the rest if possible.
uint256 _balance = totalBridgedUSDC;

View File

@@ -75,7 +75,7 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
**********************/
modifier onlyMessenger() {
require(msg.sender == messenger, "Only callable by the L1ScrollMessenger");
require(_msgSender() == messenger, "Only callable by the L1ScrollMessenger");
_;
}
@@ -292,7 +292,7 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
_validateGasLimit(_gasLimit, _data);
// do address alias to avoid replay attack in L2.
address _sender = AddressAliasHelper.applyL1ToL2Alias(msg.sender);
address _sender = AddressAliasHelper.applyL1ToL2Alias(_msgSender());
_queueTransaction(_sender, _target, 0, _gasLimit, _data);
}
@@ -305,7 +305,7 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
uint256 _gasLimit,
bytes calldata _data
) external override {
require(msg.sender == enforcedTxGateway, "Only callable by the EnforcedTxGateway");
require(_msgSender() == enforcedTxGateway, "Only callable by the EnforcedTxGateway");
// We will check it in EnforcedTxGateway, just in case.
require(_sender.code.length == 0, "only EOA");
@@ -321,7 +321,7 @@ contract L1MessageQueue is OwnableUpgradeable, IL1MessageQueue {
uint256 _count,
uint256 _skippedBitmap
) external {
require(msg.sender == scrollChain, "Only callable by the ScrollChain");
require(_msgSender() == scrollChain, "Only callable by the ScrollChain");
require(_count <= 256, "pop too many messages");
require(pendingQueueIndex == _startIndex, "start index mismatch");

View File

@@ -111,7 +111,7 @@ contract L2GasPriceOracle is OwnableUpgradeable, IL2GasPriceOracle {
/// @notice Allows whitelisted caller to modify the l2 base fee.
/// @param _newL2BaseFee The new l2 base fee.
function setL2BaseFee(uint256 _newL2BaseFee) external {
require(whitelist.isSenderAllowed(msg.sender), "Not whitelisted sender");
require(whitelist.isSenderAllowed(_msgSender()), "Not whitelisted sender");
uint256 _oldL2BaseFee = l2BaseFee;
l2BaseFee = _newL2BaseFee;

View File

@@ -85,12 +85,12 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain {
modifier OnlySequencer() {
// @note In the decentralized mode, it should be only called by a list of validator.
require(isSequencer[msg.sender], "caller not sequencer");
require(isSequencer[_msgSender()], "caller not sequencer");
_;
}
modifier OnlyProver() {
require(isProver[msg.sender], "caller not prover");
require(isProver[_msgSender()], "caller not prover");
_;
}

View File

@@ -92,7 +92,7 @@ contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger {
bytes memory _message
) external override whenNotPaused {
// It is impossible to deploy a contract with the same address, reentrance is prevented in nature.
require(AddressAliasHelper.undoL1ToL2Alias(msg.sender) == counterpart, "Caller is not L1ScrollMessenger");
require(AddressAliasHelper.undoL1ToL2Alias(_msgSender()) == counterpart, "Caller is not L1ScrollMessenger");
bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(_from, _to, _value, _nonce, _message));
@@ -117,10 +117,9 @@ contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger {
uint256 _gasLimit
) internal nonReentrant {
require(msg.value == _value, "msg.value mismatch");
_addUsedAmount(_value);
uint256 _nonce = L2MessageQueue(messageQueue).nextMessageIndex();
bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(msg.sender, _to, _value, _nonce, _message));
bytes32 _xDomainCalldataHash = keccak256(_encodeXDomainCalldata(_msgSender(), _to, _value, _nonce, _message));
// normally this won't happen, since each message has different nonce, but just in case.
require(messageSendTimestamp[_xDomainCalldataHash] == 0, "Duplicated message");
@@ -128,7 +127,7 @@ contract L2ScrollMessenger is ScrollMessengerBase, IL2ScrollMessenger {
L2MessageQueue(messageQueue).appendMessage(_xDomainCalldataHash);
emit SentMessage(msg.sender, _to, _value, _nonce, _gasLimit, _message);
emit SentMessage(_msgSender(), _to, _value, _nonce, _gasLimit, _message);
}
/// @dev Internal function to execute a L1 => L2 message.

View File

@@ -121,14 +121,11 @@ contract L2CustomERC20Gateway is L2ERC20Gateway {
require(_amount > 0, "withdraw zero amount");
// 1. Extract real sender if this call is from L2GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}
// rate limit
_addUsedAmount(_token, _amount);
// 2. Burn token.
IScrollERC20Upgradeable(_token).burn(_from, _amount);

View File

@@ -61,7 +61,7 @@ contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC
uint256 _amount,
uint256 _gasLimit
) external payable override {
_withdrawERC1155(_token, msg.sender, _tokenId, _amount, _gasLimit);
_withdrawERC1155(_token, _msgSender(), _tokenId, _amount, _gasLimit);
}
/// @inheritdoc IL2ERC1155Gateway
@@ -82,7 +82,7 @@ contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC
uint256[] calldata _amounts,
uint256 _gasLimit
) external payable override {
_batchWithdrawERC1155(_token, msg.sender, _tokenIds, _amounts, _gasLimit);
_batchWithdrawERC1155(_token, _msgSender(), _tokenIds, _amounts, _gasLimit);
}
/// @inheritdoc IL2ERC1155Gateway
@@ -168,19 +168,21 @@ contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "no corresponding l1 token");
address _sender = _msgSender();
// 1. burn token
IScrollERC1155(_token).burn(msg.sender, _tokenId, _amount);
IScrollERC1155(_token).burn(_sender, _tokenId, _amount);
// 2. Generate message passed to L1ERC1155Gateway.
bytes memory _message = abi.encodeCall(
IL1ERC1155Gateway.finalizeWithdrawERC1155,
(_l1Token, _token, msg.sender, _to, _tokenId, _amount)
(_l1Token, _token, _sender, _to, _tokenId, _amount)
);
// 3. Send message to L2ScrollMessenger.
IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit);
emit WithdrawERC1155(_l1Token, _token, msg.sender, _to, _tokenId, _amount);
emit WithdrawERC1155(_l1Token, _token, _sender, _to, _tokenId, _amount);
}
/// @dev Internal function to batch withdraw ERC1155 NFT to layer 2.
@@ -206,18 +208,20 @@ contract L2ERC1155Gateway is ERC1155HolderUpgradeable, ScrollGatewayBase, IL2ERC
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "no corresponding l1 token");
address _sender = _msgSender();
// 1. transfer token to this contract
IScrollERC1155(_token).batchBurn(msg.sender, _tokenIds, _amounts);
IScrollERC1155(_token).batchBurn(_sender, _tokenIds, _amounts);
// 2. Generate message passed to L1ERC1155Gateway.
bytes memory _message = abi.encodeCall(
IL1ERC1155Gateway.finalizeBatchWithdrawERC1155,
(_l1Token, _token, msg.sender, _to, _tokenIds, _amounts)
(_l1Token, _token, _sender, _to, _tokenIds, _amounts)
);
// 3. Send message to L2ScrollMessenger.
IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit);
emit BatchWithdrawERC1155(_l1Token, _token, msg.sender, _to, _tokenIds, _amounts);
emit BatchWithdrawERC1155(_l1Token, _token, _sender, _to, _tokenIds, _amounts);
}
}

View File

@@ -24,7 +24,7 @@ abstract contract L2ERC20Gateway is ScrollGatewayBase, IL2ERC20Gateway {
uint256 _amount,
uint256 _gasLimit
) external payable override {
_withdraw(_token, msg.sender, _amount, new bytes(0), _gasLimit);
_withdraw(_token, _msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ERC20Gateway

View File

@@ -59,7 +59,7 @@ contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC72
uint256 _tokenId,
uint256 _gasLimit
) external payable override {
_withdrawERC721(_token, msg.sender, _tokenId, _gasLimit);
_withdrawERC721(_token, _msgSender(), _tokenId, _gasLimit);
}
/// @inheritdoc IL2ERC721Gateway
@@ -78,7 +78,7 @@ contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC72
uint256[] calldata _tokenIds,
uint256 _gasLimit
) external payable override {
_batchWithdrawERC721(_token, msg.sender, _tokenIds, _gasLimit);
_batchWithdrawERC721(_token, _msgSender(), _tokenIds, _gasLimit);
}
/// @inheritdoc IL2ERC721Gateway
@@ -159,21 +159,23 @@ contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC72
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "no corresponding l1 token");
address _sender = _msgSender();
// 1. burn token
// @note in case the token has given too much power to the gateway, we check owner here.
require(IScrollERC721(_token).ownerOf(_tokenId) == msg.sender, "token not owned");
require(IScrollERC721(_token).ownerOf(_tokenId) == _sender, "token not owned");
IScrollERC721(_token).burn(_tokenId);
// 2. Generate message passed to L1ERC721Gateway.
bytes memory _message = abi.encodeCall(
IL1ERC721Gateway.finalizeWithdrawERC721,
(_l1Token, _token, msg.sender, _to, _tokenId)
(_l1Token, _token, _sender, _to, _tokenId)
);
// 3. Send message to L2ScrollMessenger.
IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit);
emit WithdrawERC721(_l1Token, _token, msg.sender, _to, _tokenId);
emit WithdrawERC721(_l1Token, _token, _sender, _to, _tokenId);
}
/// @dev Internal function to batch withdraw ERC721 NFT to layer 1.
@@ -192,22 +194,24 @@ contract L2ERC721Gateway is ERC721HolderUpgradeable, ScrollGatewayBase, IL2ERC72
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "no corresponding l1 token");
address _sender = _msgSender();
// 1. transfer token to this contract
for (uint256 i = 0; i < _tokenIds.length; i++) {
// @note in case the token has given too much power to the gateway, we check owner here.
require(IScrollERC721(_token).ownerOf(_tokenIds[i]) == msg.sender, "token not owned");
require(IScrollERC721(_token).ownerOf(_tokenIds[i]) == _sender, "token not owned");
IScrollERC721(_token).burn(_tokenIds[i]);
}
// 2. Generate message passed to L1ERC721Gateway.
bytes memory _message = abi.encodeCall(
IL1ERC721Gateway.finalizeBatchWithdrawERC721,
(_l1Token, _token, msg.sender, _to, _tokenIds)
(_l1Token, _token, _sender, _to, _tokenIds)
);
// 3. Send message to L2ScrollMessenger.
IL2ScrollMessenger(messenger).sendMessage{value: msg.value}(counterpart, 0, _message, _gasLimit);
emit BatchWithdrawERC721(_l1Token, _token, msg.sender, _to, _tokenIds);
emit BatchWithdrawERC721(_l1Token, _token, _sender, _to, _tokenIds);
}
}

View File

@@ -40,7 +40,7 @@ contract L2ETHGateway is ScrollGatewayBase, IL2ETHGateway {
/// @inheritdoc IL2ETHGateway
function withdrawETH(uint256 _amount, uint256 _gasLimit) external payable override {
_withdraw(msg.sender, _amount, new bytes(0), _gasLimit);
_withdraw(_msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ETHGateway
@@ -93,8 +93,8 @@ contract L2ETHGateway is ScrollGatewayBase, IL2ETHGateway {
require(msg.value > 0, "withdraw zero eth");
// 1. Extract real sender if this call is from L1GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}

View File

@@ -91,7 +91,7 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
uint256 _amount,
uint256 _gasLimit
) external payable override {
withdrawERC20AndCall(_token, msg.sender, _amount, new bytes(0), _gasLimit);
withdrawERC20AndCall(_token, _msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ERC20Gateway
@@ -116,14 +116,14 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
require(_gateway != address(0), "no gateway available");
// encode msg.sender with _data
bytes memory _routerData = abi.encode(msg.sender, _data);
bytes memory _routerData = abi.encode(_msgSender(), _data);
IL2ERC20Gateway(_gateway).withdrawERC20AndCall{value: msg.value}(_token, _to, _amount, _routerData, _gasLimit);
}
/// @inheritdoc IL2ETHGateway
function withdrawETH(uint256 _amount, uint256 _gasLimit) external payable override {
withdrawETHAndCall(msg.sender, _amount, new bytes(0), _gasLimit);
withdrawETHAndCall(_msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ETHGateway
@@ -146,7 +146,7 @@ contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
require(_gateway != address(0), "eth gateway available");
// encode msg.sender with _data
bytes memory _routerData = abi.encode(msg.sender, _data);
bytes memory _routerData = abi.encode(_msgSender(), _data);
IL2ETHGateway(_gateway).withdrawETHAndCall{value: msg.value}(_to, _amount, _routerData, _gasLimit);
}

View File

@@ -132,17 +132,14 @@ contract L2StandardERC20Gateway is L2ERC20Gateway {
require(_amount > 0, "withdraw zero amount");
// 1. Extract real sender if this call is from L2GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}
address _l1Token = tokenMapping[_token];
require(_l1Token != address(0), "no corresponding l1 token");
// rate limit
_addUsedAmount(_token, _amount);
// 2. Burn token.
IScrollERC20Upgradeable(_token).burn(_from, _amount);

View File

@@ -53,7 +53,7 @@ contract L2WETHGateway is L2ERC20Gateway {
}
receive() external payable {
require(msg.sender == WETH, "only WETH");
require(_msgSender() == WETH, "only WETH");
}
/*************************
@@ -111,14 +111,11 @@ contract L2WETHGateway is L2ERC20Gateway {
require(_token == WETH, "only WETH is allowed");
// 1. Extract real sender if this call is from L1GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}
// rate limit
_addUsedAmount(_token, _amount);
// 2. Transfer token into this contract.
IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount);
IWETH(_token).withdraw(_amount);

View File

@@ -116,7 +116,7 @@ contract L2USDCGateway is L2ERC20Gateway, IUSDCDestinationBridge {
/// @inheritdoc IUSDCDestinationBridge
function transferUSDCRoles(address _owner) external {
require(msg.sender == circleCaller, "only circle caller");
require(_msgSender() == circleCaller, "only circle caller");
OwnableUpgradeable(l2USDC).transferOwnership(_owner);
}
@@ -156,15 +156,12 @@ contract L2USDCGateway is L2ERC20Gateway, IUSDCDestinationBridge {
require(!withdrawPaused, "withdraw paused");
// 1. Extract real sender if this call is from L2GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}
require(_data.length == 0, "call is not allowed");
// rate limit
_addUsedAmount(_token, _amount);
// 2. Transfer token into this contract.
IERC20Upgradeable(_token).safeTransferFrom(_from, address(this), _amount);
IFiatToken(_token).burn(_amount);

View File

@@ -119,8 +119,8 @@ contract L2USDCGatewayCCTP is CCTPGatewayBase, L2ERC20Gateway {
require(_token == l2USDC, "only USDC is allowed");
// 1. Extract real sender if this call is from L1GatewayRouter.
address _from = msg.sender;
if (router == msg.sender) {
address _from = _msgSender();
if (router == _from) {
(_from, _data) = abi.decode(_data, (address, bytes));
}

View File

@@ -27,17 +27,21 @@ contract WrappedEther is ERC20Permit {
}
function deposit() public payable {
_mint(msg.sender, msg.value);
address _sender = _msgSender();
emit Deposit(msg.sender, msg.value);
_mint(_sender, msg.value);
emit Deposit(_sender, msg.value);
}
function withdraw(uint256 wad) external {
_burn(msg.sender, wad);
address _sender = _msgSender();
(bool success, ) = msg.sender.call{value: wad}("");
_burn(_sender, wad);
(bool success, ) = _sender.call{value: wad}("");
require(success, "withdraw ETH failed");
emit Withdrawal(msg.sender, wad);
emit Withdrawal(_sender, wad);
}
}

View File

@@ -144,10 +144,10 @@ contract GasSwap is ERC2771Context, Ownable, ReentrancyGuard {
/// @param _amount The amount of token to withdraw.
function withdraw(address _token, uint256 _amount) external onlyOwner {
if (_token == address(0)) {
(bool success, ) = msg.sender.call{value: _amount}("");
(bool success, ) = _msgSender().call{value: _amount}("");
require(success, "ETH transfer failed");
} else {
IERC20(_token).safeTransfer(msg.sender, _amount);
IERC20(_token).safeTransfer(_msgSender(), _amount);
}
}

View File

@@ -7,7 +7,6 @@ import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {ScrollConstants} from "./constants/ScrollConstants.sol";
import {IETHRateLimiter} from "../rate-limiter/IETHRateLimiter.sol";
import {IScrollMessenger} from "./IScrollMessenger.sol";
// solhint-disable var-name-mixedcase
@@ -27,11 +26,6 @@ abstract contract ScrollMessengerBase is
/// @param _newFeeVault The address of new fee vault contract.
event UpdateFeeVault(address _oldFeeVault, address _newFeeVault);
/// @notice Emitted when owner updates rate limiter contract.
/// @param _oldRateLimiter The address of old rate limiter contract.
/// @param _newRateLimiter The address of new rate limiter contract.
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter);
/*************
* Variables *
*************/
@@ -45,8 +39,8 @@ abstract contract ScrollMessengerBase is
/// @notice The address of fee vault, collecting cross domain messaging fee.
address public feeVault;
/// @notice The address of ETH rate limiter contract.
address public rateLimiter;
/// @dev The storage slot used as ETH rate limiter contract, which is deprecated now.
address private __rateLimiter;
/// @dev The storage slots for future usage.
uint256[46] private __gap;
@@ -98,16 +92,6 @@ abstract contract ScrollMessengerBase is
emit UpdateFeeVault(_oldFeeVault, _newFeeVault);
}
/// @notice Update rate limiter contract.
/// @dev This function can only called by contract owner.
/// @param _newRateLimiter The address of new rate limiter contract.
function updateRateLimiter(address _newRateLimiter) external onlyOwner {
address _oldRateLimiter = rateLimiter;
rateLimiter = _newRateLimiter;
emit UpdateRateLimiter(_oldRateLimiter, _newRateLimiter);
}
/// @notice Pause the contract
/// @dev This function can only called by contract owner.
/// @param _status The pause status to update.
@@ -148,26 +132,11 @@ abstract contract ScrollMessengerBase is
);
}
/// @dev Internal function to increase ETH usage for the given `_sender`.
/// @param _amount The amount of ETH used.
function _addUsedAmount(uint256 _amount) internal {
if (_amount == 0) return;
address _rateLimiter = rateLimiter;
if (_rateLimiter != address(0)) {
IETHRateLimiter(_rateLimiter).addUsedAmount(_amount);
}
}
/// @dev Internal function to check whether the `_target` address is allowed to avoid attack.
/// @param _target The address of target address to check.
function _validateTargetAddress(address _target) internal view {
// @note check more `_target` address to avoid attack in the future when we add more external contracts.
address _rateLimiter = rateLimiter;
if (_rateLimiter != address(0)) {
require(_target != _rateLimiter, "Forbid to call rate limiter");
}
require(_target != address(this), "Forbid to call self");
}
}

View File

@@ -14,15 +14,6 @@ import {ITokenRateLimiter} from "../../rate-limiter/ITokenRateLimiter.sol";
/// @title ScrollGatewayBase
/// @notice The `ScrollGatewayBase` is a base contract for gateway contracts used in both in L1 and L2.
abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgradeable, IScrollGateway {
/**********
* Events *
**********/
/// @notice Emitted when owner updates rate limiter contract.
/// @param _oldRateLimiter The address of old rate limiter contract.
/// @param _newRateLimiter The address of new rate limiter contract.
event UpdateRateLimiter(address indexed _oldRateLimiter, address indexed _newRateLimiter);
/*************
* Variables *
*************/
@@ -36,8 +27,8 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
/// @inheritdoc IScrollGateway
address public override messenger;
/// @notice The address of token rate limiter contract.
address public rateLimiter;
/// @dev The storage slot used as token rate limiter contract, which is deprecated now.
address private __rateLimiter;
/// @dev The storage slots for future usage.
uint256[46] private __gap;
@@ -48,14 +39,14 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
modifier onlyCallByCounterpart() {
address _messenger = messenger; // gas saving
require(msg.sender == _messenger, "only messenger can call");
require(_msgSender() == _messenger, "only messenger can call");
require(counterpart == IScrollMessenger(_messenger).xDomainMessageSender(), "only call by counterpart");
_;
}
modifier onlyInDropContext() {
address _messenger = messenger; // gas saving
require(msg.sender == _messenger, "only messenger can call");
require(_msgSender() == _messenger, "only messenger can call");
require(
ScrollConstants.DROP_XDOMAIN_MESSAGE_SENDER == IScrollMessenger(_messenger).xDomainMessageSender(),
"only called in drop context"
@@ -87,20 +78,6 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
}
}
/************************
* Restricted Functions *
************************/
/// @notice Update rate limiter contract.
/// @dev This function can only called by contract owner.
/// @param _newRateLimiter The address of new rate limiter contract.
function updateRateLimiter(address _newRateLimiter) external onlyOwner {
address _oldRateLimiter = rateLimiter;
rateLimiter = _newRateLimiter;
emit UpdateRateLimiter(_oldRateLimiter, _newRateLimiter);
}
/**********************
* Internal Functions *
**********************/
@@ -113,16 +90,4 @@ abstract contract ScrollGatewayBase is ReentrancyGuardUpgradeable, OwnableUpgrad
IScrollGatewayCallback(_to).onScrollGatewayCallback(_data);
}
}
/// @dev Internal function to increase token usage for the given `_sender`.
/// @param _token The address of token.
/// @param _amount The amount of token used.
function _addUsedAmount(address _token, uint256 _amount) internal {
if (_amount == 0) return;
address _rateLimiter = rateLimiter;
if (_rateLimiter != address(0)) {
ITokenRateLimiter(_rateLimiter).addUsedAmount(_token, _amount);
}
}
}

View File

@@ -24,7 +24,7 @@ contract ScrollStandardERC20 is ERC20PermitUpgradeable, IScrollERC20Upgradeable
uint8 private decimals_;
modifier onlyGateway() {
require(gateway == msg.sender, "Only Gateway");
require(gateway == _msgSender(), "Only Gateway");
_;
}
@@ -72,7 +72,7 @@ contract ScrollStandardERC20 is ERC20PermitUpgradeable, IScrollERC20Upgradeable
bytes memory data
) private {
IERC677Receiver receiver = IERC677Receiver(to);
receiver.onTokenTransfer(msg.sender, value, data);
receiver.onTokenTransfer(_msgSender(), value, data);
}
function isContract(address _addr) private view returns (bool hasCode) {

View File

@@ -52,7 +52,7 @@ contract ScrollOwner is AccessControlEnumerable {
***************/
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
/*************************

View File

@@ -67,7 +67,7 @@ contract ETHRateLimiter is Ownable, IETHRateLimiter {
/// @inheritdoc IETHRateLimiter
function addUsedAmount(uint256 _amount) external override {
if (msg.sender != spender) {
if (_msgSender() != spender) {
revert CallerNotSpender();
}
if (_amount == 0) return;

View File

@@ -54,7 +54,7 @@ contract TokenRateLimiter is AccessControlEnumerable, ITokenRateLimiter {
revert PeriodIsZero();
}
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
periodDuration = _periodDuration;
}

View File

@@ -42,26 +42,6 @@ contract L1ScrollMessengerTest is L1GatewayTestBase {
l1Messenger.relayMessageWithProof(address(this), address(messageQueue), 0, 0, new bytes(0), proof);
}
function testForbidCallRateLimiterFromL2() external {
l1Messenger.updateRateLimiter(address(1));
bytes32 _xDomainCalldataHash = keccak256(
abi.encodeWithSignature(
"relayMessage(address,address,uint256,uint256,bytes)",
address(this),
address(1),
0,
0,
new bytes(0)
)
);
prepareL2MessageRoot(_xDomainCalldataHash);
IL1ScrollMessenger.L2MessageProof memory proof;
proof.batchIndex = rollup.lastFinalizedBatchIndex();
hevm.expectRevert("Forbid to call rate limiter");
l1Messenger.relayMessageWithProof(address(this), address(1), 0, 0, new bytes(0), proof);
}
function testForbidCallSelfFromL2() external {
bytes32 _xDomainCalldataHash = keccak256(
abi.encodeWithSignature(

View File

@@ -51,15 +51,10 @@ contract L2ScrollMessengerTest is DSTestPlus {
}
function testForbidCallFromL1() external {
l2Messenger.updateRateLimiter(address(1));
hevm.startPrank(AddressAliasHelper.applyL1ToL2Alias(address(l1Messenger)));
hevm.expectRevert("Forbid to call message queue");
l2Messenger.relayMessage(address(this), address(l2MessageQueue), 0, 0, new bytes(0));
hevm.expectRevert("Forbid to call rate limiter");
l2Messenger.relayMessage(address(this), address(1), 0, 0, new bytes(0));
hevm.expectRevert("Forbid to call self");
l2Messenger.relayMessage(address(this), address(l2Messenger), 0, 0, new bytes(0));
hevm.stopPrank();

View File

@@ -74,6 +74,10 @@ func (*Batch) TableName() string {
// GetUnassignedBatch retrieves unassigned batch based on the specified limit.
// The returned batch are sorted in ascending order by their index.
func (o *Batch) GetUnassignedBatch(ctx context.Context, maxActiveAttempts, maxTotalAttempts uint8) (*Batch, error) {
t := time.Now()
defer func() {
log.Info("GetUnassignedBatch cost", "duration(ms)", time.Since(t).Milliseconds())
}()
db := o.db.WithContext(ctx)
db = db.Where("proving_status = ?", int(types.ProvingTaskUnassigned))
db = db.Where("total_attempts < ?", maxTotalAttempts)
@@ -95,6 +99,10 @@ func (o *Batch) GetUnassignedBatch(ctx context.Context, maxActiveAttempts, maxTo
// GetAssignedBatch retrieves assigned batch based on the specified limit.
// The returned batch are sorted in ascending order by their index.
func (o *Batch) GetAssignedBatch(ctx context.Context, maxActiveAttempts, maxTotalAttempts uint8) (*Batch, error) {
t := time.Now()
defer func() {
log.Info("GetAssignedBatch cost", "duration(ms)", time.Since(t).Milliseconds())
}()
db := o.db.WithContext(ctx)
db = db.Where("proving_status = ?", int(types.ProvingTaskAssigned))
db = db.Where("total_attempts < ?", maxTotalAttempts)

View File

@@ -69,6 +69,10 @@ func (*Chunk) TableName() string {
// GetUnassignedChunk retrieves unassigned chunk based on the specified limit.
// The returned chunks are sorted in ascending order by their index.
func (o *Chunk) GetUnassignedChunk(ctx context.Context, height int, maxActiveAttempts, maxTotalAttempts uint8) (*Chunk, error) {
t := time.Now()
defer func() {
log.Info("GetUnassignedChunk cost", "duration(ms)", time.Since(t).Milliseconds())
}()
db := o.db.WithContext(ctx)
db = db.Model(&Chunk{})
db = db.Where("proving_status = ?", int(types.ProvingTaskUnassigned))
@@ -91,6 +95,10 @@ func (o *Chunk) GetUnassignedChunk(ctx context.Context, height int, maxActiveAtt
// GetAssignedChunk retrieves assigned chunk based on the specified limit.
// The returned chunks are sorted in ascending order by their index.
func (o *Chunk) GetAssignedChunk(ctx context.Context, height int, maxActiveAttempts, maxTotalAttempts uint8) (*Chunk, error) {
t := time.Now()
defer func() {
log.Info("GetAssignedChunk cost", "duration(ms)", time.Since(t).Milliseconds())
}()
db := o.db.WithContext(ctx)
db = db.Model(&Chunk{})
db = db.Where("proving_status = ?", int(types.ProvingTaskAssigned))

View File

@@ -63,7 +63,7 @@ func testResetDB(t *testing.T) {
cur, err := Current(pgDB.DB)
assert.NoError(t, err)
// total number of tables.
assert.Equal(t, 13, int(cur))
assert.Equal(t, 14, int(cur))
}
func testMigrate(t *testing.T) {

View File

@@ -0,0 +1,27 @@
-- +goose Up
-- +goose StatementBegin
drop index if exists idx_total_attempts_active_attempts_end_block_number;
drop index if exists idx_total_attempts_active_attempts_chunk_proofs_status;
create index if not exists idx_chunk_proving_status_index on chunk (proving_status, index) where deleted_at IS NULL;
create index if not exists idx_batch_proving_status_index on batch (proving_status, chunk_proofs_status, index) where deleted_at IS NULL;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
create index if not exists idx_total_attempts_active_attempts_end_block_number
on chunk (total_attempts, active_attempts, end_block_number)
where deleted_at IS NULL;
create index if not exists idx_total_attempts_active_attempts_chunk_proofs_status
on batch (total_attempts, active_attempts, chunk_proofs_status)
where deleted_at IS NULL;
drop index if exists idx_chunk_proving_status_index;
drop index if exists idx_batch_proving_status_index;
-- +goose StatementEnd

2
l2geth

Submodule l2geth updated: 25fe3ba69a...38a3a9c919

View File

@@ -307,12 +307,12 @@ func (r *Layer2Relayer) ProcessGasPriceOracle() {
// ProcessPendingBatches processes the pending batches by sending commitBatch transactions to layer 1.
func (r *Layer2Relayer) ProcessPendingBatches() {
// get pending batches from database in ascending order by their index.
pendingBatches, err := r.batchOrm.GetPendingBatches(r.ctx, 5)
batches, err := r.batchOrm.GetFailedAndPendingBatches(r.ctx, 5)
if err != nil {
log.Error("Failed to fetch pending L2 batches", "err", err)
return
}
for _, batch := range pendingBatches {
for _, batch := range batches {
r.metrics.rollupL2RelayerProcessPendingBatchTotal.Inc()
// get current header and parent header.
currentBatchHeader, err := types.DecodeBatchHeader(batch.BatchHeader)
@@ -327,6 +327,12 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
log.Error("Failed to get parent batch header", "index", batch.Index-1, "error", err)
return
}
if types.RollupStatus(parentBatch.RollupStatus) == types.RollupCommitFailed {
log.Error("Previous batch commit failed, halting further committing",
"index", parentBatch.Index, "tx hash", parentBatch.CommitTxHash)
return
}
}
// get the chunks for the batch
@@ -371,6 +377,11 @@ func (r *Layer2Relayer) ProcessPendingBatches() {
// send transaction
txID := batch.Hash + "-commit"
fallbackGasLimit := uint64(float64(batch.TotalL1CommitGas) * r.cfg.L1CommitGasLimitMultiplier)
if types.RollupStatus(batch.RollupStatus) == types.RollupCommitFailed {
// use eth_estimateGas if this batch has been committed failed.
fallbackGasLimit = 0
log.Warn("Batch commit previously failed, using eth_estimateGas for the re-submission", "hash", batch.Hash)
}
txHash, err := r.commitSender.SendTransaction(txID, &r.cfg.RollupContractAddress, big.NewInt(0), calldata, fallbackGasLimit)
if err != nil {
log.Error(
@@ -582,7 +593,8 @@ func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
status = types.RollupCommitted
} else {
status = types.RollupCommitFailed
log.Warn("transaction confirmed but failed in layer1", "confirmation", confirmation)
r.metrics.rollupL2BatchesCommittedConfirmedFailedTotal.Inc()
log.Warn("commitBatch transaction confirmed but failed in layer1", "confirmation", confirmation)
}
// @todo handle db error
err := r.batchOrm.UpdateCommitTxHashAndRollupStatus(r.ctx, batchHash.(string), confirmation.TxHash.String(), status)
@@ -603,7 +615,8 @@ func (r *Layer2Relayer) handleConfirmation(confirmation *sender.Confirmation) {
status = types.RollupFinalized
} else {
status = types.RollupFinalizeFailed
log.Warn("transaction confirmed but failed in layer1", "confirmation", confirmation)
r.metrics.rollupL2BatchesFinalizedConfirmedFailedTotal.Inc()
log.Warn("finalizeBatchWithProof transaction confirmed but failed in layer1", "confirmation", confirmation)
}
// @todo handle db error

View File

@@ -16,7 +16,9 @@ type l2RelayerMetrics struct {
rollupL2RelayerProcessCommittedBatchesFinalizedTotal prometheus.Counter
rollupL2RelayerProcessCommittedBatchesFinalizedSuccessTotal prometheus.Counter
rollupL2BatchesCommittedConfirmedTotal prometheus.Counter
rollupL2BatchesCommittedConfirmedFailedTotal prometheus.Counter
rollupL2BatchesFinalizedConfirmedTotal prometheus.Counter
rollupL2BatchesFinalizedConfirmedFailedTotal prometheus.Counter
rollupL2BatchesGasOraclerConfirmedTotal prometheus.Counter
rollupL2ChainMonitorLatestFailedCall prometheus.Counter
rollupL2ChainMonitorLatestFailedBatchStatus prometheus.Counter
@@ -62,10 +64,18 @@ func initL2RelayerMetrics(reg prometheus.Registerer) *l2RelayerMetrics {
Name: "rollup_layer2_process_committed_batches_confirmed_total",
Help: "The total number of layer2 process committed batches confirmed total",
}),
rollupL2BatchesCommittedConfirmedFailedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_committed_batches_confirmed_failed_total",
Help: "The total number of layer2 process committed batches confirmed failed total",
}),
rollupL2BatchesFinalizedConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_finalized_batches_confirmed_total",
Help: "The total number of layer2 process finalized batches confirmed total",
}),
rollupL2BatchesFinalizedConfirmedFailedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_finalized_batches_confirmed_failed_total",
Help: "The total number of layer2 process finalized batches confirmed failed total",
}),
rollupL2BatchesGasOraclerConfirmedTotal: promauto.With(reg).NewCounter(prometheus.CounterOpts{
Name: "rollup_layer2_process_gras_oracler_confirmed_total",
Help: "The total number of layer2 process finalized batches confirmed total",

View File

@@ -177,6 +177,7 @@ func (p *BatchProposer) proposeBatchChunks() ([]*orm.Chunk, *types.BatchMeta, er
}
// Add extra gas costs
totalL1CommitGas += 100000 // constant to account for ops like _getAdmin, _implementation, _requireNotPaused, etc
totalL1CommitGas += 4 * 2100 // 4 one-time cold sload for commitBatch
totalL1CommitGas += 20000 // 1 time sstore
totalL1CommitGas += 21000 // base fee for tx
@@ -206,9 +207,11 @@ func (p *BatchProposer) proposeBatchChunks() ([]*orm.Chunk, *types.BatchMeta, er
// adjust batch header hash gas cost, batch header size: 89 + 32 * ceil(l1MessagePopped / 256)
totalL1CommitGas -= types.GetKeccak256Gas(89 + 32*(totalL1MessagePopped+255)/256)
totalL1CommitGas -= types.CalldataNonZeroByteGas * (32 * (totalL1MessagePopped + 255) / 256)
totalL1CommitGas -= types.GetMemoryExpansionCost(uint64(totalL1CommitCalldataSize))
totalL1MessagePopped += uint64(chunk.TotalL1MessagesPoppedInChunk)
totalL1CommitGas += types.CalldataNonZeroByteGas * (32 * (totalL1MessagePopped + 255) / 256)
totalL1CommitGas += types.GetKeccak256Gas(89 + 32*(totalL1MessagePopped+255)/256)
totalL1CommitGas += types.GetMemoryExpansionCost(uint64(totalL1CommitCalldataSize))
totalOverEstimateL1CommitGas := uint64(p.gasCostIncreaseMultiplier * float64(totalL1CommitGas))
if totalL1CommitCalldataSize > p.maxL1CommitCalldataSizePerBatch ||
totalOverEstimateL1CommitGas > p.maxL1CommitGasPerBatch {

View File

@@ -68,7 +68,7 @@ func testBatchProposerLimits(t *testing.T) {
{
name: "MaxL1CommitGasPerBatchIsFirstChunk",
maxChunkNum: 10,
maxL1CommitGas: 100000,
maxL1CommitGas: 200000,
maxL1CommitCalldataSize: 1000000,
batchTimeoutSec: 1000000000000,
expectedBatchesLen: 1,
@@ -109,9 +109,9 @@ func testBatchProposerLimits(t *testing.T) {
chunkOrm := orm.NewChunk(db)
chunks, err := chunkOrm.GetChunksInRange(context.Background(), 0, 1)
assert.NoError(t, err)
assert.Equal(t, uint64(6006), chunks[0].TotalL1CommitGas)
assert.Equal(t, uint64(6042), chunks[0].TotalL1CommitGas)
assert.Equal(t, uint32(298), chunks[0].TotalL1CommitCalldataSize)
assert.Equal(t, uint64(93982), chunks[1].TotalL1CommitGas)
assert.Equal(t, uint64(94586), chunks[1].TotalL1CommitGas)
assert.Equal(t, uint32(5735), chunks[1].TotalL1CommitCalldataSize)
bp := NewBatchProposer(context.Background(), &config.BatchProposerConfig{
@@ -168,9 +168,9 @@ func testBatchCommitGasAndCalldataSizeEstimation(t *testing.T) {
chunkOrm := orm.NewChunk(db)
chunks, err := chunkOrm.GetChunksInRange(context.Background(), 0, 1)
assert.NoError(t, err)
assert.Equal(t, uint64(6006), chunks[0].TotalL1CommitGas)
assert.Equal(t, uint64(6042), chunks[0].TotalL1CommitGas)
assert.Equal(t, uint32(298), chunks[0].TotalL1CommitCalldataSize)
assert.Equal(t, uint64(93982), chunks[1].TotalL1CommitGas)
assert.Equal(t, uint64(94586), chunks[1].TotalL1CommitGas)
assert.Equal(t, uint32(5735), chunks[1].TotalL1CommitCalldataSize)
bp := NewBatchProposer(context.Background(), &config.BatchProposerConfig{
@@ -199,6 +199,6 @@ func testBatchCommitGasAndCalldataSizeEstimation(t *testing.T) {
assert.Equal(t, types.ProvingTaskUnassigned, types.ProvingStatus(chunk.ProvingStatus))
}
assert.Equal(t, uint64(153916), batches[0].TotalL1CommitGas)
assert.Equal(t, uint64(254562), batches[0].TotalL1CommitGas)
assert.Equal(t, uint32(6033), batches[0].TotalL1CommitCalldataSize)
}

View File

@@ -2,6 +2,7 @@ package watcher
import (
"context"
"errors"
"math/big"
"github.com/prometheus/client_golang/prometheus"
@@ -116,52 +117,39 @@ func (w *L1WatcherClient) SetConfirmations(confirmations rpc.BlockNumber) {
// FetchBlockHeader pull latest L1 blocks and save in DB
func (w *L1WatcherClient) FetchBlockHeader(blockHeight uint64) error {
w.metrics.l1WatcherFetchBlockHeaderTotal.Inc()
fromBlock := int64(w.processedBlockHeight) + 1
toBlock := int64(blockHeight)
if toBlock < fromBlock {
return nil
}
if toBlock > fromBlock+contractEventsBlocksFetchLimit {
toBlock = fromBlock + contractEventsBlocksFetchLimit - 1
}
var blocks []orm.L1Block
var err error
height := fromBlock
for ; height <= toBlock; height++ {
var block *gethTypes.Header
block, err = w.client.HeaderByNumber(w.ctx, big.NewInt(height))
if err != nil {
log.Warn("Failed to get block", "height", height, "err", err)
break
}
var baseFee uint64
if block.BaseFee != nil {
baseFee = block.BaseFee.Uint64()
}
blocks = append(blocks, orm.L1Block{
Number: uint64(height),
Hash: block.Hash().String(),
BaseFee: baseFee,
GasOracleStatus: int16(types.GasOraclePending),
})
}
// failed at first block, return with the error
if height == fromBlock {
var block *gethTypes.Header
block, err := w.client.HeaderByNumber(w.ctx, big.NewInt(int64(blockHeight)))
if err != nil {
log.Warn("Failed to get block", "height", blockHeight, "err", err)
return err
}
toBlock = height - 1
// insert succeed blocks
err = w.l1BlockOrm.InsertL1Blocks(w.ctx, blocks)
if block == nil {
log.Warn("Received nil block", "height", blockHeight)
return errors.New("received nil block")
}
var baseFee uint64
if block.BaseFee != nil {
baseFee = block.BaseFee.Uint64()
}
l1Block := orm.L1Block{
Number: blockHeight,
Hash: block.Hash().String(),
BaseFee: baseFee,
GasOracleStatus: int16(types.GasOraclePending),
}
err = w.l1BlockOrm.InsertL1Blocks(w.ctx, []orm.L1Block{l1Block})
if err != nil {
log.Warn("Failed to insert L1 block to db", "fromBlock", fromBlock, "toBlock", toBlock, "err", err)
log.Warn("Failed to insert L1 block to db", "blockHeight", blockHeight, "err", err)
return err
}
// update processed height
w.processedBlockHeight = uint64(toBlock)
w.processedBlockHeight = blockHeight
w.metrics.l1WatcherFetchBlockHeaderProcessedBlockHeight.Set(float64(w.processedBlockHeight))
return nil
}

View File

@@ -180,6 +180,9 @@ func (w *L2WatcherClient) getAndStoreBlockTraces(ctx context.Context, from, to u
}
if len(blocks) > 0 {
for _, block := range blocks {
w.metrics.rollupL2BlockL1CommitCalldataSize.Set(float64(block.EstimateL1CommitCalldataSize()))
}
if err := w.l2BlockOrm.InsertL2Blocks(w.ctx, blocks); err != nil {
return fmt.Errorf("failed to batch insert BlockTraces: %v", err)
}

View File

@@ -8,12 +8,13 @@ import (
)
type l2WatcherMetrics struct {
fetchRunningMissingBlocksTotal prometheus.Counter
fetchRunningMissingBlocksHeight prometheus.Gauge
fetchContractEventTotal prometheus.Counter
fetchContractEventHeight prometheus.Gauge
rollupL2MsgsRelayedEventsTotal prometheus.Counter
rollupL2BlocksFetchedGap prometheus.Gauge
fetchRunningMissingBlocksTotal prometheus.Counter
fetchRunningMissingBlocksHeight prometheus.Gauge
fetchContractEventTotal prometheus.Counter
fetchContractEventHeight prometheus.Gauge
rollupL2MsgsRelayedEventsTotal prometheus.Counter
rollupL2BlocksFetchedGap prometheus.Gauge
rollupL2BlockL1CommitCalldataSize prometheus.Gauge
}
var (
@@ -48,6 +49,10 @@ func initL2WatcherMetrics(reg prometheus.Registerer) *l2WatcherMetrics {
Name: "rollup_l2_watcher_blocks_fetched_gap",
Help: "The gap of l2 fetch",
}),
rollupL2BlockL1CommitCalldataSize: promauto.With(reg).NewGauge(prometheus.GaugeOpts{
Name: "rollup_l2_block_l1_commit_calldata_size",
Help: "The l1 commitBatch calldata size of the l2 block",
}),
}
})
return l2WatcherMetric

View File

@@ -192,22 +192,22 @@ func (o *Batch) GetRollupStatusByHashList(ctx context.Context, hashes []string)
return statuses, nil
}
// GetPendingBatches retrieves pending batches up to the specified limit.
// GetFailedAndPendingBatches retrieves batches with failed or pending status up to the specified limit.
// The returned batches are sorted in ascending order by their index.
func (o *Batch) GetPendingBatches(ctx context.Context, limit int) ([]*Batch, error) {
func (o *Batch) GetFailedAndPendingBatches(ctx context.Context, limit int) ([]*Batch, error) {
if limit <= 0 {
return nil, errors.New("limit must be greater than zero")
}
db := o.db.WithContext(ctx)
db = db.Model(&Batch{})
db = db.Where("rollup_status = ?", types.RollupPending)
db = db.Where("rollup_status = ? OR rollup_status = ?", types.RollupCommitFailed, types.RollupPending)
db = db.Order("index ASC")
db = db.Limit(limit)
var batches []*Batch
if err := db.Find(&batches).Error; err != nil {
return nil, fmt.Errorf("Batch.GetPendingBatches error: %w", err)
return nil, fmt.Errorf("Batch.GetFailedAndPendingBatches error: %w", err)
}
return batches, nil
}

View File

@@ -258,14 +258,17 @@ func TestBatchOrm(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, uint64(2), count)
pendingBatches, err := batchOrm.GetPendingBatches(context.Background(), 100)
err = batchOrm.UpdateRollupStatus(context.Background(), batchHash1, types.RollupCommitFailed)
assert.NoError(t, err)
pendingBatches, err := batchOrm.GetFailedAndPendingBatches(context.Background(), 100)
assert.NoError(t, err)
assert.Equal(t, 2, len(pendingBatches))
rollupStatus, err := batchOrm.GetRollupStatusByHashList(context.Background(), []string{batchHash1, batchHash2})
assert.NoError(t, err)
assert.Equal(t, 2, len(rollupStatus))
assert.Equal(t, types.RollupPending, rollupStatus[0])
assert.Equal(t, types.RollupCommitFailed, rollupStatus[0])
assert.Equal(t, types.RollupPending, rollupStatus[1])
err = batchOrm.UpdateProvingStatus(context.Background(), batchHash2, types.ProvingTaskVerified)

Submodule rpc-gateway deleted from df9af42135