Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
4abef208
Unverified
Commit
4abef208
authored
Dec 15, 2023
by
Wyatt Barnes
Committed by
GitHub
Dec 16, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add deployed bytecode retrieval mitigation (#8282)
parent
6d78aa09
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
2 deletions
+86
-2
Makefile
op-bindings/Makefile
+8
-2
generator_remote.go
op-bindings/bindgen/generator_remote.go
+5
-0
main.go
op-bindings/bindgen/main.go
+18
-0
remote_handlers.go
op-bindings/bindgen/remote_handlers.go
+55
-0
No files found.
op-bindings/Makefile
View file @
4abef208
...
...
@@ -7,6 +7,8 @@ contracts-list := ./artifacts.json
log-level
:=
info
ETHERSCAN_APIKEY_ETH
?=
ETHERSCAN_APIKEY_OP
?=
RPC_URL_ETH
?=
RPC_URL_OP
?=
all
:
version mkdir bindings
...
...
@@ -36,7 +38,9 @@ bindgen-generate-all:
--source-maps-list
MIPS,PreimageOracle
\
--forge-artifacts
$
(
contracts-dir
)
/forge-artifacts
\
--etherscan
.apikey.eth
$(ETHERSCAN_APIKEY_ETH)
\
--etherscan
.apikey.op
$(ETHERSCAN_APIKEY_OP)
--etherscan
.apikey.op
$(ETHERSCAN_APIKEY_OP)
\
--rpc
.url.eth
$(RPC_URL_ETH)
\
--rpc
.url.op
$(RPC_URL_OP)
bindgen-local
:
compile bindgen-generate-local
...
...
@@ -60,7 +64,9 @@ bindgen-remote:
--log
.level
$
(
log-level
)
\
remote
\
--etherscan
.apikey.eth
$(ETHERSCAN_APIKEY_ETH)
\
--etherscan
.apikey.op
$(ETHERSCAN_APIKEY_OP)
--etherscan
.apikey.op
$(ETHERSCAN_APIKEY_OP)
\
--rpc
.url.eth
$(RPC_URL_ETH)
\
--rpc
.url.op
$(RPC_URL_OP)
mkdir
:
mkdir
-p
$(pkg)
...
...
op-bindings/bindgen/generator_remote.go
View file @
4abef208
...
...
@@ -7,6 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/etherscan"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
type
bindGenGeneratorRemote
struct
{
...
...
@@ -15,6 +16,10 @@ type bindGenGeneratorRemote struct {
eth
contractDataClient
op
contractDataClient
}
rpcClients
struct
{
eth
*
ethclient
.
Client
op
*
ethclient
.
Client
}
tempArtifactsDir
string
}
...
...
op-bindings/bindgen/main.go
View file @
4abef208
...
...
@@ -7,6 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/etherscan"
"github.com/ethereum-optimism/optimism/op-e2e/config"
oplog
"github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"
)
...
...
@@ -170,6 +171,13 @@ func parseConfigRemote(logger log.Logger, c *cli.Context) (bindGenGeneratorRemot
generator
.
contractDataClients
.
eth
=
etherscan
.
NewEthereumClient
(
c
.
String
(
EtherscanApiKeyEthFlagName
))
generator
.
contractDataClients
.
op
=
etherscan
.
NewOptimismClient
(
c
.
String
(
EtherscanApiKeyOpFlagName
))
if
generator
.
rpcClients
.
eth
,
err
=
ethclient
.
Dial
(
c
.
String
(
RpcUrlEthFlagName
));
err
!=
nil
{
return
bindGenGeneratorRemote
{},
fmt
.
Errorf
(
"error initializing Ethereum client: %w"
,
err
)
}
if
generator
.
rpcClients
.
op
,
err
=
ethclient
.
Dial
(
c
.
String
(
RpcUrlOpFlagName
));
err
!=
nil
{
return
bindGenGeneratorRemote
{},
fmt
.
Errorf
(
"error initializing Optimism client: %w"
,
err
)
}
return
generator
,
nil
}
...
...
@@ -221,5 +229,15 @@ func remoteFlags() []cli.Flag {
Usage
:
"API key to make queries to Etherscan for Optimism"
,
Required
:
true
,
},
&
cli
.
StringFlag
{
Name
:
RpcUrlEthFlagName
,
Usage
:
"RPC URL (with API key if required) to query Ethereum"
,
Required
:
true
,
},
&
cli
.
StringFlag
{
Name
:
RpcUrlOpFlagName
,
Usage
:
"RPC URL (with API key if required) to query Optimism"
,
Required
:
true
,
},
}
}
op-bindings/bindgen/remote_handlers.go
View file @
4abef208
...
...
@@ -10,6 +10,8 @@ import (
"text/template"
"github.com/ethereum-optimism/optimism/op-bindings/etherscan"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
type
contractData
struct
{
...
...
@@ -25,6 +27,12 @@ func (generator *bindGenGeneratorRemote) standardHandler(contractMetadata *remot
}
contractMetadata
.
DeployedBin
=
fetchedData
.
deployedBin
if
err
=
generator
.
compareDeployedBytecodeWithRpc
(
contractMetadata
,
"eth"
);
err
!=
nil
{
return
err
}
if
err
=
generator
.
compareDeployedBytecodeWithRpc
(
contractMetadata
,
"op"
);
err
!=
nil
{
return
err
}
// If ABI was explicitly provided by config, don't overwrite
if
contractMetadata
.
ABI
==
""
{
...
...
@@ -76,6 +84,12 @@ func (generator *bindGenGeneratorRemote) multiSendHandler(contractMetadata *remo
contractMetadata
.
ABI
=
fetchedData
.
abi
contractMetadata
.
DeployedBin
=
fetchedData
.
deployedBin
if
err
=
generator
.
compareDeployedBytecodeWithRpc
(
contractMetadata
,
"eth"
);
err
!=
nil
{
return
err
}
if
err
=
generator
.
compareDeployedBytecodeWithRpc
(
contractMetadata
,
"op"
);
err
!=
nil
{
return
err
}
if
contractMetadata
.
InitBin
,
err
=
generator
.
removeDeploymentSalt
(
fetchedData
.
deploymentTx
.
Input
,
contractMetadata
.
DeploymentSalt
);
err
!=
nil
{
return
err
}
...
...
@@ -89,6 +103,12 @@ func (generator *bindGenGeneratorRemote) senderCreatorHandler(contractMetadata *
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error fetching deployed bytecode: %w"
,
err
)
}
if
err
=
generator
.
compareDeployedBytecodeWithRpc
(
contractMetadata
,
"eth"
);
err
!=
nil
{
return
err
}
if
err
=
generator
.
compareDeployedBytecodeWithRpc
(
contractMetadata
,
"op"
);
err
!=
nil
{
return
err
}
// The SenderCreator contract is deployed by EntryPoint, so the transaction data
// from the deployment transaction is for the entire EntryPoint deployment.
...
...
@@ -221,6 +241,41 @@ func (generator *bindGenGeneratorRemote) compareBytecodeWithOp(contractMetadataE
return
nil
}
func
(
generator
*
bindGenGeneratorRemote
)
compareDeployedBytecodeWithRpc
(
contractMetadata
*
remoteContractMetadata
,
chain
string
)
error
{
var
client
*
ethclient
.
Client
switch
chain
{
case
"eth"
:
client
=
generator
.
rpcClients
.
eth
case
"op"
:
client
=
generator
.
rpcClients
.
op
default
:
return
fmt
.
Errorf
(
"unknown chain: %s, unable to retrieve a RPC client"
,
chain
)
}
var
deployment
common
.
Address
switch
chain
{
case
"eth"
:
deployment
=
contractMetadata
.
Deployments
.
Eth
case
"op"
:
deployment
=
contractMetadata
.
Deployments
.
Op
default
:
generator
.
logger
.
Warn
(
"Unable to compare bytecode from Etherscan against RPC client, no deployment address provided for chain"
,
"chain"
,
chain
)
}
if
deployment
!=
(
common
.
Address
{})
{
bytecode
,
err
:=
client
.
CodeAt
(
context
.
Background
(),
common
.
HexToAddress
(
deployment
.
Hex
()),
nil
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"error getting deployed bytecode from RPC on chain: %s err: %w"
,
chain
,
err
)
}
bytecodeHex
:=
common
.
Bytes2Hex
(
bytecode
)
if
!
strings
.
EqualFold
(
strings
.
TrimPrefix
(
contractMetadata
.
DeployedBin
,
"0x"
),
bytecodeHex
)
{
return
fmt
.
Errorf
(
"%s deployment bytecode from RPC doesn't match bytecode from Etherscan. rpcBytecode: %s etherscanBytecode: %s"
,
contractMetadata
.
Name
,
bytecodeHex
,
contractMetadata
.
DeployedBin
)
}
}
return
nil
}
func
(
generator
*
bindGenGeneratorRemote
)
writeAllOutputs
(
contractMetadata
*
remoteContractMetadata
,
fileTemplate
string
)
error
{
abiFilePath
,
bytecodeFilePath
,
err
:=
writeContractArtifacts
(
generator
.
logger
,
generator
.
tempArtifactsDir
,
contractMetadata
.
Name
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment