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
16efedcd
Unverified
Commit
16efedcd
authored
Sep 08, 2021
by
Kelvin Fichter
Committed by
Kelvin Fichter
Nov 10, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: reintroduce whitelist
parent
f38b8000
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
239 additions
and
59 deletions
+239
-59
whitelist.spec.ts
integration-tests/test/whitelist.spec.ts
+121
-0
evm.go
l2geth/core/vm/evm.go
+39
-0
constants.go
l2geth/rollup/dump/constants.go
+1
-0
vm_errors.go
l2geth/rollup/util/vm_errors.go
+40
-0
docker-compose.yml
ops/docker-compose.yml
+2
-1
take-dump.ts
packages/contracts/bin/take-dump.ts
+7
-1
OVM_DeployerWhitelist.sol
...ntracts/contracts/L2/predeploys/OVM_DeployerWhitelist.sol
+24
-42
make-dump.ts
packages/contracts/src/make-dump.ts
+0
-4
whitelist.ts
packages/contracts/tasks/whitelist.ts
+5
-11
No files found.
integration-tests/test/whitelist.spec.ts
0 → 100644
View file @
16efedcd
/* Imports: External */
import
{
Contract
,
ContractFactory
,
Wallet
}
from
'
ethers
'
import
{
ethers
}
from
'
hardhat
'
import
chai
,
{
expect
}
from
'
chai
'
import
{
solidity
}
from
'
ethereum-waffle
'
import
{
predeploys
}
from
'
@eth-optimism/contracts
'
/* Imports: Internal */
import
{
OptimismEnv
}
from
'
./shared/env
'
import
{
l2Provider
}
from
'
./shared/utils
'
chai
.
use
(
solidity
)
describe
(
'
Whitelist
'
,
async
()
=>
{
const
initialAmount
=
1000
const
tokenName
=
'
OVM Test
'
const
tokenDecimals
=
8
const
TokenSymbol
=
'
OVM
'
let
Factory__ERC20
:
ContractFactory
let
env
:
OptimismEnv
before
(
async
()
=>
{
env
=
await
OptimismEnv
.
new
()
Factory__ERC20
=
await
ethers
.
getContractFactory
(
'
ERC20
'
,
env
.
l2Wallet
)
})
describe
(
'
when the whitelist is disabled
'
,
()
=>
{
it
(
'
should be able to deploy a contract
'
,
async
()
=>
{
await
expect
(
l2Provider
.
send
(
'
eth_call
'
,
[
Factory__ERC20
.
getDeployTransaction
(
initialAmount
,
tokenName
,
tokenDecimals
,
TokenSymbol
),
'
latest
'
,
{
[
predeploys
.
OVM_DeployerWhitelist
]:
{
state
:
{
[
'
0x0000000000000000000000000000000000000000000000000000000000000000
'
]:
'
0x0000000000000000000000000000000000000000000000000000000000000000
'
,
},
},
},
])
).
to
.
not
.
be
.
reverted
})
})
describe
(
'
when the whitelist is enabled
'
,
()
=>
{
const
sender
=
'
0x
'
+
'
22
'
.
repeat
(
20
)
it
(
'
should fail if the user is not whitelisted
'
,
async
()
=>
{
await
expect
(
l2Provider
.
send
(
'
eth_call
'
,
[
{
...
Factory__ERC20
.
getDeployTransaction
(
initialAmount
,
tokenName
,
tokenDecimals
,
TokenSymbol
),
from
:
sender
,
},
'
latest
'
,
{
[
predeploys
.
OVM_DeployerWhitelist
]:
{
state
:
{
// Set an owner but don't allow this user to deploy
// Owner here is address(1) instead of address(0)
[
'
0x0000000000000000000000000000000000000000000000000000000000000000
'
]:
'
0x0000000000000000000000000000000000000000000000000000000000000001
'
,
},
},
},
])
).
to
.
be
.
revertedWith
(
`deployer address not whitelisted:
${
sender
}
`
)
})
it
(
'
should succeed if the user is whitelisted
'
,
async
()
=>
{
await
expect
(
l2Provider
.
send
(
'
eth_call
'
,
[
{
...
Factory__ERC20
.
getDeployTransaction
(
initialAmount
,
tokenName
,
tokenDecimals
,
TokenSymbol
),
from
:
sender
,
},
'
latest
'
,
{
[
predeploys
.
OVM_DeployerWhitelist
]:
{
state
:
{
// Set an owner
[
'
0x0000000000000000000000000000000000000000000000000000000000000000
'
]:
'
0x0000000000000000000000000000000000000000000000000000000000000001
'
,
// See https://docs.soliditylang.org/en/v0.8.7/internals/layout_in_storage.html for
// reference on how the correct storage slot should be set.
// Whitelist mapping is located at storage slot 1.
// whitelist[address] will be located at:
// keccak256(uint256(address) . uint256(1)))
[
ethers
.
utils
.
keccak256
(
'
0x
'
+
// uint256(address)
'
0000000000000000000000002222222222222222222222222222222222222222
'
+
// uint256(1)
'
0000000000000000000000000000000000000000000000000000000000000001
'
)]:
'
0x0000000000000000000000000000000000000000000000000000000000000001
'
,
// Boolean (1)
},
},
},
])
).
to
.
not
.
be
.
reverted
})
})
})
l2geth/core/vm/evm.go
View file @
16efedcd
...
@@ -18,6 +18,7 @@ package vm
...
@@ -18,6 +18,7 @@ package vm
import
(
import
(
"bytes"
"bytes"
"fmt"
"math/big"
"math/big"
"sync/atomic"
"sync/atomic"
"time"
"time"
...
@@ -25,6 +26,10 @@ import (
...
@@ -25,6 +26,10 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rollup/dump"
"github.com/ethereum/go-ethereum/rollup/rcfg"
"github.com/ethereum/go-ethereum/rollup/util"
"golang.org/x/crypto/sha3"
)
)
// emptyCodeHash is used by create to ensure deployment is disallowed to already
// emptyCodeHash is used by create to ensure deployment is disallowed to already
...
@@ -414,6 +419,20 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
...
@@ -414,6 +419,20 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if
!
evm
.
CanTransfer
(
evm
.
StateDB
,
caller
.
Address
(),
value
)
{
if
!
evm
.
CanTransfer
(
evm
.
StateDB
,
caller
.
Address
(),
value
)
{
return
nil
,
common
.
Address
{},
gas
,
ErrInsufficientBalance
return
nil
,
common
.
Address
{},
gas
,
ErrInsufficientBalance
}
}
if
rcfg
.
UsingOVM
{
// Make sure the creator address should be able to deploy.
if
!
evm
.
AddressWhitelisted
(
caller
.
Address
())
{
// Try to encode this error as a Solidity error message so it's more clear to end-users
// what's going on when a contract creation fails.
solerr
:=
fmt
.
Errorf
(
"deployer address not whitelisted: %s"
,
caller
.
Address
()
.
Hex
())
ret
,
err
:=
util
.
EncodeSolidityError
(
solerr
)
if
err
!=
nil
{
// If we're unable to properly encode the error then just return the original message.
return
nil
,
common
.
Address
{},
gas
,
solerr
}
return
ret
,
common
.
Address
{},
gas
,
errExecutionReverted
}
}
nonce
:=
evm
.
StateDB
.
GetNonce
(
caller
.
Address
())
nonce
:=
evm
.
StateDB
.
GetNonce
(
caller
.
Address
())
evm
.
StateDB
.
SetNonce
(
caller
.
Address
(),
nonce
+
1
)
evm
.
StateDB
.
SetNonce
(
caller
.
Address
(),
nonce
+
1
)
...
@@ -499,3 +518,23 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *
...
@@ -499,3 +518,23 @@ func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *
// ChainConfig returns the environment's chain configuration
// ChainConfig returns the environment's chain configuration
func
(
evm
*
EVM
)
ChainConfig
()
*
params
.
ChainConfig
{
return
evm
.
chainConfig
}
func
(
evm
*
EVM
)
ChainConfig
()
*
params
.
ChainConfig
{
return
evm
.
chainConfig
}
func
(
evm
*
EVM
)
AddressWhitelisted
(
addr
common
.
Address
)
bool
{
// First check if the owner is address(0), which implicitly disables the whitelist.
ownerKey
:=
common
.
Hash
{}
owner
:=
evm
.
StateDB
.
GetState
(
dump
.
OvmWhitelistAddress
,
ownerKey
)
if
(
owner
==
common
.
Hash
{})
{
return
true
}
// Next check if the user is whitelisted by resolving the position where the
// true/false value would be.
position
:=
common
.
Big1
hasher
:=
sha3
.
NewLegacyKeccak256
()
hasher
.
Write
(
common
.
LeftPadBytes
(
addr
.
Bytes
(),
32
))
hasher
.
Write
(
common
.
LeftPadBytes
(
position
.
Bytes
(),
32
))
digest
:=
hasher
.
Sum
(
nil
)
key
:=
common
.
BytesToHash
(
digest
)
isWhitelisted
:=
evm
.
StateDB
.
GetState
(
dump
.
OvmWhitelistAddress
,
key
)
return
isWhitelisted
!=
common
.
Hash
{}
}
l2geth/rollup/dump/constants.go
View file @
16efedcd
...
@@ -6,3 +6,4 @@ import (
...
@@ -6,3 +6,4 @@ import (
var
OvmEthAddress
=
common
.
HexToAddress
(
"0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000"
)
var
OvmEthAddress
=
common
.
HexToAddress
(
"0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000"
)
var
OvmFeeWallet
=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000011"
)
var
OvmFeeWallet
=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000011"
)
var
OvmWhitelistAddress
=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000002"
)
l2geth/rollup/util/vm_errors.go
0 → 100644
View file @
16efedcd
package
util
import
(
"fmt"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
)
var
codec
abi
.
ABI
func
init
()
{
const
abidata
=
`
[
{
"type": "function",
"name": "Error",
"constant": true,
"inputs": [
{
"name": "msg",
"type": "string"
}
],
"outputs": []
}
]
`
var
err
error
codec
,
err
=
abi
.
JSON
(
strings
.
NewReader
(
abidata
))
if
err
!=
nil
{
panic
(
fmt
.
Errorf
(
"unable to create abi decoder: %v"
,
err
))
}
}
// EncodeSolidityError generates an abi-encoded error message.
func
EncodeSolidityError
(
err
error
)
([]
byte
,
error
)
{
return
codec
.
Pack
(
"Error"
,
err
.
Error
())
}
ops/docker-compose.yml
View file @
16efedcd
...
@@ -35,7 +35,8 @@ services:
...
@@ -35,7 +35,8 @@ services:
DEPLOYER_PRIVATE_KEY
:
"
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
DEPLOYER_PRIVATE_KEY
:
"
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
SEQUENCER_PRIVATE_KEY
:
"
0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
SEQUENCER_PRIVATE_KEY
:
"
0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
GAS_PRICE_ORACLE_OWNER
:
"
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
GAS_PRICE_ORACLE_OWNER
:
"
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
WHITELIST_OWNER
:
"
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
# setting the whitelist owner to address(0) disables the whitelist
WHITELIST_OWNER
:
"
0x0000000000000000000000000000000000000000"
L1_FEE_WALLET_ADDRESS
:
"
0x391716d440c151c42cdf1c95c1d83a5427bca52c"
L1_FEE_WALLET_ADDRESS
:
"
0x391716d440c151c42cdf1c95c1d83a5427bca52c"
# skip compilation when run in docker-compose, since the contracts
# skip compilation when run in docker-compose, since the contracts
# were already compiled in the builder step
# were already compiled in the builder step
...
...
packages/contracts/bin/take-dump.ts
View file @
16efedcd
...
@@ -10,10 +10,16 @@ import { makeStateDump } from '../src/make-dump'
...
@@ -10,10 +10,16 @@ import { makeStateDump } from '../src/make-dump'
const
outfile
=
path
.
join
(
outdir
,
'
state-dump.latest.json
'
)
const
outfile
=
path
.
join
(
outdir
,
'
state-dump.latest.json
'
)
mkdirp
.
sync
(
outdir
)
mkdirp
.
sync
(
outdir
)
// Basic warning so users know that the whitelist will be disabled if the owner is the zero address.
if
(
process
.
env
.
WHITELIST_OWNER
===
'
0x
'
+
'
00
'
.
repeat
(
20
))
{
console
.
log
(
'
WARNING: whitelist owner is address(0), whitelist will be disabled
'
)
}
const
dump
=
await
makeStateDump
({
const
dump
=
await
makeStateDump
({
whitelistConfig
:
{
whitelistConfig
:
{
owner
:
process
.
env
.
WHITELIST_OWNER
,
owner
:
process
.
env
.
WHITELIST_OWNER
,
allowArbitraryContractDeployment
:
true
,
},
},
gasPriceOracleConfig
:
{
gasPriceOracleConfig
:
{
owner
:
process
.
env
.
GAS_PRICE_ORACLE_OWNER
,
owner
:
process
.
env
.
GAS_PRICE_ORACLE_OWNER
,
...
...
packages/contracts/contracts/L2/predeploys/OVM_DeployerWhitelist.sol
View file @
16efedcd
...
@@ -12,12 +12,20 @@ pragma solidity >0.5.0 <0.8.0;
...
@@ -12,12 +12,20 @@ pragma solidity >0.5.0 <0.8.0;
*/
*/
contract OVM_DeployerWhitelist {
contract OVM_DeployerWhitelist {
/**********
* Events *
**********/
event OwnerChanged(address oldOwner, address newOwner);
event WhitelistStatusChanged(address deployer, bool whitelisted);
event WhitelistDisabled(address oldOwner);
/**********************
/**********************
* Contract Constants *
* Contract Constants *
**********************/
**********************/
bool public initialized;
// WARNING: When owner is set to address(0), the whitelist is disabled.
bool public allowArbitraryDeployment;
address public owner;
address public owner;
mapping (address => bool) public whitelist;
mapping (address => bool) public whitelist;
...
@@ -42,26 +50,6 @@ contract OVM_DeployerWhitelist {
...
@@ -42,26 +50,6 @@ contract OVM_DeployerWhitelist {
* Public Functions *
* Public Functions *
********************/
********************/
/**
* Initializes the whitelist.
* @param _owner Address of the owner for this contract.
* @param _allowArbitraryDeployment Whether or not to allow arbitrary contract deployment.
*/
function initialize(
address _owner,
bool _allowArbitraryDeployment
)
external
{
if (initialized == true) {
return;
}
initialized = true;
allowArbitraryDeployment = _allowArbitraryDeployment;
owner = _owner;
}
/**
/**
* Adds or removes an address from the deployment whitelist.
* Adds or removes an address from the deployment whitelist.
* @param _deployer Address to update permissions for.
* @param _deployer Address to update permissions for.
...
@@ -75,6 +63,7 @@ contract OVM_DeployerWhitelist {
...
@@ -75,6 +63,7 @@ contract OVM_DeployerWhitelist {
onlyOwner
onlyOwner
{
{
whitelist[_deployer] = _isWhitelisted;
whitelist[_deployer] = _isWhitelisted;
emit WhitelistStatusChanged(_deployer, _isWhitelisted);
}
}
/**
/**
...
@@ -87,20 +76,16 @@ contract OVM_DeployerWhitelist {
...
@@ -87,20 +76,16 @@ contract OVM_DeployerWhitelist {
public
public
onlyOwner
onlyOwner
{
{
owner = _owner;
// Prevent users from setting the whitelist owner to address(0) except via
}
// enableArbitraryContractDeployment. If you want to burn the whitelist owner, send it to any
// other address that doesn't have a corresponding knowable private key.
require(
_owner != address(0),
"OVM_DeployerWhitelist: whitelist can only be disabled via enableArbitraryContractDeployment"
);
/**
emit OwnerChanged(owner, _owner);
* Updates the arbitrary deployment flag.
owner = _owner;
* @param _allowArbitraryDeployment Whether or not to allow arbitrary contract deployment.
*/
function setAllowArbitraryDeployment(
bool _allowArbitraryDeployment
)
public
onlyOwner
{
allowArbitraryDeployment = _allowArbitraryDeployment;
}
}
/**
/**
...
@@ -110,8 +95,8 @@ contract OVM_DeployerWhitelist {
...
@@ -110,8 +95,8 @@ contract OVM_DeployerWhitelist {
external
external
onlyOwner
onlyOwner
{
{
setAllowArbitraryDeployment(true
);
emit WhitelistDisabled(owner
);
setOwner(address(0)
);
owner = address(0
);
}
}
/**
/**
...
@@ -123,14 +108,11 @@ contract OVM_DeployerWhitelist {
...
@@ -123,14 +108,11 @@ contract OVM_DeployerWhitelist {
address _deployer
address _deployer
)
)
external
external
view
returns (
returns (
bool
bool
)
)
{
{
return (
return (owner == address(0) || whitelist[_deployer]);
initialized == false
|| allowArbitraryDeployment == true
|| whitelist[_deployer]
);
}
}
}
}
packages/contracts/src/make-dump.ts
View file @
16efedcd
...
@@ -12,7 +12,6 @@ import { getContractArtifact } from './contract-artifacts'
...
@@ -12,7 +12,6 @@ import { getContractArtifact } from './contract-artifacts'
export
interface
RollupDeployConfig
{
export
interface
RollupDeployConfig
{
whitelistConfig
:
{
whitelistConfig
:
{
owner
:
string
|
Signer
owner
:
string
|
Signer
allowArbitraryContractDeployment
:
boolean
}
}
gasPriceOracleConfig
:
{
gasPriceOracleConfig
:
{
owner
:
string
|
Signer
owner
:
string
|
Signer
...
@@ -32,9 +31,6 @@ export interface RollupDeployConfig {
...
@@ -32,9 +31,6 @@ export interface RollupDeployConfig {
export
const
makeStateDump
=
async
(
cfg
:
RollupDeployConfig
):
Promise
<
any
>
=>
{
export
const
makeStateDump
=
async
(
cfg
:
RollupDeployConfig
):
Promise
<
any
>
=>
{
const
variables
=
{
const
variables
=
{
OVM_DeployerWhitelist
:
{
OVM_DeployerWhitelist
:
{
initialized
:
true
,
allowArbitraryDeployment
:
cfg
.
whitelistConfig
.
allowArbitraryContractDeployment
,
owner
:
cfg
.
whitelistConfig
.
owner
,
owner
:
cfg
.
whitelistConfig
.
owner
,
},
},
OVM_GasPriceOracle
:
{
OVM_GasPriceOracle
:
{
...
...
packages/contracts/tasks/whitelist.ts
View file @
16efedcd
...
@@ -60,18 +60,12 @@ task('whitelist')
...
@@ -60,18 +60,12 @@ task('whitelist')
const
addr
=
await
signer
.
getAddress
()
const
addr
=
await
signer
.
getAddress
()
console
.
log
(
`Using signer:
${
addr
}
`
)
console
.
log
(
`Using signer:
${
addr
}
`
)
let
owner
=
await
deployerWhitelist
.
owner
()
const
owner
=
await
deployerWhitelist
.
owner
()
console
.
log
(
`OVM_DeployerWhitelist owner:
${
owner
}
`
)
if
(
owner
===
'
0x0000000000000000000000000000000000000000
'
)
{
if
(
owner
===
'
0x0000000000000000000000000000000000000000
'
)
{
console
.
log
(
`Initializing whitelist`
)
console
.
log
(
`Whitelist is disabled. Exiting early.`
)
const
response
=
await
deployerWhitelist
.
initialize
(
addr
,
false
,
{
return
gasPrice
:
args
.
transactionGasPrice
,
}
else
{
})
console
.
log
(
`OVM_DeployerWhitelist owner:
${
owner
}
`
)
const
receipt
=
await
response
.
wait
()
console
.
log
(
`Initialized whitelist:
${
receipt
.
transactionHash
}
`
)
owner
=
await
deployerWhitelist
.
owner
()
}
}
if
(
addr
!==
owner
)
{
if
(
addr
!==
owner
)
{
...
...
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