Commit f0693443 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #6206 from ethereum-optimism/feat/port-contracts-periphery

feat: port contracts periphery to contracts bedrock
parents 2bfa9c6a 292ef6ea
---
'@eth-optimism/chain-mon': patch
---
Update import path for artifact
---
'@eth-optimism/contracts-bedrock': minor
---
Migrate contracts periphery into bedrock
......@@ -139,7 +139,6 @@ jobs:
- "packages/chain-mon/node_modules"
- "packages/common-ts/node_modules"
- "packages/contracts-bedrock/node_modules"
- "packages/contracts-periphery/node_modules"
- "packages/core-utils/node_modules"
- "packages/fault-detector/node_modules"
- "packages/hardhat-deploy-config/node_modules"
......@@ -873,10 +872,6 @@ jobs:
name: Check common-ts
command: npx depcheck
working_directory: packages/common-ts
- run:
name: Check contracts-periphery
command: npx depcheck
working_directory: packages/contracts-periphery
- run:
name: Check core-utils
command: npx depcheck
......@@ -1328,18 +1323,11 @@ workflows:
- op-bindings-build:
requires:
- pnpm-monorepo
- js-lint-test:
name: contracts-periphery-tests
coverage_flag: contracts-periphery-tests
package_name: contracts-periphery
dependencies: "(contracts|contracts-bedrock|core-utils|hardhat-deploy-config)"
requires:
- pnpm-monorepo
- js-lint-test:
name: chain-mon-tests
coverage_flag: chain-mon-tests
package_name: chain-mon
dependencies: "(common-ts|contracts-periphery|core-utils|sdk)"
dependencies: "(common-ts|contracts-bedrock|core-utils|sdk)"
requires:
- pnpm-monorepo
- js-lint-test:
......
......@@ -2,7 +2,6 @@
/packages/common-ts @ethereum-optimism/typescript-reviewers
/packages/contracts @ethereum-optimism/contract-reviewers
/packages/contracts-bedrock @ethereum-optimism/contract-reviewers
/packages/contracts-periphery @ethereum-optimism/contract-reviewers
/packages/core-utils @ethereum-optimism/legacy-reviewers
/packages/chain-mon @smartcontracts
/packages/fault-detector @ethereum-optimism/devxpod
......
......@@ -17,11 +17,6 @@ dist
artifacts
cache
packages/contracts-periphery/coverage*
packages/contracts-periphery/@openzeppelin*
packages/contracts-periphery/hardhat*
packages/contracts-periphery/forge-artifacts*
packages/contracts-bedrock/deployments/devnetL1
packages/contracts-bedrock/deployments/anvil
......
[submodule "packages/contracts-periphery/lib/multicall"]
path = packages/contracts-periphery/lib/multicall
url = https://github.com/mds1/multicall
[submodule "lib/multicall"]
branch = v3.1.0
......@@ -16,10 +16,6 @@
"directory": "packages/contracts",
"changeProcessCWD": true
},
{
"directory": "packages/contracts-periphery",
"changeProcessCWD": true
},
{
"directory": "packages/chain-mon",
"changeProcessCWD": true
......
......@@ -52,7 +52,6 @@ Refer to the Directory Structure section below to understand which packages are
├── <a href="./packages">packages</a>
│ ├── <a href="./packages/common-ts">common-ts</a>: Common tools for building apps in TypeScript
│ ├── <a href="./packages/contracts-bedrock">contracts-bedrock</a>: Bedrock smart contracts.
│ ├── <a href="./packages/contracts-periphery">contracts-periphery</a>: Peripheral contracts for Optimism
│ ├── <a href="./packages/core-utils">core-utils</a>: Low-level utilities that make building Optimism easier
│ ├── <a href="./packages/chain-mon">chain-mon</a>: Chain monitoring services
│ ├── <a href="./packages/fault-detector">fault-detector</a>: Service for detecting Sequencer faults
......@@ -79,7 +78,6 @@ Refer to the Directory Structure section below to understand which packages are
~~ Pre-BEDROCK ~~
├── <a href="./packages">packages</a>
│ ├── <a href="./packages/common-ts">common-ts</a>: Common tools for building apps in TypeScript
│ ├── <a href="./packages/contracts-periphery">contracts-periphery</a>: Peripheral contracts for Optimism
│ ├── <a href="./packages/core-utils">core-utils</a>: Low-level utilities that make building Optimism easier
│ ├── <a href="./packages/chain-mon">chain-mon</a>: Chain monitoring services
│ ├── <a href="./packages/fault-detector">fault-detector</a>: Service for detecting Sequencer faults
......
......@@ -33,7 +33,6 @@ flag_management:
- name: common-ts-tests
- name: contracts-tests
- name: core-utils-tests
- name: contracts-periphery-tests
- name: dtl-tests
- name: chain-mon-tests
- name: fault-detector-tests
......
SHELL := /bin/bash
pkg := bindings
contracts-dir := ../packages/contracts-bedrock
monorepo-base := $(shell dirname $(realpath .))
contracts-dir := $(monorepo-base)/packages/contracts-bedrock
all: version mkdir bindings
......@@ -17,11 +18,12 @@ bindings: compile bindings-build
bindings-build:
go run ./gen/main.go \
-forge-artifacts ../packages/contracts-bedrock/forge-artifacts \
-forge-artifacts $(contracts-dir)/forge-artifacts \
-out ./bindings \
-contracts ./artifacts.json \
-source-maps MIPS,PreimageOracle \
-package $(pkg)
-package $(pkg) \
-monorepo-base $(monorepo-base)
mkdir:
mkdir -p $(pkg)
......
package ast
import (
"path/filepath"
"regexp"
"sort"
"strconv"
......@@ -33,7 +34,7 @@ type typeRemapping struct {
// inefficiency comes from replaceType, which performs a linear
// search of all replacements when performing substring matches of
// composite types.
func CanonicalizeASTIDs(in *solc.StorageLayout) *solc.StorageLayout {
func CanonicalizeASTIDs(in *solc.StorageLayout, monorepoBase string) *solc.StorageLayout {
lastId := uint(1000)
astIDRemappings := make(map[uint]uint)
typeRemappings := make(map[string]string)
......@@ -83,9 +84,18 @@ func CanonicalizeASTIDs(in *solc.StorageLayout) *solc.StorageLayout {
Types: make(map[string]solc.StorageLayoutType),
}
for _, slot := range in.Storage {
contract := slot.Contract
// Normalize the name of the contract since absolute paths
// are used when there are 2 contracts imported with the same
// name
if filepath.IsAbs(contract) {
contract = strings.TrimPrefix(strings.Replace(contract, monorepoBase, "", 1), "/")
}
outLayout.Storage = append(outLayout.Storage, solc.StorageLayoutEntry{
AstId: astIDRemappings[slot.AstId],
Contract: slot.Contract,
Contract: contract,
Label: slot.Label,
Offset: slot.Offset,
Slot: slot.Slot,
......
......@@ -49,7 +49,7 @@ func TestCanonicalize(t *testing.T) {
// Run 100 times to make sure that we aren't relying
// on random map iteration order.
for i := 0; i < 100; i++ {
require.Equal(t, testData.Out, CanonicalizeASTIDs(testData.In))
require.Equal(t, testData.Out, CanonicalizeASTIDs(testData.In, ""))
}
})
}
......
......@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const ERC20StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1001,\"contract\":\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1002,\"contract\":\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":1004,\"contract\":\"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
const ERC20StorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"node_modules/.pnpm/@openzeppelin+contracts@4.7.3/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_balances\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_mapping(t_address,t_uint256)\"},{\"astId\":1001,\"contract\":\"node_modules/.pnpm/@openzeppelin+contracts@4.7.3/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_allowances\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1002,\"contract\":\"node_modules/.pnpm/@openzeppelin+contracts@4.7.3/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_totalSupply\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_uint256\"},{\"astId\":1003,\"contract\":\"node_modules/.pnpm/@openzeppelin+contracts@4.7.3/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_name\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_string_storage\"},{\"astId\":1004,\"contract\":\"node_modules/.pnpm/@openzeppelin+contracts@4.7.3/node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20\",\"label\":\"_symbol\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_string_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_string_storage\":{\"encoding\":\"bytes\",\"label\":\"string\",\"numberOfBytes\":\"32\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}"
var ERC20StorageLayout = new(solc.StorageLayout)
......
This diff is collapsed.
......@@ -22,6 +22,7 @@ type flags struct {
SourceMaps string
OutDir string
Package string
MonorepoBase string
}
type data struct {
......@@ -39,8 +40,14 @@ func main() {
flag.StringVar(&f.Contracts, "contracts", "artifacts.json", "Path to file containing list of contracts to generate bindings for")
flag.StringVar(&f.SourceMaps, "source-maps", "", "Comma-separated list of contracts to generate source-maps for")
flag.StringVar(&f.Package, "package", "artifacts", "Go package name")
flag.StringVar(&f.MonorepoBase, "monorepo-base", "", "Base of the monorepo")
flag.Parse()
if f.MonorepoBase == "" {
log.Fatal("must provide -monorepo-base")
}
log.Printf("Using monorepo base %s\n", f.MonorepoBase)
contractData, err := os.ReadFile(f.Contracts)
if err != nil {
log.Fatal("error reading contract list: %w\n", err)
......@@ -72,21 +79,47 @@ func main() {
defer os.RemoveAll(dir)
log.Printf("created temp dir %s\n", dir)
// If some contracts have the same name then the path to their
// artifact depends on their full import path. Scan over all artifacts
// and hold a mapping from the contract name to the contract path.
// Walk walks the directory deterministically, so the later instance
// of the contract with the same name will be used
artifactPaths := make(map[string]string)
if err := filepath.Walk(f.ForgeArtifacts,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
base := filepath.Base(path)
if strings.HasSuffix(base, ".json") {
name := base[:len(base)-5]
if _, ok := artifactPaths[name]; !ok {
artifactPaths[name] = path
}
}
return nil
}); err != nil {
log.Fatal(err)
}
for _, name := range contracts {
log.Printf("generating code for %s\n", name)
forgeArtifactData, err := os.ReadFile(path.Join(f.ForgeArtifacts, name+".sol", name+".json"))
artifactPath := path.Join(f.ForgeArtifacts, name+".sol", name+".json")
forgeArtifactData, err := os.ReadFile(artifactPath)
if errors.Is(err, os.ErrNotExist) {
artifactPath = artifactPaths[name]
forgeArtifactData, err = os.ReadFile(artifactPath)
if errors.Is(err, os.ErrNotExist) {
log.Fatalf("cannot find forge-artifact of %q\n", name)
}
}
log.Printf("using forge-artifact %s\n", artifactPath)
var artifact foundry.Artifact
if err := json.Unmarshal(forgeArtifactData, &artifact); err != nil {
log.Fatalf("failed to parse forge artifact of %q: %v\n", name, err)
}
if err != nil {
log.Fatalf("error reading storage layout %s: %v\n", name, err)
}
rawAbi := artifact.Abi
if err != nil {
......@@ -121,7 +154,7 @@ func main() {
}
storage := artifact.StorageLayout
canonicalStorage := ast.CanonicalizeASTIDs(&storage)
canonicalStorage := ast.CanonicalizeASTIDs(&storage, f.MonorepoBase)
ser, err := json.Marshal(canonicalStorage)
if err != nil {
log.Fatalf("error marshaling storage: %v\n", err)
......
......@@ -7,7 +7,7 @@ import {
} from '@eth-optimism/common-ts'
import { Provider } from '@ethersproject/abstract-provider'
import { ethers } from 'ethers'
import * as DrippieArtifact from '@eth-optimism/contracts-periphery/artifacts/contracts/universal/drippie/Drippie.sol/Drippie.json'
import * as DrippieArtifact from '@eth-optimism/contracts-bedrock/forge-artifacts/Drippie.sol/Drippie.json'
import { version } from '../../package.json'
......
AdminFaucetAuthModuleTest:test_adminProof_verify_succeeds() (gas: 57577)
AdminFaucetAuthModuleTest:test_nonAdminProof_verify_succeeds() (gas: 59050)
AdminFaucetAuthModuleTest:test_proofWithWrongId_verify_succeeds() (gas: 60673)
AssetReceiverTest:test_constructor_succeeds() (gas: 9696)
AssetReceiverTest:test_receive_succeeds() (gas: 20844)
AssetReceiverTest:test_withdrawERC20_succeeds() (gas: 183383)
AssetReceiverTest:test_withdrawERC20_unauthorized_reverts() (gas: 153517)
AssetReceiverTest:test_withdrawERC20withAmount_succeeds() (gas: 182567)
AssetReceiverTest:test_withdrawERC20withAmount_unauthorized_reverts() (gas: 153528)
AssetReceiverTest:test_withdrawERC721_succeeds() (gas: 50755)
AssetReceiverTest:test_withdrawERC721_unauthorized_reverts() (gas: 51063)
AssetReceiverTest:test_withdrawETH_succeeds() (gas: 28344)
AssetReceiverTest:test_withdrawETH_unauthorized_reverts() (gas: 10680)
AssetReceiverTest:test_withdrawETHwithAmount_succeeds() (gas: 28241)
AssetReceiverTest:test_withdrawETHwithAmount_unauthorized_reverts() (gas: 10738)
AttestationStationTest:test_attest_bulk_succeeds() (gas: 703749)
AttestationStationTest:test_attest_individual_succeeds() (gas: 632087)
AttestationStationTest:test_attest_single_succeeds() (gas: 651325)
Bytes_slice_Test:test_slice_acrossMultipleWords_works() (gas: 9413)
Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1430)
Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17240)
......@@ -32,6 +50,39 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
Drippie_Test:test_create_calledTwice_reverts() (gas: 168931)
Drippie_Test:test_create_succeeds() (gas: 183380)
Drippie_Test:test_drip_amount_succeeds() (gas: 285294)
Drippie_Test:test_drip_notExist_reverts() (gas: 14876)
Drippie_Test:test_drip_reentrant_reverts() (gas: 18853)
Drippie_Test:test_name_notExist_reverts() (gas: 16012)
Drippie_Test:test_notReentrant_zeroInterval_reverts() (gas: 18845)
Drippie_Test:test_not_active_reverts() (gas: 171074)
Drippie_Test:test_reentrant_succeeds() (gas: 180159)
Drippie_Test:test_set_statusNone_reverts() (gas: 168743)
Drippie_Test:test_set_statusSame_reverts() (gas: 169129)
Drippie_Test:test_set_status_succeeds() (gas: 198449)
Drippie_Test:test_shouldArchive_ifPaused_succeeds() (gas: 177260)
Drippie_Test:test_shouldNotAllowActive_ifArchived_reverts() (gas: 174581)
Drippie_Test:test_shouldNotAllowPaused_ifArchived_reverts() (gas: 174604)
Drippie_Test:test_shouldNotArchive_ifActive_reverts() (gas: 175622)
Drippie_Test:test_status_unauthorized_reverts() (gas: 167344)
Drippie_Test:test_trigger_oneFunction_succeeds() (gas: 338143)
Drippie_Test:test_trigger_twoFunctions_succeeds() (gas: 491870)
Drippie_Test:test_twice_inOneInterval_reverts() (gas: 303767)
FaucetTest:test_authAdmin_drip_succeeds() (gas: 366111)
FaucetTest:test_drip_afterTimeout_succeeds() (gas: 447899)
FaucetTest:test_drip_beforeTimeout_reverts() (gas: 378888)
FaucetTest:test_drip_disabledModule_reverts() (gas: 352405)
FaucetTest:test_drip_emitsEvent_succeeds() (gas: 369165)
FaucetTest:test_drip_githubSendsCorrectAmount_succeeds() (gas: 366611)
FaucetTest:test_drip_optimistNftSendsCorrectAmount_succeeds() (gas: 366555)
FaucetTest:test_drip_preventsReplayAttacks_succeeds() (gas: 369218)
FaucetTest:test_initialize_succeeds() (gas: 7626)
FaucetTest:test_nonAdmin_drip_fails() (gas: 262520)
FaucetTest:test_receive_succeeds() (gas: 17401)
FaucetTest:test_withdraw_nonAdmin_reverts() (gas: 13145)
FaucetTest:test_withdraw_succeeds() (gas: 78359)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 491839)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 495751)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 495049)
......@@ -331,6 +382,53 @@ OptimismPortal_Test:test_receive_succeeds() (gas: 127513)
OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 32971)
OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46098)
OptimismPortal_Test:test_unpause_succeeds() (gas: 31756)
OptimistAllowlistTest:test_constructor_succeeds() (gas: 20476)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestorWithFalsyValue_fails() (gas: 49842)
OptimistAllowlistTest:test_isAllowedToMint_fromAllowlistAttestor_succeeds() (gas: 49304)
OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestorWithFalsyValue_fails() (gas: 49544)
OptimistAllowlistTest:test_isAllowedToMint_fromCoinbaseQuestAttestor_succeeds() (gas: 53534)
OptimistAllowlistTest:test_isAllowedToMint_fromInvite_succeeds() (gas: 235508)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongAllowlistAttestor_fails() (gas: 58311)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongCoinbaseQuestAttestor_fails() (gas: 58268)
OptimistAllowlistTest:test_isAllowedToMint_fromWrongOptimistInviter_fails() (gas: 57601)
OptimistAllowlistTest:test_isAllowedToMint_withMultipleAttestations_succeeds() (gas: 324909)
OptimistAllowlistTest:test_isAllowedToMint_withoutAnyAttestations_fails() (gas: 23210)
OptimistInviterTest:test_claimInvite_claimBeforeMinCommitmentPeriod_reverts() (gas: 142819)
OptimistInviterTest:test_claimInvite_claimForSomeoneElse_succeeds() (gas: 245467)
OptimistInviterTest:test_claimInvite_replayingUsedNonce_reverts() (gas: 288437)
OptimistInviterTest:test_claimInvite_succeeds() (gas: 241374)
OptimistInviterTest:test_claimInvite_usingERC1271Wallet_succeeds() (gas: 245742)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentChain_reverts() (gas: 156587)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentContract_reverts() (gas: 156478)
OptimistInviterTest:test_claimInvite_usingSignatureIssuedForDifferentVersion_reverts() (gas: 155102)
OptimistInviterTest:test_claimInvite_whenIssuerHasNoInvitesLeft_reverts() (gas: 562110)
OptimistInviterTest:test_claimInvite_whenIssuerNeverReceivedInvites_reverts() (gas: 110711)
OptimistInviterTest:test_claimInvite_withIncorrectSignature_reverts() (gas: 253095)
OptimistInviterTest:test_claimInvite_withoutCommittingHash_reverts() (gas: 119210)
OptimistInviterTest:test_commitInvite_committingForSomeoneElse_succeeds() (gas: 140584)
OptimistInviterTest:test_commitInvite_committingForYourself_succeeds() (gas: 138628)
OptimistInviterTest:test_commitInvite_committingSameHashTwice_reverts() (gas: 142056)
OptimistInviterTest:test_grantInvites_adminAddingInvites_succeeds() (gas: 190757)
OptimistInviterTest:test_grantInvites_nonAdminAddingInvites_reverts() (gas: 14026)
OptimistInviterTest:test_initialize_succeeds() (gas: 14724)
OptimistTest:test_approve_soulbound_reverts() (gas: 70487)
OptimistTest:test_baseURI_returnsCorrectBaseURI_succeeds() (gas: 124568)
OptimistTest:test_burn_byNonOwner_reverts() (gas: 73197)
OptimistTest:test_burn_byOwner_succeeds() (gas: 54487)
OptimistTest:test_initialize_succeeds() (gas: 24977)
OptimistTest:test_mint_afterAllowlistAttestation_succeeds() (gas: 121465)
OptimistTest:test_mint_afterCoinbaseQuestAttestation_succeeds() (gas: 130362)
OptimistTest:test_mint_afterInviteClaimed_succeeds() (gas: 311331)
OptimistTest:test_mint_afterMultipleAttestations_succeeds() (gas: 377762)
OptimistTest:test_mint_forAlreadyMintedClaimer_reverts() (gas: 118023)
OptimistTest:test_mint_forNonAllowlistedClaimer_reverts() (gas: 29886)
OptimistTest:test_mint_secondaryMinter_succeeds() (gas: 72711)
OptimistTest:test_multicall_batchingClaimAndMint_succeeds() (gas: 308376)
OptimistTest:test_setApprovalForAll_soulbound_reverts() (gas: 74239)
OptimistTest:test_supportsInterface_returnsCorrectInterfaceForERC721_succeeds() (gas: 5805)
OptimistTest:test_tokenIdOfAddress_returnsOwnerID_succeeds() (gas: 63730)
OptimistTest:test_tokenURI_returnsCorrectTokenURI_succeeds() (gas: 195908)
OptimistTest:test_transferFrom_soulbound_reverts() (gas: 75512)
PreimageOracle_Test:test_computePreimageKey_succeeds() (gas: 6267)
PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (gas: 9025)
PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 77552)
......@@ -463,5 +561,10 @@ SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas:
SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 11790)
SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 13039)
SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 10616)
TransactorTest:test_call_succeeds() (gas: 26709)
TransactorTest:test_call_unauthorized_reverts() (gas: 16543)
TransactorTest:test_constructor_succeeds() (gas: 9739)
TransactorTest:test_delegateCall_succeeds() (gas: 20909)
TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 16550)
TransferOnionTest:test_constructor_succeeds() (gas: 564855)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { AssetReceiver } from "../AssetReceiver.sol";
import { IDripCheck } from "./IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
import { Semver } from "../../universal/Semver.sol";
/**
* @title AttestationStation
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
import { Semver } from "../../universal/Semver.sol";
import {
ERC721BurnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
import { Semver } from "../../universal/Semver.sol";
import { AttestationStation } from "./AttestationStation.sol";
import { OptimistConstants } from "./libraries/OptimistConstants.sol";
......
......@@ -2,7 +2,7 @@
pragma solidity 0.8.15;
import { OptimistConstants } from "./libraries/OptimistConstants.sol";
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol";
import { Semver } from "../../universal/Semver.sol";
import { AttestationStation } from "./AttestationStation.sol";
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import {
......
......@@ -2,9 +2,9 @@
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { AdminFaucetAuthModule } from "../universal/faucet/authmodules/AdminFaucetAuthModule.sol";
import { Faucet } from "../universal/faucet/Faucet.sol";
import { FaucetHelper } from "../testing/helpers/FaucetHelper.sol";
import { AdminFaucetAuthModule } from "../periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
import { Faucet } from "../periphery/faucet/Faucet.sol";
import { FaucetHelper } from "./Helpers.sol";
/**
* @title AdminFaucetAuthModuleTest
......@@ -104,7 +104,7 @@ contract AdminFaucetAuthModuleTest is Test {
/**
* @notice assert that verify returns true for valid proofs signed by admins.
*/
function test_adminProof_verify_returnsTrue() external {
function test_adminProof_verify_succeeds() external {
bytes32 nonce = faucetHelper.consumeNonce();
address fundsReceiver = makeAddr("fundsReceiver");
bytes memory proof = issueProofWithEIP712Domain(
......@@ -132,7 +132,7 @@ contract AdminFaucetAuthModuleTest is Test {
/**
* @notice assert that verify returns false for proofs signed by nonadmins.
*/
function test_nonAdminProof_verify_returnsFalse() external {
function test_nonAdminProof_verify_succeeds() external {
bytes32 nonce = faucetHelper.consumeNonce();
address fundsReceiver = makeAddr("fundsReceiver");
bytes memory proof = issueProofWithEIP712Domain(
......@@ -161,7 +161,7 @@ contract AdminFaucetAuthModuleTest is Test {
* @notice assert that verify returns false for proofs where the id in the proof is different
* than the id in the call to verify.
*/
function test_proofWithWrongId_verify_returnsFalse() external {
function test_proofWithWrongId_verify_succeeds() external {
bytes32 nonce = faucetHelper.consumeNonce();
address fundsReceiver = makeAddr("fundsReceiver");
address randomAddress = makeAddr("randomAddress");
......
......@@ -3,9 +3,9 @@ pragma solidity 0.8.15;
/* Testing utilities */
import { Test } from "forge-std/Test.sol";
import { TestERC20 } from "../testing/helpers/TestERC20.sol";
import { TestERC721 } from "../testing/helpers/TestERC721.sol";
import { AssetReceiver } from "../universal/AssetReceiver.sol";
import { TestERC20 } from "./Helpers.sol";
import { TestERC721 } from "./Helpers.sol";
import { AssetReceiver } from "../periphery/AssetReceiver.sol";
contract AssetReceiver_Initializer is Test {
address alice = address(128);
......@@ -54,12 +54,12 @@ contract AssetReceiver_Initializer is Test {
contract AssetReceiverTest is AssetReceiver_Initializer {
// Tests if the owner was set correctly during deploy
function test_constructor() external {
function test_constructor_succeeds() external {
assertEq(address(alice), assetReceiver.owner());
}
// Tests that receive works as inteded
function test_receive() external {
function test_receive_succeeds() external {
// Check that contract balance is 0 initially
assertEq(address(assetReceiver).balance, 0);
......@@ -75,7 +75,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
}
// Tests withdrawETH function with only an address as argument, called by owner
function test_withdrawETH() external {
function test_withdrawETH_succeeds() external {
// Check contract initial balance
assertEq(address(assetReceiver).balance, 0);
// Fund contract with 1 eth and check caller and contract balances
......@@ -97,14 +97,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
}
// withdrawETH should fail if called by non-owner
function testFail_withdrawETH() external {
function test_withdrawETH_unauthorized_reverts() external {
vm.deal(address(assetReceiver), 1 ether);
assetReceiver.withdrawETH(payable(alice));
vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawETH(payable(alice));
}
// Similar as withdrawETH but specify amount to withdraw
function test_withdrawETHwithAmount() external {
function test_withdrawETHwithAmount_succeeds() external {
assertEq(address(assetReceiver).balance, 0);
vm.deal(address(assetReceiver), 1 ether);
......@@ -125,14 +125,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
}
// withdrawETH with address and amount as arguments called by non-owner
function testFail_withdrawETHwithAmount() external {
function test_withdrawETHwithAmount_unauthorized_reverts() external {
vm.deal(address(assetReceiver), 1 ether);
assetReceiver.withdrawETH(payable(alice), 0.5 ether);
vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawETH(payable(alice), 0.5 ether);
}
// Test withdrawERC20 with token and address arguments, from owner
function test_withdrawERC20() external {
function test_withdrawERC20_succeeds() external {
// check balances before the call
assertEq(testERC20.balanceOf(address(assetReceiver)), 0);
......@@ -153,14 +153,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
}
// Same as withdrawERC20 but call from non-owner
function testFail_withdrawERC20() external {
function test_withdrawERC20_unauthorized_reverts() external {
deal(address(testERC20), address(assetReceiver), 100_000);
assetReceiver.withdrawERC20(testERC20, alice);
vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawERC20(testERC20, alice);
}
// Similar as withdrawERC20 but specify amount to withdraw
function test_withdrawERC20withAmount() external {
function test_withdrawERC20withAmount_succeeds() external {
// check balances before the call
assertEq(testERC20.balanceOf(address(assetReceiver)), 0);
......@@ -181,14 +181,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
}
// Similar as withdrawERC20 with amount but call from non-owner
function testFail_withdrawERC20withAmount() external {
function test_withdrawERC20withAmount_unauthorized_reverts() external {
deal(address(testERC20), address(assetReceiver), 100_000);
assetReceiver.withdrawERC20(testERC20, alice, 50_000);
vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawERC20(testERC20, alice, 50_000);
}
// Test withdrawERC721 from owner
function test_withdrawERC721() external {
function test_withdrawERC721_succeeds() external {
// Check owner of the token before calling withdrawERC721
assertEq(testERC721.ownerOf(DEFAULT_TOKEN_ID), alice);
......@@ -209,10 +209,10 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
}
// Similar as withdrawERC721 but call from non-owner
function testFail_withdrawERC721() external {
function test_withdrawERC721_unauthorized_reverts() external {
vm.prank(alice);
testERC721.transferFrom(alice, address(assetReceiver), DEFAULT_TOKEN_ID);
assetReceiver.withdrawERC721(testERC721, alice, DEFAULT_TOKEN_ID);
vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawERC721(testERC721, alice, DEFAULT_TOKEN_ID);
}
}
......@@ -3,7 +3,7 @@ pragma solidity 0.8.15;
/* Testing utilities */
import { Test } from "forge-std/Test.sol";
import { AttestationStation } from "../universal/op-nft/AttestationStation.sol";
import { AttestationStation } from "../periphery/op-nft/AttestationStation.sol";
contract AttestationStation_Initializer is Test {
address alice_attestor = address(128);
......@@ -28,7 +28,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
bytes val
);
function test_attest_individual() external {
function test_attest_individual_succeeds() external {
AttestationStation attestationStation = new AttestationStation();
vm.expectEmit(true, true, true, true);
......@@ -38,7 +38,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
attestationStation.attest({ _about: bob, _key: bytes32("foo"), _val: bytes("bar") });
}
function test_attest_single() external {
function test_attest_single_succeeds() external {
AttestationStation attestationStation = new AttestationStation();
AttestationStation.AttestationData[]
......@@ -100,7 +100,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
);
}
function test_attest_bulk() external {
function test_attest_bulk_succeeds() external {
AttestationStation attestationStation = new AttestationStation();
vm.prank(alice_attestor);
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { CheckBalanceHigh } from "../universal/drippie/dripchecks/CheckBalanceHigh.sol";
import { CheckBalanceHigh } from "../periphery/drippie/dripchecks/CheckBalanceHigh.sol";
/**
* @title CheckBalanceHighTest
......@@ -43,7 +43,7 @@ contract CheckBalanceHighTest is Test {
* @notice Fuzz the `check` function and assert that it always returns false
* when the target's balance is smaller than the threshold.
*/
function testFuzz_check_fails(address _target, uint256 _threshold) external {
function testFuzz_check_lowBalance_fails(address _target, uint256 _threshold) external {
CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({
target: _target,
threshold: _threshold
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { CheckBalanceLow } from "../universal/drippie/dripchecks/CheckBalanceLow.sol";
import { CheckBalanceLow } from "../periphery/drippie/dripchecks/CheckBalanceLow.sol";
/**
* @title CheckBalanceLowTest
......@@ -41,7 +41,7 @@ contract CheckBalanceLowTest is Test {
* @notice Fuzz the `check` function and assert that it always returns false
* when the target's balance is larger than the threshold.
*/
function testFuzz_check_fails(address _target, uint256 _threshold) external {
function testFuzz_check_highBalance_fails(address _target, uint256 _threshold) external {
CheckBalanceLow.Params memory p = CheckBalanceLow.Params({
target: _target,
threshold: _threshold
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import {
CheckGelatoLow,
IGelatoTreasury
} from "../universal/drippie/dripchecks/CheckGelatoLow.sol";
} from "../periphery/drippie/dripchecks/CheckGelatoLow.sol";
/**
* @title MockGelatoTreasury
......@@ -78,7 +78,7 @@ contract CheckGelatoLowTest is Test {
* when the user's balance in the treasury is greater than or equal
* to the threshold.
*/
function testFuzz_check_fails(uint256 _threshold, address _recipient) external {
function testFuzz_check_highBalance_fails(uint256 _threshold, address _recipient) external {
CheckGelatoLow.Params memory p = CheckGelatoLow.Params({
treasury: address(gelato),
threshold: _threshold,
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { CheckTrue } from "../universal/drippie/dripchecks/CheckTrue.sol";
import { CheckTrue } from "../periphery/drippie/dripchecks/CheckTrue.sol";
/**
* @title CheckTrueTest
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { Drippie } from "../universal/drippie/Drippie.sol";
import { IDripCheck } from "../universal/drippie/IDripCheck.sol";
import { CheckTrue } from "../universal/drippie/dripchecks/CheckTrue.sol";
import { SimpleStorage } from "../testing/helpers/SimpleStorage.sol";
import { Drippie } from "../periphery/drippie/Drippie.sol";
import { IDripCheck } from "../periphery/drippie/IDripCheck.sol";
import { CheckTrue } from "../periphery/drippie/dripchecks/CheckTrue.sol";
import { SimpleStorage } from "./Helpers.sol";
/**
* @title TestDrippie
......@@ -149,7 +149,7 @@ contract Drippie_Test is Test {
/**
* @notice Creates a drip and asserts that it was configured as expected.
*/
function test_create_success() external {
function test_create_succeeds() external {
Drippie.DripConfig memory cfg = _defaultConfig();
vm.expectEmit(true, true, true, true);
emit DripCreated(dripName, dripName, cfg);
......@@ -188,7 +188,7 @@ contract Drippie_Test is Test {
/**
* @notice Ensures that the same drip cannot be created two times.
*/
function test_create_fails_twice() external {
function test_create_calledTwice_reverts() external {
vm.startPrank(drippie.owner());
Drippie.DripConfig memory cfg = _defaultConfig();
drippie.create(dripName, cfg);
......@@ -200,7 +200,7 @@ contract Drippie_Test is Test {
/**
* @notice Ensures that only the owner of Drippie can create a drip.
*/
function testFuzz_fails_unauthorized(address caller) external {
function testFuzz_owner_unauthorized_reverts(address caller) external {
vm.assume(caller != drippie.owner());
vm.prank(caller);
vm.expectRevert("UNAUTHORIZED");
......@@ -210,7 +210,7 @@ contract Drippie_Test is Test {
/**
* @notice The owner should be able to set the status of the drip.
*/
function test_set_status_success() external {
function test_set_status_succeeds() external {
vm.expectEmit(true, true, true, true);
emit DripCreated(dripName, dripName, _defaultConfig());
_createDefaultDrip(dripName);
......@@ -258,7 +258,7 @@ contract Drippie_Test is Test {
/**
* @notice The drip status cannot be set back to NONE after it is created.
*/
function test_set_status_none_fails() external {
function test_set_statusNone_reverts() external {
_createDefaultDrip(dripName);
vm.prank(drippie.owner());
......@@ -272,7 +272,7 @@ contract Drippie_Test is Test {
* @notice The owner cannot set the status of the drip to the status that
* it is already set as.
*/
function test_set_status_same_fails() external {
function test_set_statusSame_reverts() external {
_createDefaultDrip(dripName);
vm.prank(drippie.owner());
......@@ -286,7 +286,7 @@ contract Drippie_Test is Test {
* @notice The owner should be able to archive the drip if it is in the
* paused state.
*/
function test_should_archive_if_paused_success() external {
function test_shouldArchive_ifPaused_succeeds() external {
_createDefaultDrip(dripName);
address owner = drippie.owner();
......@@ -310,7 +310,7 @@ contract Drippie_Test is Test {
* @notice The owner should not be able to archive the drip if it is in the
* active state.
*/
function test_should_not_archive_if_active_fails() external {
function test_shouldNotArchive_ifActive_reverts() external {
_createDefaultDrip(dripName);
vm.prank(drippie.owner());
......@@ -327,7 +327,7 @@ contract Drippie_Test is Test {
* @notice The owner should not be allowed to pause the drip if it
* has already been archived.
*/
function test_should_not_allow_paused_if_archived_fails() external {
function test_shouldNotAllowPaused_ifArchived_reverts() external {
_createDefaultDrip(dripName);
_notAllowFromArchive(dripName, Drippie.DripStatus.PAUSED);
......@@ -337,7 +337,7 @@ contract Drippie_Test is Test {
* @notice The owner should not be allowed to make the drip active again if
* it has already been archived.
*/
function test_should_not_allow_active_if_archived_fails() external {
function test_shouldNotAllowActive_ifArchived_reverts() external {
_createDefaultDrip(dripName);
_notAllowFromArchive(dripName, Drippie.DripStatus.ACTIVE);
......@@ -361,7 +361,7 @@ contract Drippie_Test is Test {
/**
* @notice Attempt to update a drip that does not exist.
*/
function test_name_not_exist_fails() external {
function test_name_notExist_reverts() external {
string memory otherName = "bar";
vm.prank(drippie.owner());
......@@ -376,7 +376,7 @@ contract Drippie_Test is Test {
/**
* @notice Expect a revert when attempting to set the status when not the owner.
*/
function test_status_unauthorized_fails() external {
function test_status_unauthorized_reverts() external {
_createDefaultDrip(dripName);
vm.expectRevert("UNAUTHORIZED");
......@@ -386,7 +386,7 @@ contract Drippie_Test is Test {
/**
* @notice The drip should execute and be able to transfer value.
*/
function test_drip_amount() external {
function test_drip_amount_succeeds() external {
_createDefaultDrip(dripName);
vm.prank(drippie.owner());
......@@ -418,7 +418,7 @@ contract Drippie_Test is Test {
/**
* @notice A single DripAction should be able to make a state modifying call.
*/
function test_trigger_one_function() external {
function test_trigger_oneFunction_succeeds() external {
Drippie.DripConfig memory cfg = _defaultConfig();
bytes32 key = bytes32(uint256(2));
......@@ -455,7 +455,7 @@ contract Drippie_Test is Test {
/**
* @notice Multiple drip actions should be able to be triggered with the same check.
*/
function test_trigger_two_functions() external {
function test_trigger_twoFunctions_succeeds() external {
Drippie.DripConfig memory cfg = _defaultConfig();
Drippie.DripAction[] memory actions = new Drippie.DripAction[](2);
......@@ -516,7 +516,7 @@ contract Drippie_Test is Test {
* trigger the same drip multiple times in the same interval. Then
* move forward to the next interval and it should trigger.
*/
function test_twice_in_one_interval_fails() external {
function test_twice_inOneInterval_reverts() external {
_createDefaultDrip(dripName);
vm.prank(drippie.owner());
......@@ -551,7 +551,7 @@ contract Drippie_Test is Test {
* @notice It should revert if attempting to trigger a drip that does not exist.
* Note that the drip was never created at the beginning of the test.
*/
function test_drip_not_exist_fails() external {
function test_drip_notExist_reverts() external {
vm.prank(drippie.owner());
vm.expectRevert("Drippie: selected drip does not exist or is not currently active");
......@@ -562,7 +562,7 @@ contract Drippie_Test is Test {
/**
* @notice The owner cannot trigger the drip when it is paused.
*/
function test_not_active_fails() external {
function test_not_active_reverts() external {
_createDefaultDrip(dripName);
Drippie.DripStatus status = drippie.dripStatus(dripName);
......@@ -598,7 +598,7 @@ contract Drippie_Test is Test {
* @notice A non zero interval when reentrant is true will cause a revert
* when creating a drip.
*/
function test_reentrant_fails() external {
function test_drip_reentrant_reverts() external {
address owner = drippie.owner();
Drippie.DripConfig memory cfg = _defaultConfig();
cfg.reentrant = true;
......@@ -614,7 +614,7 @@ contract Drippie_Test is Test {
* @notice If reentrant is false and the interval is 0 then it should
* revert when the drip is created.
*/
function test_non_reentrant_zero_interval_fails() external {
function test_notReentrant_zeroInterval_reverts() external {
address owner = drippie.owner();
Drippie.DripConfig memory cfg = _defaultConfig();
cfg.reentrant = false;
......
......@@ -2,9 +2,9 @@
pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol";
import { Faucet } from "../universal/faucet/Faucet.sol";
import { AdminFaucetAuthModule } from "../universal/faucet/authmodules/AdminFaucetAuthModule.sol";
import { FaucetHelper } from "../testing/helpers/FaucetHelper.sol";
import { Faucet } from "../periphery/faucet/Faucet.sol";
import { AdminFaucetAuthModule } from "../periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
import { FaucetHelper } from "./Helpers.sol";
contract Faucet_Initializer is Test {
event Drip(
......@@ -126,7 +126,7 @@ contract Faucet_Initializer is Test {
}
contract FaucetTest is Faucet_Initializer {
function test_initialize() external {
function test_initialize_succeeds() external {
assertEq(faucet.ADMIN(), faucetContractAdmin);
}
......@@ -181,7 +181,7 @@ contract FaucetTest is Faucet_Initializer {
);
}
function test_drip_optimistNft_sendsCorrectAmount() external {
function test_drip_optimistNftSendsCorrectAmount_succeeds() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
......@@ -213,7 +213,7 @@ contract FaucetTest is Faucet_Initializer {
);
}
function test_drip_github_sendsCorrectAmount() external {
function test_drip_githubSendsCorrectAmount_succeeds() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
......@@ -241,7 +241,7 @@ contract FaucetTest is Faucet_Initializer {
);
}
function test_drip_emitsEvent() external {
function test_drip_emitsEvent_succeeds() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
......@@ -300,7 +300,7 @@ contract FaucetTest is Faucet_Initializer {
vm.stopPrank();
}
function test_drip_preventsReplayAttacks() external {
function test_drip_preventsReplayAttacks_succeeds() external {
_enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain(
......@@ -423,7 +423,7 @@ contract FaucetTest is Faucet_Initializer {
vm.stopPrank();
}
function test_withdraw_nonAdmin_fails() external {
function test_withdraw_nonAdmin_reverts() external {
vm.prank(nonAdmin);
vm.expectRevert("Faucet: function can only be called by admin");
faucet.withdraw(payable(fundsReceiver), 2 ether);
......
//SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
pragma solidity ^0.8.0;
import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol";
import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol";
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { OptimistInviter } from "../periphery/op-nft/OptimistInviter.sol";
import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import {
ECDSAUpgradeable
} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import { AdminFaucetAuthModule } from "../periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
import { OptimistInviter } from "../../universal/op-nft/OptimistInviter.sol";
contract TestERC20 is ERC20 {
constructor() ERC20("TEST", "TST", 18) {}
function mint(address to, uint256 value) public {
_mint(to, value);
}
}
contract TestERC721 is ERC721 {
constructor() ERC721("TEST", "TST") {}
function mint(address to, uint256 tokenId) public {
_mint(to, tokenId);
}
function tokenURI(uint256) public pure virtual override returns (string memory) {}
}
contract CallRecorder {
struct CallInfo {
address sender;
bytes data;
uint256 gas;
uint256 value;
}
CallInfo public lastCall;
function record() public payable {
lastCall.sender = msg.sender;
lastCall.data = msg.data;
lastCall.gas = gasleft();
lastCall.value = msg.value;
}
}
contract Reverter {
function doRevert() public pure {
revert("Reverter reverted");
}
}
contract SimpleStorage {
mapping(bytes32 => bytes32) public db;
function set(bytes32 _key, bytes32 _value) public payable {
db[_key] = _value;
}
function get(bytes32 _key) public view returns (bytes32) {
return db[_key];
}
}
/**
* Simple helper contract that helps with testing flow and signature for OptimistInviter contract.
......@@ -144,3 +205,106 @@ contract OptimistInviterHelper {
ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite));
}
}
// solhint-disable max-line-length
/**
* Simple ERC1271 wallet that can be used to test the ERC1271 signature checker.
* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/mocks/ERC1271WalletMock.sol
*/
contract TestERC1271Wallet is Ownable, IERC1271 {
constructor(address originalOwner) {
transferOwnership(originalOwner);
}
function isValidSignature(bytes32 hash, bytes memory signature)
public
view
override
returns (bytes4 magicValue)
{
return
ECDSA.recover(hash, signature) == owner() ? this.isValidSignature.selector : bytes4(0);
}
}
/**
* Simple helper contract that helps with testing the Faucet contract.
*/
contract FaucetHelper {
/**
* @notice EIP712 typehash for the Proof type.
*/
bytes32 public constant PROOF_TYPEHASH =
keccak256("Proof(address recipient,bytes32 nonce,bytes32 id)");
/**
* @notice EIP712 typehash for the EIP712Domain type that is included as part of the signature.
*/
bytes32 public constant EIP712_DOMAIN_TYPEHASH =
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
/**
* @notice Keeps track of current nonce to generate new nonces for each drip.
*/
uint256 public currentNonce;
/**
* @notice Returns a bytes32 nonce that should change everytime. In practice, people should use
* pseudorandom nonces.
*
* @return Nonce that should be used as part of drip parameters.
*/
function consumeNonce() public returns (bytes32) {
return bytes32(keccak256(abi.encode(currentNonce++)));
}
/**
* @notice Returns the hash of the struct Proof.
*
* @param _proof Proof struct to hash.
*
* @return EIP-712 typed struct hash.
*/
function getProofStructHash(AdminFaucetAuthModule.Proof memory _proof)
public
pure
returns (bytes32)
{
return keccak256(abi.encode(PROOF_TYPEHASH, _proof.recipient, _proof.nonce, _proof.id));
}
/**
* @notice Computes the EIP712 digest with the given domain parameters.
* Used for testing that different domain parameters fail.
*
* @param _proof Proof struct to hash.
* @param _name Contract name to use in the EIP712 domain.
* @param _version Contract version to use in the EIP712 domain.
* @param _chainid Chain ID to use in the EIP712 domain.
* @param _verifyingContract Address to use in the EIP712 domain.
* @param _verifyingContract Address to use in the EIP712 domain.
* @param _verifyingContract Address to use in the EIP712 domain.
*
* @return EIP-712 compatible digest.
*/
function getDigestWithEIP712Domain(
AdminFaucetAuthModule.Proof memory _proof,
bytes memory _name,
bytes memory _version,
uint256 _chainid,
address _verifyingContract
) public pure returns (bytes32) {
bytes32 domainSeparator = keccak256(
abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(_name),
keccak256(_version),
_chainid,
_verifyingContract
)
);
return ECDSAUpgradeable.toTypedDataHash(domainSeparator, getProofStructHash(_proof));
}
}
......@@ -3,11 +3,11 @@ pragma solidity 0.8.15;
/* Testing utilities */
import { Test } from "forge-std/Test.sol";
import { AttestationStation } from "../universal/op-nft/AttestationStation.sol";
import { OptimistAllowlist } from "../universal/op-nft/OptimistAllowlist.sol";
import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol";
import { OptimistInviterHelper } from "../testing/helpers/OptimistInviterHelper.sol";
import { OptimistConstants } from "../universal/op-nft/libraries/OptimistConstants.sol";
import { AttestationStation } from "../periphery/op-nft/AttestationStation.sol";
import { OptimistAllowlist } from "../periphery/op-nft/OptimistAllowlist.sol";
import { OptimistInviter } from "../periphery/op-nft/OptimistInviter.sol";
import { OptimistInviterHelper } from "./Helpers.sol";
import { OptimistConstants } from "../periphery/op-nft/libraries/OptimistConstants.sol";
contract OptimistAllowlist_Initializer is Test {
event AttestationCreated(
......
......@@ -3,13 +3,13 @@ pragma solidity 0.8.15;
/* Testing utilities */
import { Test } from "forge-std/Test.sol";
import { AttestationStation } from "../universal/op-nft/AttestationStation.sol";
import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol";
import { Optimist } from "../universal/op-nft/Optimist.sol";
import { AttestationStation } from "../periphery/op-nft/AttestationStation.sol";
import { OptimistInviter } from "../periphery/op-nft/OptimistInviter.sol";
import { Optimist } from "../periphery/op-nft/Optimist.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { TestERC1271Wallet } from "../testing/helpers/TestERC1271Wallet.sol";
import { OptimistInviterHelper } from "../testing/helpers/OptimistInviterHelper.sol";
import { OptimistConstants } from "../universal/op-nft/libraries/OptimistConstants.sol";
import { TestERC1271Wallet } from "./Helpers.sol";
import { OptimistInviterHelper } from "./Helpers.sol";
import { OptimistConstants } from "../periphery/op-nft/libraries/OptimistConstants.sol";
contract OptimistInviter_Initializer is Test {
event InviteClaimed(address indexed issuer, address indexed claimer);
......@@ -260,7 +260,7 @@ contract OptimistInviter_Initializer is Test {
}
contract OptimistInviterTest is OptimistInviter_Initializer {
function test_initialize() external {
function test_initialize_succeeds() external {
// expect attestationStation to be set
assertEq(address(optimistInviter.ATTESTATION_STATION()), address(attestationStation));
assertEq(optimistInviter.INVITE_GRANTER(), alice_inviteGranter);
......
......@@ -3,9 +3,9 @@ pragma solidity 0.8.15;
/* Testing utilities */
import { Test } from "forge-std/Test.sol";
import { CallRecorder } from "../testing/helpers/CallRecorder.sol";
import { Reverter } from "../testing/helpers/Reverter.sol";
import { Transactor } from "../universal/Transactor.sol";
import { CallRecorder } from "./Helpers.sol";
import { Reverter } from "./Helpers.sol";
import { Transactor } from "../periphery/Transactor.sol";
contract Transactor_Initializer is Test {
address alice = address(128);
......@@ -35,12 +35,12 @@ contract Transactor_Initializer is Test {
contract TransactorTest is Transactor_Initializer {
// Tests if the owner was set correctly during deploy
function test_constructor() external {
function test_constructor_succeeds() external {
assertEq(address(alice), transactor.owner());
}
// Tests CALL, should do a call to target
function test_CALL() external {
function test_call_succeeds() external {
// Initialize call data
bytes memory data = abi.encodeWithSelector(callRecorded.record.selector);
// Run CALL
......@@ -50,16 +50,16 @@ contract TransactorTest is Transactor_Initializer {
}
// It should revert if called by non-owner
function testFail_CALL() external {
function test_call_unauthorized_reverts() external {
// Initialize call data
bytes memory data = abi.encodeWithSelector(callRecorded.record.selector);
// Run CALL
vm.prank(bob);
transactor.CALL(address(callRecorded), data, 200_000 wei);
vm.expectRevert("UNAUTHORIZED");
transactor.CALL(address(callRecorded), data, 200_000 wei);
}
function test_DELEGATECALL() external {
function test_delegateCall_succeeds() external {
// Initialize call data
bytes memory data = abi.encodeWithSelector(reverter.doRevert.selector);
// Run CALL
......@@ -69,12 +69,12 @@ contract TransactorTest is Transactor_Initializer {
}
// It should revert if called by non-owner
function testFail_DELEGATECALLL() external {
function test_delegateCall_unauthorized_reverts() external {
// Initialize call data
bytes memory data = abi.encodeWithSelector(reverter.doRevert.selector);
// Run CALL
vm.prank(bob);
transactor.DELEGATECALL(address(reverter), data);
vm.expectRevert("UNAUTHORIZED");
transactor.DELEGATECALL(address(reverter), data);
}
}
......@@ -107,7 +107,7 @@ const main = async () => {
// Check the rest.
for (const { check, error } of checks) {
if (!check(element.name.split('_'))) {
errors.push(`${filepath} function ${element.name}: ${error}`)
errors.push(`${filepath}#${element.name}: ${error}`)
success = false
}
}
......
ignores: [
"@eth-optimism/contracts-bedrock",
"@openzeppelin/contracts",
"@openzeppelin/contracts-upgradeable",
"@ethersproject/providers",
"@ethersproject/abi",
"@rari-capital/solmate",
"@types/node",
"hardhat-deploy",
"ts-node",
"typescript",
"prettier-plugin-solidity",
"solhint-plugin-prettier",
"@babel/eslint-parser",
"@typescript-eslint/parser",
"eslint-plugin-import",
"eslint-plugin-unicorn",
"eslint-plugin-jsdoc",
"eslint-plugin-prefer-arrow",
"eslint-plugin-react",
"mkdirp",
"@typescript-eslint/eslint-plugin",
"eslint-config-prettier",
"eslint-plugin-prettier",
"chai",
"babel-eslint",
"ds-test",
"forge-std"
]
# Etherscan API key for Ethereum and Ethereum testnets
ETHEREUM_ETHERSCAN_API_KEY=
# Etherscan API key for Optimism and Optimism testnets
OPTIMISTIC_ETHERSCAN_API_KEY=
# Insert your Ledger address here if using a Ledger to deploy
LEDGER_ADDRESS=
# Alternatively you can use a private key, but leave Ledger blank if so
PRIVATE_KEY=
# Required to deploy to Ethereum or Ethereum testnets
INFURA_PROJECT_ID=
module.exports = {
extends: '../../.eslintrc.js',
}
AssetReceiverTest:testFail_withdrawERC20() (gas: 199012)
AssetReceiverTest:testFail_withdrawERC20withAmount() (gas: 199092)
AssetReceiverTest:testFail_withdrawERC721() (gas: 55908)
AssetReceiverTest:testFail_withdrawETH() (gas: 10457)
AssetReceiverTest:testFail_withdrawETHwithAmount() (gas: 10594)
AssetReceiverTest:test_constructor() (gas: 9794)
AssetReceiverTest:test_receive() (gas: 21010)
AssetReceiverTest:test_withdrawERC20() (gas: 185529)
AssetReceiverTest:test_withdrawERC20withAmount() (gas: 184609)
AssetReceiverTest:test_withdrawERC721() (gas: 51565)
AssetReceiverTest:test_withdrawETH() (gas: 28774)
AssetReceiverTest:test_withdrawETHwithAmount() (gas: 28703)
AssetReceiverTest:test_attest_bulk() (gas: 611417)
AssetReceiverTest:test_attest_individual() (gas: 538536)
AssetReceiverTest:test_attest_single() (gas: 558939)
CheckBalanceHighTest:testFuzz_check_fails(address,uint256) (runs: 256, μ: 12352, ~: 12382)
CheckBalanceHighTest:testFuzz_check_succeeds(address,uint256) (runs: 256, μ: 10284, ~: 10284)
CheckBalanceLowTest:testFuzz_check_fails(address,uint256) (runs: 256, μ: 10262, ~: 10262)
CheckBalanceLowTest:testFuzz_check_succeeds(address,uint256) (runs: 256, μ: 12374, ~: 12404)
CheckGelatoLowTest:testFuzz_check_fails(uint256,address) (runs: 256, μ: 34938, ~: 35871)
CheckGelatoLowTest:testFuzz_check_succeeds(uint256,address) (runs: 256, μ: 18800, ~: 18800)
CheckTrueTest:testFuzz_always_true_succeeds(bytes) (runs: 256, μ: 6539, ~: 6486)
Drippie_Test:testFuzz_fails_unauthorized(address) (runs: 256, μ: 17073, ~: 17073)
Drippie_Test:test_create_fails_twice() (gas: 169499)
Drippie_Test:test_create_success() (gas: 184013)
Drippie_Test:test_drip_amount() (gas: 286156)
Drippie_Test:test_drip_not_exist_fails() (gas: 15136)
Drippie_Test:test_name_not_exist_fails() (gas: 16157)
Drippie_Test:test_non_reentrant_zero_interval_fails() (gas: 19090)
Drippie_Test:test_not_active_fails() (gas: 171861)
Drippie_Test:test_reentrant_fails() (gas: 19129)
Drippie_Test:test_reentrant_succeeds() (gas: 180769)
Drippie_Test:test_set_status_none_fails() (gas: 169439)
Drippie_Test:test_set_status_same_fails() (gas: 169939)
Drippie_Test:test_set_status_success() (gas: 199270)
Drippie_Test:test_should_archive_if_paused_success() (gas: 177922)
Drippie_Test:test_should_not_allow_active_if_archived_fails() (gas: 175362)
Drippie_Test:test_should_not_allow_paused_if_archived_fails() (gas: 175383)
Drippie_Test:test_should_not_archive_if_active_fails() (gas: 176512)
Drippie_Test:test_status_unauthorized_fails() (gas: 167971)
Drippie_Test:test_trigger_one_function() (gas: 339137)
Drippie_Test:test_trigger_two_functions() (gas: 493184)
Drippie_Test:test_twice_in_one_interval_fails() (gas: 305202)
OptimistTest:test_optimist_baseURI() (gas: 116809)
OptimistTest:test_optimist_burn() (gas: 77526)
OptimistTest:test_optimist_initialize() (gas: 23095)
OptimistTest:test_optimist_is_on_allow_list() (gas: 52616)
OptimistTest:test_optimist_mint_already_minted() (gas: 98823)
OptimistTest:test_optimist_mint_happy_path() (gas: 99175)
OptimistTest:test_optimist_mint_no_attestation() (gas: 15897)
OptimistTest:test_optimist_mint_secondary_minter() (gas: 100576)
OptimistTest:test_optimist_sbt_approve() (gas: 97284)
OptimistTest:test_optimist_sbt_transfer() (gas: 102331)
OptimistTest:test_optimist_set_approval_for_all() (gas: 100907)
OptimistTest:test_optimist_supports_interface() (gas: 5797)
OptimistTest:test_optimist_token_id_of_owner() (gas: 95045)
OptimistTest:test_optimist_token_uri() (gas: 213972)
TransactorTest:testFail_CALL() (gas: 15636)
TransactorTest:testFail_DELEGATECALLL() (gas: 15632)
TransactorTest:test_CALL() (gas: 26969)
TransactorTest:test_DELEGATECALL() (gas: 21189)
TransactorTest:test_constructor() (gas: 9772)
"*.{ts,js}":
- eslint
"*.sol":
- pnpm solhint -f table
module.exports = {
...require('../../.prettierrc.js'),
}
module.exports = {
skipFiles: [
'./test-libraries',
'./foundry-tests',
'./testing'
],
mocha: {
grep: "@skip-on-coverage",
invert: true
}
};
{
"extends": "solhint:recommended",
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"compiler-version": "off",
"code-complexity": ["warn", 5],
"max-line-length": ["error", 100],
"func-param-name-mixedcase": "error",
"modifier-name-mixedcase": "error",
"ordering": "warn",
"not-rely-on-time": "off",
"no-complex-fallback": "off",
"not-rely-on-block-hash": "off",
"reentrancy": "off",
"contract-name-camelcase": "off"
}
}
node_modules
contracts/foundry-tests/*.t.sol
# @eth-optimism/contracts-periphery
## 1.0.8
### Patch Changes
- 2129dafa3: Add faucet contract
- 188d1e930: Change type for auth id on Faucet contracts from bytes to bytes32
## 1.0.7
### Patch Changes
- 4c64a5811: Update the attestation station impl to 1.1.0
## 1.0.6
### Patch Changes
- 0222215f6: Manually update the version on the contracts-bedrock dep.
## 1.0.5
### Patch Changes
- fe8f2afd0: Minor fix to AttestationStation test
- 886fec5bb: Add attestation contracts
- 596d51852: Update zeppelin deps in contracts periphery
- c12aeb2f9: Add deploy script for attestations tation
- a610b4f3b: Make zeppelin deps in contracts periphery not get hoisted
- 55515ba14: Add some default options to optimist config
- bf5f9febd: Add authors to optimist contracts
- 9a996a13c: Make deploy scripts a little safer
- 09924e8ed: Add test coverage script to contracts periphery
- 746ce5545: Add deployment scripts for optimist
- 0e0546a11: Add optimist contract
## 1.0.4
### Patch Changes
- 1d3c749a2: Bumps the version of ts-node used
## 1.0.3
### Patch Changes
- f49b71d50: Updated forge-std version
## 1.0.2
### Patch Changes
- e81a6ff5: Goerli nft bridge deployment
- a3242d4f: Fix erc721 factory to match erc21 factory
- ffa5297e: mainnet nft bridge deployments
## 1.0.1
### Patch Changes
- 02c457a5: Removes NFT refund logic if withdrawals fail.
- d3fe9b6d: Adds input validation to the ERC721Bridge constructor, fixes a typo in the L1ERC721Bridge, and removes the ERC721Refunded event declaration.
- 220ad4ef: Remove ownable upgradable from erc721 factory
- 5d86ff0e: Increased solc version on drip checks to 0.8.16.
## 1.0.0
### Major Changes
- 5c3f2b1f: Fixes NFT bridge related contracts in response to the OpenZeppelin audit. Updates tests to support these changes, including integration tests.
### Patch Changes
- 3883f34b: Remove ERC721Refunded events
## 0.2.4
### Patch Changes
- 7215f4ce: Bump ethers to 5.7.0 globally
- 0ceff8b8: Drippie Spearbit audit fix for issues #32 and #33, clarify behavior of executable function
- 0ceff8b8: Drippie Spearbit audit fix for issue #25, reorder DripStatus enum for clarity
- 0ceff8b8: Drippie Spearbit audit fix for issue #44, document drip count and increment before external calls
- 0ceff8b8: Drippie Spearbit audit fix for issue 24, use call over transfer for withdrawETH
- 0ceff8b8: Drippie Spearbit audit fix for issue 22, remove unnecessary gas parameter
- 0ceff8b8: Drippie Spearbit audit fix for issue #34, missing natspec
- 0ceff8b8: Drippie Spearbit audit fix for issue #28, document dripcheck behavior in drip function
- 0ceff8b8: Drippie Spearbit audit fix #42, remove unnecessary SLOADs in the status function
- 0ceff8b8: Drippie Spearbit audit fix for issue #39, update to latest version of Solidity
- 0ceff8b8: Drippie Spearbit audit fix for issue #21, use correct version of Solmate
- 0ceff8b8: Drippie Spearbit audit fix for issue #31, require explicit opt-in for reentrant drips
- 0ceff8b8: Drippie Spearbit audit fix for issue #45, calldata over memory to save gas
- 0ceff8b8: Drippie Spearbit audit fix for issue #35, correct contract layout ordering
## 0.2.3
### Patch Changes
- f4bf4f52: Fixes import paths in the contracts-periphery package
## 0.2.2
### Patch Changes
- ea371af2: Support deploy via Ledger or private key
## 0.2.1
### Patch Changes
- 93d3bd41: Update compiler version to 0.8.15
- bcfd1edc: Add compiler 0.8.15
- 0bf3b9b4: Update forge-std
## 0.2.0
### Minor Changes
- 8a335b7b: Fixes a bug in the OptimismMintableERC721. Requires an interface change, so this is a minor and not patch.
### Patch Changes
- 95fc3fbf: Add typechain with ethers v5 support
- 019657db: Add TeleportrDeposit and TeleportrDisburser to contracts-periphery
- 6ff5c0a3: Cleaned up natspec for Drippie and its dependencies
- 119f0e97: Moves TeleportrWithdrawer to L1 contracts folder
- 9c8b1f00: Bump forge-std to 62caef29b0f87a2c6aaaf634b2ca4c09b6867c92
- 89d01f2e: Update dev deps
## 0.1.5
### Patch Changes
- 3799bb6f: Deploy Drippie to mainnet
## 0.1.4
### Patch Changes
- 9aa8049c: Deploy NFT bridge contracts
## 0.1.3
### Patch Changes
- da1633a3: ERC721 bridge from Eth Mainnet to Optimism
- 61a30273: Simplify, cleanup, and standardize ERC721 bridge contracts.
- a320e744: Updates contracts-periphery to use the standardized hardhat deploy config plugin
- 29ff7462: Revert es target back to 2017
- 604dd315: Deploy Drippie to kovan and OP kovan
## 0.1.2
### Patch Changes
- e0b89fcd: Re-deploy RetroReceiver
- 982cb980: Tweaks Drippie contract for client-side ease
- 9142adc4: Adds new TeleportrWithdrawer contract for withdrawing from Teleportr
## 0.1.1
### Patch Changes
- 416d2e60: Introduce the Drippie peripheral contract for managing ETH drips
## 0.1.0
### Minor Changes
- f7d964d7: Releases the first version of the contracts-periphery package
### Patch Changes
- d18ae135: Updates all ethers versions in response to BN.js bug
- Updated dependencies [d18ae135]
- @eth-optimism/core-utils@0.8.5
(The MIT License)
Copyright 2020-2021 Optimism
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Optimism Peripheral Smart Contracts
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=contracts-periphery-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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