Commit aead527d authored by Mark Tyneway's avatar Mark Tyneway

contracts-bedrock: migrate to packages directory

Also remove the dependency on `contracts` by pulling
in files that `contracts-bedrock` depends on.
parent 416d2e60
module.exports = {
env: {
browser: false,
es2021: true,
mocha: true,
node: true,
},
plugins: ['@typescript-eslint'],
extends: [
'standard',
'plugin:prettier/recommended',
'plugin:node/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 12,
},
rules: {
'node/no-unpublished-import': 'off',
'node/no-unsupported-features/es-syntax': [
'error',
{ ignores: ['modules'] },
],
},
}
module.exports = {
$schema: 'http://json.schemastore.org/prettierrc',
trailingComma: 'es5',
tabWidth: 2,
semi: false,
singleQuote: true,
arrowParens: 'always',
overrides: [
{
files: '*.sol',
options: {
// These options are native to Prettier.
printWidth: 100,
tabWidth: 4,
useTabs: false,
singleQuote: false,
bracketSpacing: true,
// These options are specific to the Solidity Plugin
explicitTypes: 'always',
compiler: '0.8.10',
},
},
],
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
* @title Lib_BedrockPredeployAddresses
* TODO: just merge this value into the monorepo
*/
library Lib_BedrockPredeployAddresses {
address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;
}
Subproject commit c7a36fb236f298e04edf28e2fee385b80f53945f
Subproject commit 1680d7fb3e00b7b197a7336e7c88e838c7e6a3ec
Subproject commit 851ea3baa4327f453da723df75b1093b58b964dc
{
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"declaration": true,
"resolveJsonModule": true
},
"include": ["./scripts", "./test", "./typechain"],
"files": ["./hardhat.config.ts"]
}
module.exports = {
extends: '../../.eslintrc.js',
}
......@@ -88,14 +88,14 @@ OVM_ETH_Test:test_metadata() (gas: 15608)
OVM_ETH_Test:test_mint() (gas: 10621)
OVM_ETH_Test:test_transfer() (gas: 10726)
OVM_ETH_Test:test_transferFrom() (gas: 13008)
OptimismMintableTokenFactory_Test:test_bridge() (gas: 9850)
OptimismMintableTokenFactory_Test:test_burn() (gas: 52791)
OptimismMintableTokenFactory_Test:test_burnRevertsFromNotBridge() (gas: 13211)
OptimismMintableTokenFactory_Test:test_l1Token() (gas: 9779)
OptimismMintableTokenFactory_Test:test_l2Bridge() (gas: 9768)
OptimismMintableTokenFactory_Test:test_mint() (gas: 65732)
OptimismMintableTokenFactory_Test:test_mintRevertsFromNotBridge() (gas: 13213)
OptimismMintableTokenFactory_Test:test_remoteToken() (gas: 9762)
OptimismMintableERC20_Test:test_bridge() (gas: 9850)
OptimismMintableERC20_Test:test_burn() (gas: 52791)
OptimismMintableERC20_Test:test_burnRevertsFromNotBridge() (gas: 13211)
OptimismMintableERC20_Test:test_l1Token() (gas: 9779)
OptimismMintableERC20_Test:test_l2Bridge() (gas: 9768)
OptimismMintableERC20_Test:test_mint() (gas: 65732)
OptimismMintableERC20_Test:test_mintRevertsFromNotBridge() (gas: 13213)
OptimismMintableERC20_Test:test_remoteToken() (gas: 9762)
OptimismMintableTokenFactory_Test:test_bridge() (gas: 9707)
OptimismMintableTokenFactory_Test:test_createStandardL2Token() (gas: 1106538)
OptimismMintableTokenFactory_Test:test_createStandardL2TokenSameTwice() (gas: 2193987)
......
module.exports = {
...require('../../.prettierrc.js'),
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { OptimismPortal } from "./OptimismPortal.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
/**
......
......@@ -3,7 +3,7 @@ pragma solidity 0.8.10;
import { L2OutputOracle } from "./L2OutputOracle.sol";
import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol";
import { AddressAliasHelper } from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { ExcessivelySafeCall } from "../libraries/ExcessivelySafeCall.sol";
/**
......
......@@ -3,7 +3,7 @@ pragma solidity ^0.8.10;
/* External Imports */
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Lib_BedrockPredeployAddresses } from "../libraries/Lib_BedrockPredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { L1Block } from "../L2/L1Block.sol";
/**
......@@ -68,7 +68,7 @@ contract GasPriceOracle is Ownable {
}
function l1BaseFee() public view returns (uint256) {
return L1Block(Lib_BedrockPredeployAddresses.L1_BLOCK_ATTRIBUTES).basefee();
return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).basefee();
}
/**
......
......@@ -2,7 +2,7 @@
pragma solidity 0.8.10;
import { L1Block } from "./L1Block.sol";
import { Lib_BedrockPredeployAddresses } from "../libraries/Lib_BedrockPredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
/**
* @title L1BlockNumber
......@@ -30,6 +30,6 @@ contract L1BlockNumber {
}
function getL1BlockNumber() public view returns (uint256) {
return L1Block(Lib_BedrockPredeployAddresses.L1_BLOCK_ATTRIBUTES).number();
return L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES).number();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import { AddressAliasHelper } from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
import { L2ToL1MessagePasser } from "./L2ToL1MessagePasser.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
......
......@@ -2,9 +2,7 @@
pragma solidity ^0.8.9;
/* Library Imports */
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
/* Contract Imports */
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
......
......@@ -2,9 +2,7 @@
pragma solidity ^0.8.9;
/* Library Imports */
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
/* Contract Imports */
import { L2StandardBridge } from "./L2StandardBridge.sol";
......
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright 2019-2021, Offchain Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
pragma solidity ^0.8.7;
library AddressAliasHelper {
uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);
/// @notice Utility function that converts the address in the L1 that submitted a tx to
/// the inbox to the msg.sender viewed in the L2
/// @param l1Address the address in the L1 that triggered the tx to L2
/// @return l2Address L2 address as viewed in msg.sender
function applyL1ToL2Alias(address l1Address) internal pure returns (address l2Address) {
unchecked {
l2Address = address(uint160(l1Address) + offset);
}
}
/// @notice Utility function that converts the msg.sender viewed in the L2 to the
/// address in the L1 that submitted a tx to the inbox
/// @param l2Address L2 address as viewed in msg.sender
/// @return l1Address the address in the L1 that triggered the tx to L2
function undoL1ToL2Alias(address l2Address) internal pure returns (address l1Address) {
unchecked {
l1Address = address(uint160(l2Address) - offset);
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
* @title Lib_BytesUtils
*/
library Lib_BytesUtils {
/**********************
* Internal Functions *
**********************/
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
) internal pure returns (bytes memory) {
require(_length + 31 >= _length, "slice_overflow");
require(_start + _length >= _start, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) {
if (_start >= _bytes.length) {
return bytes("");
}
return slice(_bytes, _start, _bytes.length - _start);
}
function toBytes32(bytes memory _bytes) internal pure returns (bytes32) {
if (_bytes.length < 32) {
bytes32 ret;
assembly {
ret := mload(add(_bytes, 32))
}
return ret;
}
return abi.decode(_bytes, (bytes32)); // will truncate if input length > 32 bytes
}
function toUint256(bytes memory _bytes) internal pure returns (uint256) {
return uint256(toBytes32(_bytes));
}
function toNibbles(bytes memory _bytes) internal pure returns (bytes memory) {
bytes memory nibbles = new bytes(_bytes.length * 2);
for (uint256 i = 0; i < _bytes.length; i++) {
nibbles[i * 2] = _bytes[i] >> 4;
nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16);
}
return nibbles;
}
function fromNibbles(bytes memory _bytes) internal pure returns (bytes memory) {
bytes memory ret = new bytes(_bytes.length / 2);
for (uint256 i = 0; i < ret.length; i++) {
ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]);
}
return ret;
}
function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) {
return keccak256(_bytes) == keccak256(_other);
}
}
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import {
Lib_CrossDomainUtils
} from "@eth-optimism/contracts/libraries/bridge/Lib_CrossDomainUtils.sol";
import { Lib_RLPWriter } from "@eth-optimism/contracts/libraries/rlp/Lib_RLPWriter.sol";
import { Lib_CrossDomainUtils } from "./Lib_CrossDomainUtils.sol";
import { Lib_RLPWriter } from "./rlp/Lib_RLPWriter.sol";
/**
* @title CrossDomainHashing
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
* @title Lib_CrossDomainUtils
*/
library Lib_CrossDomainUtils {
/**
* Generates the correct cross domain calldata for a message.
* @param _target Target contract address.
* @param _sender Message sender address.
* @param _message Message to send to the target.
* @param _messageNonce Nonce for the provided message.
* @return ABI encoded cross domain calldata.
*/
function encodeXDomainCalldata(
address _target,
address _sender,
bytes memory _message,
uint256 _messageNonce
) internal pure returns (bytes memory) {
return
abi.encodeWithSignature(
"relayMessage(address,address,bytes,uint256)",
_target,
_sender,
_message,
_messageNonce
);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
* @title Lib_DefaultValues
*/
library Lib_DefaultValues {
// The default x-domain message sender being set to a non-zero value makes
// deployment a bit more expensive, but in exchange the refund on every call to
// `relayMessage` by the L1 and L2 messengers will be higher.
address internal constant DEFAULT_XDOMAIN_SENDER = 0x000000000000000000000000000000000000dEaD;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
* @title Lib_PredeployAddresses
*/
library Lib_PredeployAddresses {
address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;
address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;
address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;
address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000);
address internal constant L2_CROSS_DOMAIN_MESSENGER =
0x4200000000000000000000000000000000000007;
address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008;
address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009;
address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;
address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;
address internal constant L2_STANDARD_TOKEN_FACTORY =
0x4200000000000000000000000000000000000012;
address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;
address internal constant L1_BLOCK_ATTRIBUTES = 0x4200000000000000000000000000000000000015;
}
......@@ -2,12 +2,8 @@
pragma solidity 0.8.10;
/* Library Imports */
import {
Lib_SecureMerkleTrie
} from "@eth-optimism/contracts/libraries/trie/Lib_SecureMerkleTrie.sol";
import {
Lib_CrossDomainUtils
} from "@eth-optimism/contracts/libraries/bridge/Lib_CrossDomainUtils.sol";
import { Lib_SecureMerkleTrie } from "./trie/Lib_SecureMerkleTrie.sol";
import { Lib_CrossDomainUtils } from "./Lib_CrossDomainUtils.sol";
/**
* @title WithdrawalVerifier
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/**
* @title Lib_RLPWriter
* @author Bakaoh (with modifications)
*/
library Lib_RLPWriter {
/**********************
* Internal Functions *
**********************/
/**
* RLP encodes a byte string.
* @param _in The byte string to encode.
* @return The RLP encoded string in bytes.
*/
function writeBytes(bytes memory _in) internal pure returns (bytes memory) {
bytes memory encoded;
if (_in.length == 1 && uint8(_in[0]) < 128) {
encoded = _in;
} else {
encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);
}
return encoded;
}
/**
* RLP encodes a list of RLP encoded byte byte strings.
* @param _in The list of RLP encoded byte strings.
* @return The RLP encoded list of items in bytes.
*/
function writeList(bytes[] memory _in) internal pure returns (bytes memory) {
bytes memory list = _flatten(_in);
return abi.encodePacked(_writeLength(list.length, 192), list);
}
/**
* RLP encodes a string.
* @param _in The string to encode.
* @return The RLP encoded string in bytes.
*/
function writeString(string memory _in) internal pure returns (bytes memory) {
return writeBytes(bytes(_in));
}
/**
* RLP encodes an address.
* @param _in The address to encode.
* @return The RLP encoded address in bytes.
*/
function writeAddress(address _in) internal pure returns (bytes memory) {
return writeBytes(abi.encodePacked(_in));
}
/**
* RLP encodes a uint.
* @param _in The uint256 to encode.
* @return The RLP encoded uint256 in bytes.
*/
function writeUint(uint256 _in) internal pure returns (bytes memory) {
return writeBytes(_toBinary(_in));
}
/**
* RLP encodes a bool.
* @param _in The bool to encode.
* @return The RLP encoded bool in bytes.
*/
function writeBool(bool _in) internal pure returns (bytes memory) {
bytes memory encoded = new bytes(1);
encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80));
return encoded;
}
/*********************
* Private Functions *
*********************/
/**
* Encode the first byte, followed by the `len` in binary form if `length` is more than 55.
* @param _len The length of the string or the payload.
* @param _offset 128 if item is string, 192 if item is list.
* @return RLP encoded bytes.
*/
function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory) {
bytes memory encoded;
if (_len < 56) {
encoded = new bytes(1);
encoded[0] = bytes1(uint8(_len) + uint8(_offset));
} else {
uint256 lenLen;
uint256 i = 1;
while (_len / i != 0) {
lenLen++;
i *= 256;
}
encoded = new bytes(lenLen + 1);
encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55);
for (i = 1; i <= lenLen; i++) {
encoded[i] = bytes1(uint8((_len / (256**(lenLen - i))) % 256));
}
}
return encoded;
}
/**
* Encode integer in big endian binary form with no leading zeroes.
* @notice TODO: This should be optimized with assembly to save gas costs.
* @param _x The integer to encode.
* @return RLP encoded bytes.
*/
function _toBinary(uint256 _x) private pure returns (bytes memory) {
bytes memory b = abi.encodePacked(_x);
uint256 i = 0;
for (; i < 32; i++) {
if (b[i] != 0) {
break;
}
}
bytes memory res = new bytes(32 - i);
for (uint256 j = 0; j < res.length; j++) {
res[j] = b[i++];
}
return res;
}
/**
* Copies a piece of memory to another location.
* @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.
* @param _dest Destination location.
* @param _src Source location.
* @param _len Length of memory to copy.
*/
function _memcpy(
uint256 _dest,
uint256 _src,
uint256 _len
) private pure {
uint256 dest = _dest;
uint256 src = _src;
uint256 len = _len;
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
uint256 mask;
unchecked {
mask = 256**(32 - len) - 1;
}
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
/**
* Flattens a list of byte strings into one byte string.
* @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.
* @param _list List of byte strings to flatten.
* @return The flattened byte string.
*/
function _flatten(bytes[] memory _list) private pure returns (bytes memory) {
if (_list.length == 0) {
return new bytes(0);
}
uint256 len;
uint256 i = 0;
for (; i < _list.length; i++) {
len += _list[i].length;
}
bytes memory flattened = new bytes(len);
uint256 flattenedPtr;
assembly {
flattenedPtr := add(flattened, 0x20)
}
for (i = 0; i < _list.length; i++) {
bytes memory item = _list[i];
uint256 listPtr;
assembly {
listPtr := add(item, 0x20)
}
_memcpy(flattenedPtr, listPtr, item.length);
flattenedPtr += _list[i].length;
}
return flattened;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
/* Library Imports */
import { Lib_MerkleTrie } from "./Lib_MerkleTrie.sol";
/**
* @title Lib_SecureMerkleTrie
*/
library Lib_SecureMerkleTrie {
/**********************
* Internal Functions *
**********************/
/**
* @notice Verifies a proof that a given key/value pair is present in the
* Merkle trie.
* @param _key Key of the node to search for, as a hex string.
* @param _value Value of the node to search for, as a hex string.
* @param _proof Merkle trie inclusion proof for the desired node. Unlike
* traditional Merkle trees, this proof is executed top-down and consists
* of a list of RLP-encoded nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.
*/
function verifyInclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
) internal pure returns (bool _verified) {
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);
}
/**
* @notice Retrieves the value associated with a given key.
* @param _key Key to search for, as hex bytes.
* @param _proof Merkle trie inclusion proof for the key.
* @param _root Known root of the Merkle trie.
* @return _exists Whether or not the key exists.
* @return _value Value of the key if it exists.
*/
function get(
bytes memory _key,
bytes memory _proof,
bytes32 _root
) internal pure returns (bool _exists, bytes memory _value) {
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.get(key, _proof, _root);
}
/*********************
* Private Functions *
*********************/
/**
* Computes the secure counterpart to a key.
* @param _key Key to get a secure key from.
* @return _secureKey Secure version of the key.
*/
function _getSecureKey(bytes memory _key) private pure returns (bytes memory _secureKey) {
return abi.encodePacked(keccak256(_key));
}
}
......@@ -13,13 +13,9 @@ import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { L2CrossDomainMessenger } from "../L2/L2CrossDomainMessenger.sol";
import { AddressAliasHelper } from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { OVM_ETH } from "../L2/OVM_ETH.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract CommonTest is Test {
......
......@@ -4,7 +4,7 @@ pragma solidity 0.8.10;
import { CommonTest } from "./CommonTest.t.sol";
import { GasPriceOracle } from "../L2/GasPriceOracle.sol";
import { L1Block } from "../L2/L1Block.sol";
import { Lib_BedrockPredeployAddresses } from "../libraries/Lib_BedrockPredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
contract GasPriceOracle_Test is CommonTest {
......@@ -19,11 +19,11 @@ contract GasPriceOracle_Test is CommonTest {
function setUp() external {
// place the L1Block contract at the predeploy address
vm.etch(
Lib_BedrockPredeployAddresses.L1_BLOCK_ATTRIBUTES,
Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES,
address(new L1Block()).code
);
l1Block = L1Block(Lib_BedrockPredeployAddresses.L1_BLOCK_ATTRIBUTES);
l1Block = L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES);
depositor = l1Block.DEPOSITOR_ACCOUNT();
// We are not setting the gas oracle at its predeploy
......
......@@ -4,15 +4,15 @@ pragma solidity 0.8.10;
import { Test } from "forge-std/Test.sol";
import { L1Block } from "../L2/L1Block.sol";
import { L1BlockNumber } from "../L2/L1BlockNumber.sol";
import { Lib_BedrockPredeployAddresses } from "../libraries/Lib_BedrockPredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
contract L1BlockNumberTest is Test {
L1Block lb;
L1BlockNumber bn;
function setUp() external {
vm.etch(Lib_BedrockPredeployAddresses.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);
lb = L1Block(Lib_BedrockPredeployAddresses.L1_BLOCK_ATTRIBUTES);
vm.etch(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES, address(new L1Block()).code);
lb = L1Block(Lib_PredeployAddresses.L1_BLOCK_ATTRIBUTES);
bn = new L1BlockNumber();
vm.prank(lb.DEPOSITOR_ACCOUNT());
lb.setL1BlockValues(uint64(999), uint64(2), 3, keccak256(abi.encode(1)), uint64(4));
......
......@@ -6,18 +6,10 @@ import { Messenger_Initializer } from "./CommonTest.t.sol";
import { L2OutputOracle_Initializer } from "./L2OutputOracle.t.sol";
/* Libraries */
import {
AddressAliasHelper
} from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import {
Lib_DefaultValues
} from "@eth-optimism/contracts/libraries/constants/Lib_DefaultValues.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import {
Lib_CrossDomainUtils
} from "@eth-optimism/contracts/libraries/bridge/Lib_CrossDomainUtils.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { Lib_DefaultValues } from "../libraries/Lib_DefaultValues.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { Lib_CrossDomainUtils } from "../libraries/Lib_CrossDomainUtils.sol";
import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol";
/* Target contract dependencies */
......@@ -29,10 +21,6 @@ import { CrossDomainHashing } from "../libraries/Lib_CrossDomainHashing.sol";
/* Target contract */
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import {
ICrossDomainMessenger
} from "@eth-optimism/contracts/libraries/bridge/ICrossDomainMessenger.sol";
contract L1CrossDomainMessenger_Test is Messenger_Initializer {
// Receiver address for testing
address recipient = address(0xabbaacdc);
......
......@@ -5,10 +5,8 @@ import { Bridge_Initializer } from "./CommonTest.t.sol";
import { StandardBridge } from "../universal/StandardBridge.sol";
import { L2StandardBridge } from "../L2/L2StandardBridge.sol";
import { CrossDomainMessenger } from "../universal/CrossDomainMessenger.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { AddressAliasHelper } from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { stdStorage, StdStorage } from "forge-std/Test.sol";
......
......@@ -3,26 +3,14 @@ pragma solidity 0.8.10;
import { Messenger_Initializer } from "./CommonTest.t.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import {
Lib_CrossDomainUtils
} from "@eth-optimism/contracts/libraries/bridge/Lib_CrossDomainUtils.sol";
import { AddressAliasHelper } from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import { Lib_CrossDomainUtils } from "../libraries/Lib_CrossDomainUtils.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { L2ToL1MessagePasser } from "../L2/L2ToL1MessagePasser.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { L2CrossDomainMessenger } from "../L2/L2CrossDomainMessenger.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { Lib_BedrockPredeployAddresses } from "../libraries/Lib_BedrockPredeployAddresses.sol";
import { CrossDomainHashing } from "../libraries/Lib_CrossDomainHashing.sol";
import {
Lib_DefaultValues
} from "@eth-optimism/contracts/libraries/constants/Lib_DefaultValues.sol";
import { console } from "forge-std/console.sol";
import { Lib_DefaultValues } from "../libraries/Lib_DefaultValues.sol";
contract L2CrossDomainMessenger_Test is Messenger_Initializer {
// Receiver address for testing
......
......@@ -3,10 +3,7 @@ pragma solidity ^0.8.9;
import { CommonTest } from "./CommonTest.t.sol";
import { OVM_ETH } from "../L2/OVM_ETH.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
contract OVM_ETH_Test is CommonTest {
OVM_ETH eth;
......
......@@ -4,7 +4,7 @@ pragma solidity 0.8.10;
import { Bridge_Initializer } from "./CommonTest.t.sol";
import { LibRLP } from "./Lib_RLP.t.sol";
contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
contract OptimismMintableERC20_Test is Bridge_Initializer {
event Mint(address indexed _account, uint256 _amount);
event Burn(address indexed _account, uint256 _amount);
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import { AddressAliasHelper } from "@eth-optimism/contracts/standards/AddressAliasHelper.sol";
import { CommonTest } from "./CommonTest.t.sol";
import { AddressAliasHelper } from "../libraries/AddressAliasHelper.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { WithdrawalVerifier } from "../libraries/Lib_WithdrawalVerifier.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Bridge_Initializer } from "./CommonTest.t.sol";
import { SequencerFeeVault } from "../L2/SequencerFeeVault.sol";
import { L2StandardBridge } from "../L2/L2StandardBridge.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
contract SequencerFeeVault_Test is Bridge_Initializer {
SequencerFeeVault vault =
......
......@@ -4,9 +4,7 @@ pragma solidity ^0.8.9;
// solhint-disable max-line-length
/* Library Imports */
import {
Lib_DefaultValues
} from "@eth-optimism/contracts/libraries/constants/Lib_DefaultValues.sol";
import { Lib_DefaultValues } from "../libraries/Lib_DefaultValues.sol";
import { CrossDomainHashing } from "../libraries/Lib_CrossDomainHashing.sol";
/* External Imports */
......
......@@ -3,9 +3,7 @@ pragma solidity ^0.8.9;
/* Contract Imports */
import { OptimismMintableERC20 } from "../universal/OptimismMintableERC20.sol";
import {
Lib_PredeployAddresses
} from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";
import { Lib_PredeployAddresses } from "../libraries/Lib_PredeployAddresses.sol";
/**
* @title OptimismMintableTokenFactory
......
......@@ -5,10 +5,13 @@ src = 'contracts'
out = 'forge-artifacts'
optimizer = true
optimizer_runs = 999999
remappings = [
'@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/',
'@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/',
'@eth-optimism/contracts/=node_modules/@eth-optimism/contracts/',
'excessively-safe-call/=node_modules/excessively-safe-call/src/',
'solmate/=node_modules/@rari-capital/solmate/src',
'forge-std/=node_modules/forge-std/src',
'ds-test/=node_modules/ds-test/src'
]
bytecode_hash = "none"
......@@ -2,9 +2,9 @@ import { HardhatUserConfig, task, subtask } from 'hardhat/config'
import { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } from 'hardhat/builtin-tasks/task-names'
import '@nomiclabs/hardhat-waffle'
import '@typechain/hardhat'
import 'hardhat-gas-reporter'
import 'solidity-coverage'
import 'hardhat-deploy'
import '@foundry-rs/hardhat-forge'
import './tasks/deposits'
......@@ -33,9 +33,9 @@ const config: HardhatUserConfig = {
],
},
},
gasReporter: {
enabled: process.env.REPORT_GAS !== undefined,
currency: 'USD',
typechain: {
outDir: 'dist/types',
target: 'ethers-v5',
},
namedAccounts: {
deployer: {
......
import { BigNumber, BigNumberish, BytesLike, ContractReceipt, ethers, Event } from 'ethers'
function formatNumber(value: BigNumberish, name: string): Uint8Array {
import {
BigNumber,
BigNumberish,
BytesLike,
ContractReceipt,
ethers,
Event,
} from 'ethers'
const formatNumber = (value: BigNumberish, name: string): Uint8Array => {
const result = ethers.utils.stripZeros(BigNumber.from(value).toHexString())
if (result.length > 32) {
throw new Error(`invalid length for ${name}`)
......@@ -8,14 +15,14 @@ function formatNumber(value: BigNumberish, name: string): Uint8Array {
return result
}
function handleNumber(value: string): BigNumber {
const handleNumber = (value: string): BigNumber => {
if (value === '0x') {
return ethers.constants.Zero
}
return BigNumber.from(value)
}
function handleAddress(value: string): string {
const handleAddress = (value: string): string => {
if (value === '0x') {
// @ts-ignore
return null
......@@ -102,10 +109,16 @@ export class DepositTx {
}
const l1BlockHash = this.l1BlockHash
const input = ethers.utils.hexConcat([l1BlockHash, ethers.utils.zeroPad(marker, 32)])
const input = ethers.utils.hexConcat([
l1BlockHash,
ethers.utils.zeroPad(marker, 32),
])
const depositIDHash = ethers.utils.keccak256(input)
const domain = BigNumber.from(this.domain).toHexString()
const domainInput = ethers.utils.hexConcat([ethers.utils.zeroPad(domain, 32), depositIDHash])
const domainInput = ethers.utils.hexConcat([
ethers.utils.zeroPad(domain, 32),
depositIDHash,
])
this._sourceHash = ethers.utils.keccak256(domainInput)
}
return this._sourceHash
......@@ -157,7 +170,9 @@ export class DepositTx {
}
fromL1Receipt(receipt: ContractReceipt, index: number): DepositTx {
if (!receipt.events) throw new Error('cannot parse receipt')
if (!receipt.events) {
throw new Error('cannot parse receipt')
}
const event = receipt.events[index]
if (!event) {
throw new Error(`event index ${index} does not exist`)
......@@ -170,27 +185,38 @@ export class DepositTx {
}
fromL1Event(event: Event): DepositTx {
if (event.event !== 'TransactionDeposited')
if (event.event !== 'TransactionDeposited') {
throw new Error(`incorrect event type: ${event.event}`)
if (typeof event.args === 'undefined') throw new Error('no event args')
if (typeof event.args.from === 'undefined')
}
if (typeof event.args === 'undefined') {
throw new Error('no event args')
}
if (typeof event.args.from === 'undefined') {
throw new Error('"from" undefined')
}
this.from = event.args.from
if (typeof event.args.isCreation === 'undefined')
if (typeof event.args.isCreation === 'undefined') {
throw new Error('"isCreation" undefined')
if (typeof event.args.to === 'undefined') throw new Error('"to" undefined')
}
if (typeof event.args.to === 'undefined') {
throw new Error('"to" undefined')
}
this.to = event.args.isCreation ? null : event.args.to
if (typeof event.args.mint === 'undefined')
if (typeof event.args.mint === 'undefined') {
throw new Error('"mint" undefined')
}
this.mint = event.args.mint
if (typeof event.args.value === 'undefined')
if (typeof event.args.value === 'undefined') {
throw new Error('"value" undefined')
}
this.value = event.args.value
if (typeof event.args.gasLimit === 'undefined')
if (typeof event.args.gasLimit === 'undefined') {
throw new Error('"gasLimit" undefined')
}
this.gas = event.args.gasLimit
if (typeof event.args.data === 'undefined')
if (typeof event.args.data === 'undefined') {
throw new Error('"data" undefined')
}
this.data = event.args.data
this.domain = SourceHashDomain.UserDeposit
this.l1BlockHash = event.blockHash
......
{
"name": "@eth-optimism/specs-contracts",
"name": "@eth-optimism/contracts-bedrock",
"version": "0.1.0",
"description": "Contracts for Optimism Specs",
"main": "index.js",
"main": "dist/index",
"types": "dist/index",
"license": "MIT",
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"dist/types/*.ts",
"artifacts/src/**/*.json",
"deployments/**/*.json"
],
"dependencies": {
"@eth-optimism/contracts": "^0.5.21",
"@openzeppelin/contracts": "^4.5.0",
"@openzeppelin/contracts-upgradeable": "^4.5.2",
"ethers": "^5.6.8",
"hardhat": "^2.9.6",
"@rari-capital/solmate": "7.0.0-alpha.1",
"ds-test": "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5",
"forge-std": "https://github.com/foundry-rs/forge-std.git#1680d7fb3e00b7b197a7336e7c88e838c7e6a3ec",
"merkle-patricia-tree": "^4.2.4",
"rlp": "^2.2.7"
},
"scripts": {
"build:forge": "forge build",
"build:hh": "yarn hardhat compile",
"build": "yarn build:forge && yarn build:hh",
"build": "yarn hardhat compile",
"test:hh": "yarn hardhat test",
"test": "yarn test:forge",
"test:forge": "forge test",
"gas-snapshot": "forge snapshot",
"slither": "slither .",
"clean": "rm -rf ./artifacts ./forge-artifacts ./cache ./coverage ./tsconfig.build.tsbuildinfo",
"clean": "rm -rf ./artifacts ./forge-artifacts ./cache ./coverage ./tsconfig.tsbuildinfo",
"lint:ts:check": "eslint .",
"lint:contracts:check": "yarn solhint -f table 'contracts/**/*.sol'",
"lint:check": "yarn lint:contracts:check && yarn lint:ts:check",
......@@ -33,36 +42,24 @@
},
"devDependencies": {
"@eth-optimism/core-utils": "^0.7.3",
"@foundry-rs/hardhat-forge": "^0.1.5",
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-etherscan": "^2.1.3",
"@nomiclabs/hardhat-waffle": "^2.0.0",
"@typechain/ethers-v5": "^7.0.1",
"@typechain/hardhat": "^2.3.0",
"@types/chai": "^4.2.21",
"@types/mocha": "^9.0.0",
"@types/node": "^12.0.0",
"@typescript-eslint/eslint-plugin": "^4.29.1",
"@typescript-eslint/eslint-plugin": "^5.26.0",
"@typescript-eslint/parser": "^4.29.1",
"chai": "^4.2.0",
"dotenv": "^16.0.0",
"eslint": "^7.29.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-promise": "^5.1.0",
"ethereum-waffle": "^3.0.0",
"ethers": "^5.6.8",
"hardhat-deploy": "^0.11.4",
"hardhat-gas-reporter": "^1.0.4",
"prettier": "^2.3.2",
"prettier-plugin-solidity": "^1.0.0-beta.13",
"solhint": "^3.3.6",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.7.16",
"ts-node": "^10.1.0",
"typechain": "^5.1.2",
"typescript": "^4.5.2"
"typescript": "^4.6.2"
}
}
import { task, types } from 'hardhat/config'
import { Contract, providers, utils, Wallet } from 'ethers'
import { Event } from '@ethersproject/contracts'
import { Contract, providers, utils, Wallet, Event } from 'ethers'
import dotenv from 'dotenv'
import { DepositTx, SourceHashDomain } from '../helpers/index'
import { DepositTx } from '../helpers/index'
dotenv.config()
async function sleep(ms: number) {
const sleep = async (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms))
}
......@@ -37,7 +37,7 @@ task('deposit', 'Deposits funds onto L2.')
'deaddeaddeaddeaddeaddeaddeaddeaddead0001',
types.string
)
.setAction(async (args) => {
.setAction(async (args, hre) => {
const {
l1ProviderUrl,
l2ProviderUrl,
......@@ -46,7 +46,7 @@ task('deposit', 'Deposits funds onto L2.')
depositContractAddr,
privateKey,
} = args
const depositFeedArtifact = require('../artifacts/contracts/L1/OptimismPortal.sol/OptimismPortal.json')
const depositFeedArtifact = await hre.deployments.get('OptimismPortal')
const l1Provider = new providers.JsonRpcProvider(l1ProviderUrl)
const l2Provider = new providers.JsonRpcProvider(l2ProviderUrl)
......@@ -95,8 +95,8 @@ task('deposit', 'Deposits funds onto L2.')
console.log(`Waiting for L2 TX hash ${hash}`)
while (true) {
const tx = await l2Provider.send('eth_getTransactionByHash', [hash])
if (tx) {
const expected = await l2Provider.send('eth_getTransactionByHash', [hash])
if (expected) {
console.log('Deposit success')
break
}
......
import { expect } from 'chai'
import { BigNumber } from 'ethers'
import { DepositTx, SourceHashDomain } from '../helpers'
import { BigNumber } from '@ethersproject/bignumber'
describe('Helpers', () => {
describe('DepositTx', () => {
// TODO(tynes): this is out of date now that the subversion
// byte has been added
it('should serialize/deserialize and hash', () => {
// constants serialized using optimistic-geth
// TODO(tynes): more tests
......
{
"extends": "../../tsconfig.json",
"include": ["./scripts/", "./helpers/"],
"compilerOptions": {
"rootDir": ".",
"outDir": "./dist"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment