Commit b070e29e authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into aj/enable-p2p-sync

parents 5feb52c0 d1979617
---
'@eth-optimism/chain-mon': patch
---
Update import path for artifact
---
'@eth-optimism/contracts-bedrock': minor
---
Migrate contracts periphery into bedrock
...@@ -115,10 +115,19 @@ jobs: ...@@ -115,10 +115,19 @@ jobs:
name: Restore PNPM Package Cache name: Restore PNPM Package Cache
keys: keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: Install dependencies name: Install dependencies
command: pnpm install --frozen-lockfile command: pnpm install --frozen-lockfile
...@@ -130,10 +139,8 @@ jobs: ...@@ -130,10 +139,8 @@ jobs:
- "packages/chain-mon/node_modules" - "packages/chain-mon/node_modules"
- "packages/common-ts/node_modules" - "packages/common-ts/node_modules"
- "packages/contracts-bedrock/node_modules" - "packages/contracts-bedrock/node_modules"
- "packages/contracts-periphery/node_modules"
- "packages/core-utils/node_modules" - "packages/core-utils/node_modules"
- "packages/fault-detector/node_modules" - "packages/fault-detector/node_modules"
- "packages/hardhat-deploy-config/node_modules"
- "packages/replica-healthcheck/node_modules" - "packages/replica-healthcheck/node_modules"
- "packages/sdk/node_modules" - "packages/sdk/node_modules"
- run: - run:
...@@ -334,11 +341,20 @@ jobs: ...@@ -334,11 +341,20 @@ jobs:
keys: keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,hardhat-deploy-config patterns: contracts-bedrock
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: print forge version name: print forge version
command: forge --version command: forge --version
...@@ -368,11 +384,20 @@ jobs: ...@@ -368,11 +384,20 @@ jobs:
keys: keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,hardhat-deploy-config patterns: contracts-bedrock
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: print forge version name: print forge version
command: forge --version command: forge --version
...@@ -395,11 +420,20 @@ jobs: ...@@ -395,11 +420,20 @@ jobs:
keys: keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,hardhat-deploy-config patterns: contracts-bedrock
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: lint name: lint
command: | command: |
...@@ -471,11 +505,20 @@ jobs: ...@@ -471,11 +505,20 @@ jobs:
keys: keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,hardhat-deploy-config patterns: contracts-bedrock
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: slither name: slither
command: | command: |
...@@ -496,11 +539,20 @@ jobs: ...@@ -496,11 +539,20 @@ jobs:
keys: keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,hardhat-deploy-config patterns: contracts-bedrock
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: validate spacers name: validate spacers
command: pnpm validate-spacers command: pnpm validate-spacers
...@@ -514,10 +566,19 @@ jobs: ...@@ -514,10 +566,19 @@ jobs:
- attach_workspace: { at: "." } - attach_workspace: { at: "." }
- check-changed: - check-changed:
patterns: contracts-bedrock,contracts patterns: contracts-bedrock,contracts
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: Compile with metadata hash name: Compile with metadata hash
command: pnpm clean && pnpm build:with-metadata command: pnpm clean && pnpm build:with-metadata
...@@ -549,10 +610,19 @@ jobs: ...@@ -549,10 +610,19 @@ jobs:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,contracts patterns: contracts-bedrock,contracts
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: Echidna Fuzz <<parameters.echidna_target>> name: Echidna Fuzz <<parameters.echidna_target>>
command: pnpm echidna:<<parameters.echidna_target>> command: pnpm echidna:<<parameters.echidna_target>>
...@@ -572,10 +642,19 @@ jobs: ...@@ -572,10 +642,19 @@ jobs:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: contracts-bedrock,op-bindings patterns: contracts-bedrock,op-bindings
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: check go bindings name: check go bindings
command: make && git diff --exit-code command: make && git diff --exit-code
...@@ -605,10 +684,19 @@ jobs: ...@@ -605,10 +684,19 @@ jobs:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: <<parameters.package_name>>,<<parameters.dependencies>> patterns: <<parameters.package_name>>,<<parameters.dependencies>>
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: Lint name: Lint
command: pnpm lint && git diff --exit-code command: pnpm lint && git diff --exit-code
...@@ -678,10 +766,19 @@ jobs: ...@@ -678,10 +766,19 @@ jobs:
- checkout - checkout
- check-changed: - check-changed:
patterns: specs/(.*)\.md$ patterns: specs/(.*)\.md$
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
- run: - run:
name: pnpm dev deps name: pnpm dev deps
command: pnpm install command: pnpm install
...@@ -697,6 +794,7 @@ jobs: ...@@ -697,6 +794,7 @@ jobs:
image: ubuntu-2204:2022.07.1 image: ubuntu-2204:2022.07.1
steps: steps:
- checkout - checkout
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
...@@ -754,20 +852,25 @@ jobs: ...@@ -754,20 +852,25 @@ jobs:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }} - pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed: - check-changed:
patterns: packages patterns: packages
# TODO remove me after ci builder updated
- run: - run:
name: Install pnpm package manager name: Install pnpm package manager
command: | command: |
npm i pnpm --global npm i pnpm --global
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install yarn package manager
command: |
npm i yarn@1 --global
# Note: The below needs to be manually configured whenever we # Note: The below needs to be manually configured whenever we
# add a new package to CI. # add a new package to CI.
- run: - run:
name: Check common-ts name: Check common-ts
command: npx depcheck command: npx depcheck
working_directory: packages/common-ts working_directory: packages/common-ts
- run:
name: Check contracts-periphery
command: npx depcheck
working_directory: packages/contracts-periphery
- run: - run:
name: Check core-utils name: Check core-utils
command: npx depcheck command: npx depcheck
...@@ -921,15 +1024,32 @@ jobs: ...@@ -921,15 +1024,32 @@ jobs:
source $HOME/.bashrc source $HOME/.bashrc
foundryup foundryup
echo 'export PATH=$HOME/.foundry/bin:$PATH' >> $BASH_ENV echo 'export PATH=$HOME/.foundry/bin:$PATH' >> $BASH_ENV
source $HOME/.bashrc
forge --version
- run: - run:
name: Install pnpm package manager name: Install NVM
command: |
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
source ~/.bashrc
nvm --version
- run:
name: Install Node
command: |
nvm install
nvm use && node --version && npm --version
# TODO remove me after ci builder updated
# A github dep clones-with-immutable-args is installed via github
# packages installed via npm via github automatically run postpack scripts
# their postpack script happens to use yarn so we need it here
- run:
name: Install Package managers
command: | command: |
npm i pnpm --global npm i pnpm --global
npm i yarn@1 --global
- run: - run:
name: Install and build name: Install and build
command: | command: |
pnpm install pnpm install && pnpm build
pnpm build
- when: - when:
condition: condition:
and: and:
...@@ -1202,18 +1322,11 @@ workflows: ...@@ -1202,18 +1322,11 @@ workflows:
- op-bindings-build: - op-bindings-build:
requires: requires:
- pnpm-monorepo - 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: - js-lint-test:
name: chain-mon-tests name: chain-mon-tests
coverage_flag: chain-mon-tests coverage_flag: chain-mon-tests
package_name: chain-mon package_name: chain-mon
dependencies: "(common-ts|contracts-periphery|core-utils|sdk)" dependencies: "(common-ts|contracts-bedrock|core-utils|sdk)"
requires: requires:
- pnpm-monorepo - pnpm-monorepo
- js-lint-test: - js-lint-test:
......
...@@ -2,11 +2,9 @@ ...@@ -2,11 +2,9 @@
/packages/common-ts @ethereum-optimism/typescript-reviewers /packages/common-ts @ethereum-optimism/typescript-reviewers
/packages/contracts @ethereum-optimism/contract-reviewers /packages/contracts @ethereum-optimism/contract-reviewers
/packages/contracts-bedrock @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/core-utils @ethereum-optimism/legacy-reviewers
/packages/chain-mon @smartcontracts /packages/chain-mon @smartcontracts
/packages/fault-detector @ethereum-optimism/devxpod /packages/fault-detector @ethereum-optimism/devxpod
/packages/hardhat-deploy-config @ethereum-optimism/legacy-reviewers
/packages/replica-healthcheck @ethereum-optimism/legacy-reviewers /packages/replica-healthcheck @ethereum-optimism/legacy-reviewers
/packages/sdk @ethereum-optimism/devxpod /packages/sdk @ethereum-optimism/devxpod
/packages/atst @ethereum-optimism/devxpod /packages/atst @ethereum-optimism/devxpod
......
...@@ -17,11 +17,6 @@ dist ...@@ -17,11 +17,6 @@ dist
artifacts artifacts
cache 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/devnetL1
packages/contracts-bedrock/deployments/anvil 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 @@ ...@@ -16,10 +16,6 @@
"directory": "packages/contracts", "directory": "packages/contracts",
"changeProcessCWD": true "changeProcessCWD": true
}, },
{
"directory": "packages/contracts-periphery",
"changeProcessCWD": true
},
{ {
"directory": "packages/chain-mon", "directory": "packages/chain-mon",
"changeProcessCWD": true "changeProcessCWD": true
......
...@@ -52,7 +52,6 @@ Refer to the Directory Structure section below to understand which packages are ...@@ -52,7 +52,6 @@ Refer to the Directory Structure section below to understand which packages are
├── <a href="./packages">packages</a> ├── <a href="./packages">packages</a>
│ ├── <a href="./packages/common-ts">common-ts</a>: Common tools for building apps in TypeScript │ ├── <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-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/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/chain-mon">chain-mon</a>: Chain monitoring services
│ ├── <a href="./packages/fault-detector">fault-detector</a>: Service for detecting Sequencer faults │ ├── <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 ...@@ -79,7 +78,6 @@ Refer to the Directory Structure section below to understand which packages are
~~ Pre-BEDROCK ~~ ~~ Pre-BEDROCK ~~
├── <a href="./packages">packages</a> ├── <a href="./packages">packages</a>
│ ├── <a href="./packages/common-ts">common-ts</a>: Common tools for building apps in TypeScript │ ├── <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/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/chain-mon">chain-mon</a>: Chain monitoring services
│ ├── <a href="./packages/fault-detector">fault-detector</a>: Service for detecting Sequencer faults │ ├── <a href="./packages/fault-detector">fault-detector</a>: Service for detecting Sequencer faults
......
...@@ -33,7 +33,6 @@ flag_management: ...@@ -33,7 +33,6 @@ flag_management:
- name: common-ts-tests - name: common-ts-tests
- name: contracts-tests - name: contracts-tests
- name: core-utils-tests - name: core-utils-tests
- name: contracts-periphery-tests
- name: dtl-tests - name: dtl-tests
- name: chain-mon-tests - name: chain-mon-tests
- name: fault-detector-tests - name: fault-detector-tests
......
SHELL := /bin/bash SHELL := /bin/bash
pkg := bindings pkg := bindings
contracts-dir := ../packages/contracts-bedrock monorepo-base := $(shell dirname $(realpath .))
contracts-dir := $(monorepo-base)/packages/contracts-bedrock
all: version mkdir bindings all: version mkdir bindings
...@@ -17,11 +18,12 @@ bindings: compile bindings-build ...@@ -17,11 +18,12 @@ bindings: compile bindings-build
bindings-build: bindings-build:
go run ./gen/main.go \ go run ./gen/main.go \
-forge-artifacts ../packages/contracts-bedrock/forge-artifacts \ -forge-artifacts $(contracts-dir)/forge-artifacts \
-out ./bindings \ -out ./bindings \
-contracts ./artifacts.json \ -contracts ./artifacts.json \
-source-maps MIPS,PreimageOracle \ -source-maps MIPS,PreimageOracle \
-package $(pkg) -package $(pkg) \
-monorepo-base $(monorepo-base)
mkdir: mkdir:
mkdir -p $(pkg) mkdir -p $(pkg)
......
package ast package ast
import ( import (
"path/filepath"
"regexp" "regexp"
"sort" "sort"
"strconv" "strconv"
...@@ -33,7 +34,7 @@ type typeRemapping struct { ...@@ -33,7 +34,7 @@ type typeRemapping struct {
// inefficiency comes from replaceType, which performs a linear // inefficiency comes from replaceType, which performs a linear
// search of all replacements when performing substring matches of // search of all replacements when performing substring matches of
// composite types. // composite types.
func CanonicalizeASTIDs(in *solc.StorageLayout) *solc.StorageLayout { func CanonicalizeASTIDs(in *solc.StorageLayout, monorepoBase string) *solc.StorageLayout {
lastId := uint(1000) lastId := uint(1000)
astIDRemappings := make(map[uint]uint) astIDRemappings := make(map[uint]uint)
typeRemappings := make(map[string]string) typeRemappings := make(map[string]string)
...@@ -83,9 +84,18 @@ func CanonicalizeASTIDs(in *solc.StorageLayout) *solc.StorageLayout { ...@@ -83,9 +84,18 @@ func CanonicalizeASTIDs(in *solc.StorageLayout) *solc.StorageLayout {
Types: make(map[string]solc.StorageLayoutType), Types: make(map[string]solc.StorageLayoutType),
} }
for _, slot := range in.Storage { 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{ outLayout.Storage = append(outLayout.Storage, solc.StorageLayoutEntry{
AstId: astIDRemappings[slot.AstId], AstId: astIDRemappings[slot.AstId],
Contract: slot.Contract, Contract: contract,
Label: slot.Label, Label: slot.Label,
Offset: slot.Offset, Offset: slot.Offset,
Slot: slot.Slot, Slot: slot.Slot,
......
...@@ -49,7 +49,7 @@ func TestCanonicalize(t *testing.T) { ...@@ -49,7 +49,7 @@ func TestCanonicalize(t *testing.T) {
// Run 100 times to make sure that we aren't relying // Run 100 times to make sure that we aren't relying
// on random map iteration order. // on random map iteration order.
for i := 0; i < 100; i++ { 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 ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "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) var ERC20StorageLayout = new(solc.StorageLayout)
......
...@@ -31,7 +31,7 @@ var ( ...@@ -31,7 +31,7 @@ var (
// FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract. // FaultDisputeGameMetaData contains all meta data concerning the FaultDisputeGame contract.
var FaultDisputeGameMetaData = &bind.MetaData{ var FaultDisputeGameMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"Claim\",\"name\":\"_absolutePrestate\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxGameDepth\",\"type\":\"uint256\"},{\"internalType\":\"contractIBigStepper\",\"name\":\"_vm\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotDefendRootClaim\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClaimAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockTimeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameDepthExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameNotInProgress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidParent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPrestate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValidStep\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"parentIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimant\",\"type\":\"address\"}],\"name\":\"Move\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enumGameStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"Resolved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ABSOLUTE_PRESTATE\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_GAME_DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VM\",\"outputs\":[{\"internalType\":\"contractIBigStepper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"}],\"name\":\"attack\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondManager\",\"outputs\":[{\"internalType\":\"contractIBondManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"claimData\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"parentIndex\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"countered\",\"type\":\"bool\"},{\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"internalType\":\"Position\",\"name\":\"position\",\"type\":\"uint128\"},{\"internalType\":\"Clock\",\"name\":\"clock\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimDataLen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createdAt\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"createdAt_\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"}],\"name\":\"defend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"extraData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameData\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameStart\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameType\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber_\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_challengeIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"}],\"name\":\"move\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"status_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rootClaim\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"status\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_claimIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_stateData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"}],\"name\":\"step\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", ABI: "[{\"inputs\":[{\"internalType\":\"Claim\",\"name\":\"_absolutePrestate\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_maxGameDepth\",\"type\":\"uint256\"},{\"internalType\":\"contractIBigStepper\",\"name\":\"_vm\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotDefendRootClaim\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClaimAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ClockTimeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameDepthExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GameNotInProgress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidParent\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPrestate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValidStep\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"parentIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"claimant\",\"type\":\"address\"}],\"name\":\"Move\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"enumGameStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"name\":\"Resolved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ABSOLUTE_PRESTATE\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_GAME_DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VM\",\"outputs\":[{\"internalType\":\"contractIBigStepper\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"}],\"name\":\"attack\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bondManager\",\"outputs\":[{\"internalType\":\"contractIBondManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"claimData\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"parentIndex\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"countered\",\"type\":\"bool\"},{\"internalType\":\"Claim\",\"name\":\"claim\",\"type\":\"bytes32\"},{\"internalType\":\"Position\",\"name\":\"position\",\"type\":\"uint128\"},{\"internalType\":\"Clock\",\"name\":\"clock\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimDataLen\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"len_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createdAt\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"createdAt_\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_parentIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"}],\"name\":\"defend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"extraData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameData\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"},{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"extraData_\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameStart\",\"outputs\":[{\"internalType\":\"Timestamp\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gameType\",\"outputs\":[{\"internalType\":\"GameType\",\"name\":\"gameType_\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2BlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"l2BlockNumber_\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_challengeIndex\",\"type\":\"uint256\"},{\"internalType\":\"Claim\",\"name\":\"_claim\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"}],\"name\":\"move\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"status_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rootClaim\",\"outputs\":[{\"internalType\":\"Claim\",\"name\":\"rootClaim_\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"status\",\"outputs\":[{\"internalType\":\"enumGameStatus\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_claimIndex\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_isAttack\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"_stateData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_proof\",\"type\":\"bytes\"}],\"name\":\"step\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x61014060405234801561001157600080fd5b506040516120503803806120508339810160408190526100309161005b565b6000608081905260a052600260c05260e092909252610100526001600160a01b0316610120526100a1565b60008060006060848603121561007057600080fd5b83516020850151604086015191945092506001600160a01b038116811461009657600080fd5b809150509250925092565b60805160a05160c05160e0516101005161012051611f3d610113600039600081816103aa015261140c0152600081816102c20152818161061701528181610b7501526111da0152600081816101bd01526113140152600061095d015260006109340152600061090b0152611f3d6000f3fe60806040526004361061016a5760003560e01c80638129fc1c116100cb578063bcef3b551161007f578063cf09e0d011610059578063cf09e0d01461049c578063d8cc1a3c146104bb578063fa24f743146104db57600080fd5b8063bcef3b55146103e8578063c55cd0c714610425578063c6f0308c1461043857600080fd5b80638b85902b116100b05780638b85902b146103585780639293129814610398578063bbdc02db146103cc57600080fd5b80638129fc1c1461032e5780638980e0cc1461034357600080fd5b8063363cc4271161012257806354fd4d501161010757806354fd4d50146102e4578063609d333414610306578063632247ea1461031b57600080fd5b8063363cc427146102515780634778efe8146102b057600080fd5b80632810e1d6116101535780632810e1d6146101ed5780633218b99d1461020257806335fef5671461023c57600080fd5b8063200d2ed21461016f578063266198f9146101ab575b600080fd5b34801561017b57600080fd5b506000546101959068010000000000000000900460ff1681565b6040516101a291906119e7565b60405180910390f35b3480156101b757600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101a2565b3480156101f957600080fd5b506101956104ff565b34801561020e57600080fd5b506000546102239067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101a2565b61024f61024a366004611a28565b6108f4565b005b34801561025d57600080fd5b5060005461028b906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b3480156102bc57600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f057600080fd5b506102f9610904565b6040516101a29190611ac4565b34801561031257600080fd5b506102f96109a7565b61024f610329366004611af3565b6109b9565b34801561033a57600080fd5b5061024f610f73565b34801561034f57600080fd5b506001546101df565b34801561036457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101df565b3480156103a457600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d857600080fd5b50604051600081526020016101a2565b3480156103f457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101df565b61024f610433366004611a28565b6110b4565b34801561044457600080fd5b50610458610453366004611b28565b6110c0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101a2565b3480156104a857600080fd5b5060005467ffffffffffffffff16610223565b3480156104c757600080fd5b5061024f6104d6366004611b8a565b611131565b3480156104e757600080fd5b506104f06114fb565b6040516101a293929190611c14565b60008060005468010000000000000000900460ff166002811115610525576105256119b8565b1461055c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805460009161056c91611c6e565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff811015610656576000600182815481106105a6576105a6611c85565b6000918252602090912060039091020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019290915060ff64010000000090910416156105f75750610581565b600281015460009061063b906fffffffffffffffffffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000611539565b90508381101561064f578093508260010194505b5050610581565b5060006001838154811061066c5761066c611c85565b600091825260208220600390910201805490925063ffffffff908116919082146106d657600182815481106106a3576106a3611c85565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff16610702565b600283015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b905062049d4061071c67ffffffffffffffff831642611c6e565b610738836fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661074c9190611cb4565b11610783576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810154610825906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61082f9190611cfb565b67ffffffffffffffff1615801561085657506fffffffffffffffffffffffffffffffff8414155b156108645760029550610869565b600195505b600080548791907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156108ae576108ae6119b8565b0217905560028111156108c3576108c36119b8565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505050505090565b610900828260006109b9565b5050565b606061092f7f00000000000000000000000000000000000000000000000000000000000000006115ee565b6109587f00000000000000000000000000000000000000000000000000000000000000006115ee565b6109817f00000000000000000000000000000000000000000000000000000000000000006115ee565b60405160200161099393929190611d22565b604051602081830303815290604052905090565b60606109b460208061172b565b905090565b6000805468010000000000000000900460ff1660028111156109dd576109dd6119b8565b14610a14576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610a20575080155b15610a57576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610a6c57610a6c611c85565b60009182526020918290206040805160a0810182526003909302909101805463ffffffff8116845260ff64010000000090910416151593830193909352600180840154918301919091526002909201546fffffffffffffffffffffffffffffffff80821660608401527001000000000000000000000000000000009091041660808201528154909250819086908110610b0757610b07611c85565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909316929092179091556060820151610b71906fffffffffffffffffffffffffffffffff1684151760011b90565b90507f0000000000000000000000000000000000000000000000000000000000000000610c30826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610c72576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610cd2576001836000015163ffffffff1681548110610ca157610ca1611c85565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610d0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610d1f9190611cb4565b610d299190611c6e565b905062049d4067ffffffffffffffff82161115610d72576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421790506000610d93888660009182526020526040902090565b60008181526002602052604090205490915060ff1615610ddf576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260026020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581528184018e81526fffffffffffffffffffffffffffffffff808d16606085019081528a82166080860190815286548088018855968a52945160039096027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf68101805495511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909616979099169690961793909317909655517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf78401555190518416700100000000000000000000000000000000029316929092177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8909201919091555133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b600080547fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600191908101610ff87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff909316929092179490941781556040830151938101939093556060820151608090920151811670010000000000000000000000000000000002911617600290910155565b610900828260016109b9565b600181815481106110d057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff166002811115611155576111556119b8565b1461118c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600187815481106111a1576111a1611c85565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112007f00000000000000000000000000000000000000000000000000000000000000006001611cb4565b61129c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146112dd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561136357611301836fffffffffffffffffffffffffffffffff166117c2565b67ffffffffffffffff1660000361133a577f00000000000000000000000000000000000000000000000000000000000000009150611358565b611355611348600186611d98565b865463ffffffff16611868565b91505b50600184015461137d565b8460010154915061137a8460016113489190611dc9565b90505b81898960405161138e929190611dfd565b6040518091039020146113cd576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff8e0cb96000000000000000000000000000000000000000000000000000000008152819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f8e0cb9690611447908d908d908d908d90600401611e56565b6020604051808303816000875af1158015611466573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148a9190611e88565b036114c1576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179092555050505050505050565b6000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606115326109a7565b9050909192565b6000806115c6847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60608160000361163157505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561165b578061164581611ea1565b91506116549050600a83611ed9565b9150611635565b60008167ffffffffffffffff81111561167657611676611eed565b6040519080825280601f01601f1916602001820160405280156116a0576020820181803683370190505b5090505b8415611723576116b5600183611c6e565b91506116c2600a86611f1c565b6116cd906030611cb4565b60f81b8183815181106116e2576116e2611c85565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061171c600a86611ed9565b94506116a4565b949350505050565b6060600061176284367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003611cb4565b90508267ffffffffffffffff1667ffffffffffffffff81111561178757611787611eed565b6040519080825280601f01601f1916602001820160405280156117b1576020820181803683370190505b509150828160208401375092915050565b60008061184f837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080611886846fffffffffffffffffffffffffffffffff1661190c565b905060006001848154811061189d5761189d611c85565b906000526020600020906003020190505b60028101546fffffffffffffffffffffffffffffffff83811691161461190057805460018054909163ffffffff169081106118eb576118eb611c85565b906000526020600020906003020190506118ae565b60010154949350505050565b600081196001830116816119a0827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611a22577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215611a3b57600080fd5b50508035926020909101359150565b60005b83811015611a65578181015183820152602001611a4d565b83811115611a74576000848401525b50505050565b60008151808452611a92816020860160208601611a4a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ad76020830184611a7a565b9392505050565b80358015158114611aee57600080fd5b919050565b600080600060608486031215611b0857600080fd5b8335925060208401359150611b1f60408501611ade565b90509250925092565b600060208284031215611b3a57600080fd5b5035919050565b60008083601f840112611b5357600080fd5b50813567ffffffffffffffff811115611b6b57600080fd5b602083019150836020828501011115611b8357600080fd5b9250929050565b60008060008060008060808789031215611ba357600080fd5b86359550611bb360208801611ade565b9450604087013567ffffffffffffffff80821115611bd057600080fd5b611bdc8a838b01611b41565b90965094506060890135915080821115611bf557600080fd5b50611c0289828a01611b41565b979a9699509497509295939492505050565b60ff84168152826020820152606060408201526000611c366060830184611a7a565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611c8057611c80611c3f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115611cc757611cc7611c3f565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611d1657611d16611ccc565b92169190910692915050565b60008451611d34818460208901611a4a565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611d70816001850160208a01611a4a565b60019201918201528351611d8b816002840160208801611a4a565b0160020195945050505050565b60006fffffffffffffffffffffffffffffffff83811690831681811015611dc157611dc1611c3f565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115611df457611df4611c3f565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000611e6a604083018688611e0d565b8281036020840152611e7d818587611e0d565b979650505050505050565b600060208284031215611e9a57600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ed257611ed2611c3f565b5060010190565b600082611ee857611ee8611ccc565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611f2b57611f2b611ccc565b50069056fea164736f6c634300080f000a", Bin: "0x61014060405234801561001157600080fd5b50604051620021df380380620021df8339810160408190526100329161005d565b6000608081905260a052600360c05260e092909252610100526001600160a01b0316610120526100a3565b60008060006060848603121561007257600080fd5b83516020850151604086015191945092506001600160a01b038116811461009857600080fd5b809150509250925092565b60805160a05160c05160e05161010051610120516120c962000116600039600081816103aa01526113d60152600081816102c20152818161061701528181610b7501526111da0152600081816101bd01526113140152600061095d015260006109340152600061090b01526120c96000f3fe60806040526004361061016a5760003560e01c80638129fc1c116100cb578063bcef3b551161007f578063cf09e0d011610059578063cf09e0d01461049c578063d8cc1a3c146104bb578063fa24f743146104db57600080fd5b8063bcef3b55146103e8578063c55cd0c714610425578063c6f0308c1461043857600080fd5b80638b85902b116100b05780638b85902b146103585780639293129814610398578063bbdc02db146103cc57600080fd5b80638129fc1c1461032e5780638980e0cc1461034357600080fd5b8063363cc4271161012257806354fd4d501161010757806354fd4d50146102e4578063609d333414610306578063632247ea1461031b57600080fd5b8063363cc427146102515780634778efe8146102b057600080fd5b80632810e1d6116101535780632810e1d6146101ed5780633218b99d1461020257806335fef5671461023c57600080fd5b8063200d2ed21461016f578063266198f9146101ab575b600080fd5b34801561017b57600080fd5b506000546101959068010000000000000000900460ff1681565b6040516101a29190611b52565b60405180910390f35b3480156101b757600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101a2565b3480156101f957600080fd5b506101956104ff565b34801561020e57600080fd5b506000546102239067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101a2565b61024f61024a366004611b93565b6108f4565b005b34801561025d57600080fd5b5060005461028b906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b3480156102bc57600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f057600080fd5b506102f9610904565b6040516101a29190611c2f565b34801561031257600080fd5b506102f96109a7565b61024f610329366004611c5e565b6109b9565b34801561033a57600080fd5b5061024f610f73565b34801561034f57600080fd5b506001546101df565b34801561036457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101df565b3480156103a457600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d857600080fd5b50604051600081526020016101a2565b3480156103f457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101df565b61024f610433366004611b93565b6110b4565b34801561044457600080fd5b50610458610453366004611c93565b6110c0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101a2565b3480156104a857600080fd5b5060005467ffffffffffffffff16610223565b3480156104c757600080fd5b5061024f6104d6366004611cf5565b611131565b3480156104e757600080fd5b506104f061166d565b6040516101a293929190611d7f565b60008060005468010000000000000000900460ff16600281111561052557610525611b23565b1461055c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805460009161056c91611dd9565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff811015610656576000600182815481106105a6576105a6611df0565b6000918252602090912060039091020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019290915060ff64010000000090910416156105f75750610581565b600281015460009061063b906fffffffffffffffffffffffffffffffff167f00000000000000000000000000000000000000000000000000000000000000006116ab565b90508381101561064f578093508260010194505b5050610581565b5060006001838154811061066c5761066c611df0565b600091825260208220600390910201805490925063ffffffff908116919082146106d657600182815481106106a3576106a3611df0565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff16610702565b600283015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b905062049d4061071c67ffffffffffffffff831642611dd9565b610738836fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661074c9190611e1f565b11610783576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810154610825906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61082f9190611e66565b67ffffffffffffffff1615801561085657506fffffffffffffffffffffffffffffffff8414155b156108645760029550610869565b600195505b600080548791907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156108ae576108ae611b23565b0217905560028111156108c3576108c3611b23565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505050505090565b610900828260006109b9565b5050565b606061092f7f0000000000000000000000000000000000000000000000000000000000000000611760565b6109587f0000000000000000000000000000000000000000000000000000000000000000611760565b6109817f0000000000000000000000000000000000000000000000000000000000000000611760565b60405160200161099393929190611e8d565b604051602081830303815290604052905090565b60606109b460208061189d565b905090565b6000805468010000000000000000900460ff1660028111156109dd576109dd611b23565b14610a14576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610a20575080155b15610a57576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610a6c57610a6c611df0565b60009182526020918290206040805160a0810182526003909302909101805463ffffffff8116845260ff64010000000090910416151593830193909352600180840154918301919091526002909201546fffffffffffffffffffffffffffffffff80821660608401527001000000000000000000000000000000009091041660808201528154909250819086908110610b0757610b07611df0565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909316929092179091556060820151610b71906fffffffffffffffffffffffffffffffff1684151760011b90565b90507f0000000000000000000000000000000000000000000000000000000000000000610c30826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610c72576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610cd2576001836000015163ffffffff1681548110610ca157610ca1611df0565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610d0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610d1f9190611e1f565b610d299190611dd9565b905062049d4067ffffffffffffffff82161115610d72576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421790506000610d93888660009182526020526040902090565b60008181526002602052604090205490915060ff1615610ddf576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260026020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581528184018e81526fffffffffffffffffffffffffffffffff808d16606085019081528a82166080860190815286548088018855968a52945160039096027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf68101805495511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909616979099169690961793909317909655517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf78401555190518416700100000000000000000000000000000000029316929092177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8909201919091555133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b600080547fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600191908101610ff87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff909316929092179490941781556040830151938101939093556060820151608090920151811670010000000000000000000000000000000002911617600290910155565b610900828260016109b9565b600181815481106110d057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561115557611155611b23565b1461118c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600187815481106111a1576111a1611df0565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112007f00000000000000000000000000000000000000000000000000000000000000006001611e1f565b61129c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146112dd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561136357611301836fffffffffffffffffffffffffffffffff16611934565b67ffffffffffffffff1660000361133a577f0000000000000000000000000000000000000000000000000000000000000000915061135c565b611355611348600186611f03565b865463ffffffff166119da565b6001015491505b508361137d565b8460010154915061137a8460016113489190611f34565b90505b81898960405161138e929190611f68565b6040518091039020146113cd576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f8e0cb968c8c8c8c6040518563ffffffff1660e01b81526004016114339493929190611fc1565b6020604051808303816000875af1158015611452573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114769190611ff3565b600284810154929091149250600091611521906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6115bd886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6115c7919061200c565b6115d19190611e66565b67ffffffffffffffff161590508080156115e85750815b806115fa5750801580156115fa575081155b15611631576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b6000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606116a46109a7565b9050909192565b600080611738847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6060816000036117a357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156117cd57806117b78161202d565b91506117c69050600a83612065565b91506117a7565b60008167ffffffffffffffff8111156117e8576117e8612079565b6040519080825280601f01601f191660200182016040528015611812576020820181803683370190505b5090505b841561189557611827600183611dd9565b9150611834600a866120a8565b61183f906030611e1f565b60f81b81838151811061185457611854611df0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061188e600a86612065565b9450611816565b949350505050565b606060006118d484367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003611e1f565b90508267ffffffffffffffff1667ffffffffffffffff8111156118f9576118f9612079565b6040519080825280601f01601f191660200182016040528015611923576020820181803683370190505b509150828160208401375092915050565b6000806119c1837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806119f8846fffffffffffffffffffffffffffffffff16611a77565b905060018381548110611a0d57611a0d611df0565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff828116911614611a7057815460018054909163ffffffff16908110611a5b57611a5b611df0565b90600052602060002090600302019150611a1e565b5092915050565b60008119600183011681611b0b827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611b8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215611ba657600080fd5b50508035926020909101359150565b60005b83811015611bd0578181015183820152602001611bb8565b83811115611bdf576000848401525b50505050565b60008151808452611bfd816020860160208601611bb5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611c426020830184611be5565b9392505050565b80358015158114611c5957600080fd5b919050565b600080600060608486031215611c7357600080fd5b8335925060208401359150611c8a60408501611c49565b90509250925092565b600060208284031215611ca557600080fd5b5035919050565b60008083601f840112611cbe57600080fd5b50813567ffffffffffffffff811115611cd657600080fd5b602083019150836020828501011115611cee57600080fd5b9250929050565b60008060008060008060808789031215611d0e57600080fd5b86359550611d1e60208801611c49565b9450604087013567ffffffffffffffff80821115611d3b57600080fd5b611d478a838b01611cac565b90965094506060890135915080821115611d6057600080fd5b50611d6d89828a01611cac565b979a9699509497509295939492505050565b60ff84168152826020820152606060408201526000611da16060830184611be5565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611deb57611deb611daa565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115611e3257611e32611daa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611e8157611e81611e37565b92169190910692915050565b60008451611e9f818460208901611bb5565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611edb816001850160208a01611bb5565b60019201918201528351611ef6816002840160208801611bb5565b0160020195945050505050565b60006fffffffffffffffffffffffffffffffff83811690831681811015611f2c57611f2c611daa565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115611f5f57611f5f611daa565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000611fd5604083018688611f78565b8281036020840152611fe8818587611f78565b979650505050505050565b60006020828403121561200557600080fd5b5051919050565b600067ffffffffffffffff83811690831681811015611f2c57611f2c611daa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361205e5761205e611daa565b5060010190565b60008261207457612074611e37565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000826120b7576120b7611e37565b50069056fea164736f6c634300080f000a",
} }
// FaultDisputeGameABI is the input ABI used to generate the binding from. // FaultDisputeGameABI is the input ABI used to generate the binding from.
......
...@@ -13,7 +13,7 @@ const FaultDisputeGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contr ...@@ -13,7 +13,7 @@ const FaultDisputeGameStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contr
var FaultDisputeGameStorageLayout = new(solc.StorageLayout) var FaultDisputeGameStorageLayout = new(solc.StorageLayout)
var FaultDisputeGameDeployedBin = "0x60806040526004361061016a5760003560e01c80638129fc1c116100cb578063bcef3b551161007f578063cf09e0d011610059578063cf09e0d01461049c578063d8cc1a3c146104bb578063fa24f743146104db57600080fd5b8063bcef3b55146103e8578063c55cd0c714610425578063c6f0308c1461043857600080fd5b80638b85902b116100b05780638b85902b146103585780639293129814610398578063bbdc02db146103cc57600080fd5b80638129fc1c1461032e5780638980e0cc1461034357600080fd5b8063363cc4271161012257806354fd4d501161010757806354fd4d50146102e4578063609d333414610306578063632247ea1461031b57600080fd5b8063363cc427146102515780634778efe8146102b057600080fd5b80632810e1d6116101535780632810e1d6146101ed5780633218b99d1461020257806335fef5671461023c57600080fd5b8063200d2ed21461016f578063266198f9146101ab575b600080fd5b34801561017b57600080fd5b506000546101959068010000000000000000900460ff1681565b6040516101a291906119e7565b60405180910390f35b3480156101b757600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101a2565b3480156101f957600080fd5b506101956104ff565b34801561020e57600080fd5b506000546102239067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101a2565b61024f61024a366004611a28565b6108f4565b005b34801561025d57600080fd5b5060005461028b906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b3480156102bc57600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f057600080fd5b506102f9610904565b6040516101a29190611ac4565b34801561031257600080fd5b506102f96109a7565b61024f610329366004611af3565b6109b9565b34801561033a57600080fd5b5061024f610f73565b34801561034f57600080fd5b506001546101df565b34801561036457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101df565b3480156103a457600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d857600080fd5b50604051600081526020016101a2565b3480156103f457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101df565b61024f610433366004611a28565b6110b4565b34801561044457600080fd5b50610458610453366004611b28565b6110c0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101a2565b3480156104a857600080fd5b5060005467ffffffffffffffff16610223565b3480156104c757600080fd5b5061024f6104d6366004611b8a565b611131565b3480156104e757600080fd5b506104f06114fb565b6040516101a293929190611c14565b60008060005468010000000000000000900460ff166002811115610525576105256119b8565b1461055c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805460009161056c91611c6e565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff811015610656576000600182815481106105a6576105a6611c85565b6000918252602090912060039091020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019290915060ff64010000000090910416156105f75750610581565b600281015460009061063b906fffffffffffffffffffffffffffffffff167f0000000000000000000000000000000000000000000000000000000000000000611539565b90508381101561064f578093508260010194505b5050610581565b5060006001838154811061066c5761066c611c85565b600091825260208220600390910201805490925063ffffffff908116919082146106d657600182815481106106a3576106a3611c85565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff16610702565b600283015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b905062049d4061071c67ffffffffffffffff831642611c6e565b610738836fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661074c9190611cb4565b11610783576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810154610825906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61082f9190611cfb565b67ffffffffffffffff1615801561085657506fffffffffffffffffffffffffffffffff8414155b156108645760029550610869565b600195505b600080548791907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156108ae576108ae6119b8565b0217905560028111156108c3576108c36119b8565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505050505090565b610900828260006109b9565b5050565b606061092f7f00000000000000000000000000000000000000000000000000000000000000006115ee565b6109587f00000000000000000000000000000000000000000000000000000000000000006115ee565b6109817f00000000000000000000000000000000000000000000000000000000000000006115ee565b60405160200161099393929190611d22565b604051602081830303815290604052905090565b60606109b460208061172b565b905090565b6000805468010000000000000000900460ff1660028111156109dd576109dd6119b8565b14610a14576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610a20575080155b15610a57576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610a6c57610a6c611c85565b60009182526020918290206040805160a0810182526003909302909101805463ffffffff8116845260ff64010000000090910416151593830193909352600180840154918301919091526002909201546fffffffffffffffffffffffffffffffff80821660608401527001000000000000000000000000000000009091041660808201528154909250819086908110610b0757610b07611c85565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909316929092179091556060820151610b71906fffffffffffffffffffffffffffffffff1684151760011b90565b90507f0000000000000000000000000000000000000000000000000000000000000000610c30826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610c72576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610cd2576001836000015163ffffffff1681548110610ca157610ca1611c85565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610d0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610d1f9190611cb4565b610d299190611c6e565b905062049d4067ffffffffffffffff82161115610d72576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421790506000610d93888660009182526020526040902090565b60008181526002602052604090205490915060ff1615610ddf576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260026020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581528184018e81526fffffffffffffffffffffffffffffffff808d16606085019081528a82166080860190815286548088018855968a52945160039096027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf68101805495511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909616979099169690961793909317909655517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf78401555190518416700100000000000000000000000000000000029316929092177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8909201919091555133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b600080547fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600191908101610ff87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff909316929092179490941781556040830151938101939093556060820151608090920151811670010000000000000000000000000000000002911617600290910155565b610900828260016109b9565b600181815481106110d057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff166002811115611155576111556119b8565b1461118c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600187815481106111a1576111a1611c85565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112007f00000000000000000000000000000000000000000000000000000000000000006001611cb4565b61129c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146112dd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561136357611301836fffffffffffffffffffffffffffffffff166117c2565b67ffffffffffffffff1660000361133a577f00000000000000000000000000000000000000000000000000000000000000009150611358565b611355611348600186611d98565b865463ffffffff16611868565b91505b50600184015461137d565b8460010154915061137a8460016113489190611dc9565b90505b81898960405161138e929190611dfd565b6040518091039020146113cd576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517ff8e0cb96000000000000000000000000000000000000000000000000000000008152819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063f8e0cb9690611447908d908d908d908d90600401611e56565b6020604051808303816000875af1158015611466573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148a9190611e88565b036114c1576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505082547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16640100000000179092555050505050505050565b6000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606115326109a7565b9050909192565b6000806115c6847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b60608160000361163157505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561165b578061164581611ea1565b91506116549050600a83611ed9565b9150611635565b60008167ffffffffffffffff81111561167657611676611eed565b6040519080825280601f01601f1916602001820160405280156116a0576020820181803683370190505b5090505b8415611723576116b5600183611c6e565b91506116c2600a86611f1c565b6116cd906030611cb4565b60f81b8183815181106116e2576116e2611c85565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061171c600a86611ed9565b94506116a4565b949350505050565b6060600061176284367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003611cb4565b90508267ffffffffffffffff1667ffffffffffffffff81111561178757611787611eed565b6040519080825280601f01601f1916602001820160405280156117b1576020820181803683370190505b509150828160208401375092915050565b60008061184f837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b600080611886846fffffffffffffffffffffffffffffffff1661190c565b905060006001848154811061189d5761189d611c85565b906000526020600020906003020190505b60028101546fffffffffffffffffffffffffffffffff83811691161461190057805460018054909163ffffffff169081106118eb576118eb611c85565b906000526020600020906003020190506118ae565b60010154949350505050565b600081196001830116816119a0827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611a22577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215611a3b57600080fd5b50508035926020909101359150565b60005b83811015611a65578181015183820152602001611a4d565b83811115611a74576000848401525b50505050565b60008151808452611a92816020860160208601611a4a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611ad76020830184611a7a565b9392505050565b80358015158114611aee57600080fd5b919050565b600080600060608486031215611b0857600080fd5b8335925060208401359150611b1f60408501611ade565b90509250925092565b600060208284031215611b3a57600080fd5b5035919050565b60008083601f840112611b5357600080fd5b50813567ffffffffffffffff811115611b6b57600080fd5b602083019150836020828501011115611b8357600080fd5b9250929050565b60008060008060008060808789031215611ba357600080fd5b86359550611bb360208801611ade565b9450604087013567ffffffffffffffff80821115611bd057600080fd5b611bdc8a838b01611b41565b90965094506060890135915080821115611bf557600080fd5b50611c0289828a01611b41565b979a9699509497509295939492505050565b60ff84168152826020820152606060408201526000611c366060830184611a7a565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611c8057611c80611c3f565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115611cc757611cc7611c3f565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611d1657611d16611ccc565b92169190910692915050565b60008451611d34818460208901611a4a565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611d70816001850160208a01611a4a565b60019201918201528351611d8b816002840160208801611a4a565b0160020195945050505050565b60006fffffffffffffffffffffffffffffffff83811690831681811015611dc157611dc1611c3f565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115611df457611df4611c3f565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000611e6a604083018688611e0d565b8281036020840152611e7d818587611e0d565b979650505050505050565b600060208284031215611e9a57600080fd5b5051919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ed257611ed2611c3f565b5060010190565b600082611ee857611ee8611ccc565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082611f2b57611f2b611ccc565b50069056fea164736f6c634300080f000a" var FaultDisputeGameDeployedBin = "0x60806040526004361061016a5760003560e01c80638129fc1c116100cb578063bcef3b551161007f578063cf09e0d011610059578063cf09e0d01461049c578063d8cc1a3c146104bb578063fa24f743146104db57600080fd5b8063bcef3b55146103e8578063c55cd0c714610425578063c6f0308c1461043857600080fd5b80638b85902b116100b05780638b85902b146103585780639293129814610398578063bbdc02db146103cc57600080fd5b80638129fc1c1461032e5780638980e0cc1461034357600080fd5b8063363cc4271161012257806354fd4d501161010757806354fd4d50146102e4578063609d333414610306578063632247ea1461031b57600080fd5b8063363cc427146102515780634778efe8146102b057600080fd5b80632810e1d6116101535780632810e1d6146101ed5780633218b99d1461020257806335fef5671461023c57600080fd5b8063200d2ed21461016f578063266198f9146101ab575b600080fd5b34801561017b57600080fd5b506000546101959068010000000000000000900460ff1681565b6040516101a29190611b52565b60405180910390f35b3480156101b757600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101a2565b3480156101f957600080fd5b506101956104ff565b34801561020e57600080fd5b506000546102239067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016101a2565b61024f61024a366004611b93565b6108f4565b005b34801561025d57600080fd5b5060005461028b906901000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a2565b3480156102bc57600080fd5b506101df7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f057600080fd5b506102f9610904565b6040516101a29190611c2f565b34801561031257600080fd5b506102f96109a7565b61024f610329366004611c5e565b6109b9565b34801561033a57600080fd5b5061024f610f73565b34801561034f57600080fd5b506001546101df565b34801561036457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003602001356101df565b3480156103a457600080fd5b5061028b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103d857600080fd5b50604051600081526020016101a2565b3480156103f457600080fd5b50367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003356101df565b61024f610433366004611b93565b6110b4565b34801561044457600080fd5b50610458610453366004611c93565b6110c0565b6040805163ffffffff90961686529315156020860152928401919091526fffffffffffffffffffffffffffffffff908116606084015216608082015260a0016101a2565b3480156104a857600080fd5b5060005467ffffffffffffffff16610223565b3480156104c757600080fd5b5061024f6104d6366004611cf5565b611131565b3480156104e757600080fd5b506104f061166d565b6040516101a293929190611d7f565b60008060005468010000000000000000900460ff16600281111561052557610525611b23565b1461055c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805460009161056c91611dd9565b90506fffffffffffffffffffffffffffffffff815b67ffffffffffffffff811015610656576000600182815481106105a6576105a6611df0565b6000918252602090912060039091020180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019290915060ff64010000000090910416156105f75750610581565b600281015460009061063b906fffffffffffffffffffffffffffffffff167f00000000000000000000000000000000000000000000000000000000000000006116ab565b90508381101561064f578093508260010194505b5050610581565b5060006001838154811061066c5761066c611df0565b600091825260208220600390910201805490925063ffffffff908116919082146106d657600182815481106106a3576106a3611df0565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff16610702565b600283015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff165b905062049d4061071c67ffffffffffffffff831642611dd9565b610738836fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff1661074c9190611e1f565b11610783576040517ff2440b5300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600283810154610825906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b61082f9190611e66565b67ffffffffffffffff1615801561085657506fffffffffffffffffffffffffffffffff8414155b156108645760029550610869565b600195505b600080548791907fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000008360028111156108ae576108ae611b23565b0217905560028111156108c3576108c3611b23565b6040517f5e186f09b9c93491f14e277eea7faa5de6a2d4bda75a79af7a3684fbfb42da6090600090a2505050505090565b610900828260006109b9565b5050565b606061092f7f0000000000000000000000000000000000000000000000000000000000000000611760565b6109587f0000000000000000000000000000000000000000000000000000000000000000611760565b6109817f0000000000000000000000000000000000000000000000000000000000000000611760565b60405160200161099393929190611e8d565b604051602081830303815290604052905090565b60606109b460208061189d565b905090565b6000805468010000000000000000900460ff1660028111156109dd576109dd611b23565b14610a14576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82158015610a20575080155b15610a57576040517fa42637bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060018481548110610a6c57610a6c611df0565b60009182526020918290206040805160a0810182526003909302909101805463ffffffff8116845260ff64010000000090910416151593830193909352600180840154918301919091526002909201546fffffffffffffffffffffffffffffffff80821660608401527001000000000000000000000000000000009091041660808201528154909250819086908110610b0757610b07611df0565b6000918252602082206003909102018054921515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff909316929092179091556060820151610b71906fffffffffffffffffffffffffffffffff1684151760011b90565b90507f0000000000000000000000000000000000000000000000000000000000000000610c30826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff161115610c72576040517f56f57b2b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160009063ffffffff90811614610cd2576001836000015163ffffffff1681548110610ca157610ca1611df0565b906000526020600020906003020160020160109054906101000a90046fffffffffffffffffffffffffffffffff1690505b608083015160009067ffffffffffffffff1667ffffffffffffffff1642610d0b846fffffffffffffffffffffffffffffffff1660401c90565b67ffffffffffffffff16610d1f9190611e1f565b610d299190611dd9565b905062049d4067ffffffffffffffff82161115610d72576040517f3381d11400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000604082901b421790506000610d93888660009182526020526040902090565b60008181526002602052604090205490915060ff1615610ddf576040517f80497e3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260026020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155815160a08101835263ffffffff808f1682529381018581528184018e81526fffffffffffffffffffffffffffffffff808d16606085019081528a82166080860190815286548088018855968a52945160039096027fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf68101805495511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909616979099169690961793909317909655517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf78401555190518416700100000000000000000000000000000000029316929092177fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8909201919091555133918a918c917f9b3245740ec3b155098a55be84957a4da13eaf7f14a8bc6f53126c0b9350f2be91a4505050505050505050565b600080547fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000164267ffffffffffffffff161781556040805160a08101825263ffffffff81526020810192909252600191908101610ff87ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe369081013560f01c90033590565b815260016020820152604001426fffffffffffffffffffffffffffffffff908116909152825460018181018555600094855260209485902084516003909302018054958501511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000090961663ffffffff909316929092179490941781556040830151938101939093556060820151608090920151811670010000000000000000000000000000000002911617600290910155565b610900828260016109b9565b600181815481106110d057600080fd5b600091825260209091206003909102018054600182015460029092015463ffffffff8216935064010000000090910460ff1691906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041685565b6000805468010000000000000000900460ff16600281111561115557611155611b23565b1461118c576040517f67fe195000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600187815481106111a1576111a1611df0565b6000918252602082206003919091020160028101549092506fffffffffffffffffffffffffffffffff16908715821760011b90506112007f00000000000000000000000000000000000000000000000000000000000000006001611e1f565b61129c826fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff16146112dd576040517f5f53dd9800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080891561136357611301836fffffffffffffffffffffffffffffffff16611934565b67ffffffffffffffff1660000361133a577f0000000000000000000000000000000000000000000000000000000000000000915061135c565b611355611348600186611f03565b865463ffffffff166119da565b6001015491505b508361137d565b8460010154915061137a8460016113489190611f34565b90505b81898960405161138e929190611f68565b6040518091039020146113cd576040517f696550ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081600101547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f8e0cb968c8c8c8c6040518563ffffffff1660e01b81526004016114339493929190611fc1565b6020604051808303816000875af1158015611452573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114769190611ff3565b600284810154929091149250600091611521906fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6115bd886fffffffffffffffffffffffffffffffff167e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b6115c7919061200c565b6115d19190611e66565b67ffffffffffffffff161590508080156115e85750815b806115fa5750801580156115fa575081155b15611631576040517ffb4e40dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505084547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff166401000000001790945550505050505050505050565b6000367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c90033560606116a46109a7565b9050909192565b600080611738847e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff1690508083036001841b600180831b0386831b17039250505092915050565b6060816000036117a357505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156117cd57806117b78161202d565b91506117c69050600a83612065565b91506117a7565b60008167ffffffffffffffff8111156117e8576117e8612079565b6040519080825280601f01601f191660200182016040528015611812576020820181803683370190505b5090505b841561189557611827600183611dd9565b9150611834600a866120a8565b61183f906030611e1f565b60f81b81838151811061185457611854611df0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061188e600a86612065565b9450611816565b949350505050565b606060006118d484367ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81013560f01c9003611e1f565b90508267ffffffffffffffff1667ffffffffffffffff8111156118f9576118f9612079565b6040519080825280601f01601f191660200182016040528015611923576020820181803683370190505b509150828160208401375092915050565b6000806119c1837e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b600167ffffffffffffffff919091161b90920392915050565b6000806119f8846fffffffffffffffffffffffffffffffff16611a77565b905060018381548110611a0d57611a0d611df0565b906000526020600020906003020191505b60028201546fffffffffffffffffffffffffffffffff828116911614611a7057815460018054909163ffffffff16908110611a5b57611a5b611df0565b90600052602060002090600302019150611a1e565b5092915050565b60008119600183011681611b0b827e09010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f7f07c4acdd0000000000000000000000000000000000000000000000000000000067ffffffffffffffff831160061b83811c63ffffffff1060051b1792831c600181901c17600281901c17600481901c17600881901c17601081901c170260fb1c1a1790565b67ffffffffffffffff169390931c8015179392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310611b8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60008060408385031215611ba657600080fd5b50508035926020909101359150565b60005b83811015611bd0578181015183820152602001611bb8565b83811115611bdf576000848401525b50505050565b60008151808452611bfd816020860160208601611bb5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611c426020830184611be5565b9392505050565b80358015158114611c5957600080fd5b919050565b600080600060608486031215611c7357600080fd5b8335925060208401359150611c8a60408501611c49565b90509250925092565b600060208284031215611ca557600080fd5b5035919050565b60008083601f840112611cbe57600080fd5b50813567ffffffffffffffff811115611cd657600080fd5b602083019150836020828501011115611cee57600080fd5b9250929050565b60008060008060008060808789031215611d0e57600080fd5b86359550611d1e60208801611c49565b9450604087013567ffffffffffffffff80821115611d3b57600080fd5b611d478a838b01611cac565b90965094506060890135915080821115611d6057600080fd5b50611d6d89828a01611cac565b979a9699509497509295939492505050565b60ff84168152826020820152606060408201526000611da16060830184611be5565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611deb57611deb611daa565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115611e3257611e32611daa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680611e8157611e81611e37565b92169190910692915050565b60008451611e9f818460208901611bb5565b80830190507f2e000000000000000000000000000000000000000000000000000000000000008082528551611edb816001850160208a01611bb5565b60019201918201528351611ef6816002840160208801611bb5565b0160020195945050505050565b60006fffffffffffffffffffffffffffffffff83811690831681811015611f2c57611f2c611daa565b039392505050565b60006fffffffffffffffffffffffffffffffff808316818516808303821115611f5f57611f5f611daa565b01949350505050565b8183823760009101908152919050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b604081526000611fd5604083018688611f78565b8281036020840152611fe8818587611f78565b979650505050505050565b60006020828403121561200557600080fd5b5051919050565b600067ffffffffffffffff83811690831681811015611f2c57611f2c611daa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361205e5761205e611daa565b5060010190565b60008261207457612074611e37565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000826120b7576120b7611e37565b50069056fea164736f6c634300080f000a"
func init() { func init() {
if err := json.Unmarshal([]byte(FaultDisputeGameStorageLayoutJSON), FaultDisputeGameStorageLayout); err != nil { if err := json.Unmarshal([]byte(FaultDisputeGameStorageLayoutJSON), FaultDisputeGameStorageLayout); err != nil {
......
...@@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout) ...@@ -15,7 +15,7 @@ var PreimageOracleStorageLayout = new(solc.StorageLayout)
var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063e03110e11161005b578063e03110e114610111578063e159261114610139578063fe4ac08e1461014e578063fef2b4ed146101c357600080fd5b806361238bde146100825780638542cf50146100c0578063a57c202c146100fe575b600080fd5b6100ad610090366004610433565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100ee6100ce366004610433565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100b7565b6100ad61010c36600461049e565b6101e3565b61012461011f366004610433565b610242565b604080519283526020830191909152016100b7565b61014c6101473660046104e0565b610333565b005b61014c61015c36600461052c565b6000838152600260209081526040808320878452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558684528252808320968352958152858220939093559283529082905291902055565b6100ad6101d136600461055e565b60006020819052908152604090205481565b60243560c081901b608052600090608881858237207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179392505050565b6000828152600260209081526040808320848452909152812054819060ff166102cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102e78160086105a6565b6102f28560206105a6565b1061031057836103038260086105a6565b61030d91906105be565b91505b506000938452600160209081526040808620948652939052919092205492909150565b6044356000806008830186111561034957600080fd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b6000806040838503121561044657600080fd5b50508035926020909101359150565b60008083601f84011261046757600080fd5b50813567ffffffffffffffff81111561047f57600080fd5b60208301915083602082850101111561049757600080fd5b9250929050565b600080602083850312156104b157600080fd5b823567ffffffffffffffff8111156104c857600080fd5b6104d485828601610455565b90969095509350505050565b6000806000604084860312156104f557600080fd5b83359250602084013567ffffffffffffffff81111561051357600080fd5b61051f86828701610455565b9497909650939450505050565b6000806000806080858703121561054257600080fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561057057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156105b9576105b9610577565b500190565b6000828210156105d0576105d0610577565b50039056fea164736f6c634300080f000a" var PreimageOracleDeployedBin = "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063e03110e11161005b578063e03110e114610111578063e159261114610139578063fe4ac08e1461014e578063fef2b4ed146101c357600080fd5b806361238bde146100825780638542cf50146100c0578063a57c202c146100fe575b600080fd5b6100ad610090366004610433565b600160209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b6100ee6100ce366004610433565b600260209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100b7565b6100ad61010c36600461049e565b6101e3565b61012461011f366004610433565b610242565b604080519283526020830191909152016100b7565b61014c6101473660046104e0565b610333565b005b61014c61015c36600461052c565b6000838152600260209081526040808320878452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558684528252808320968352958152858220939093559283529082905291902055565b6100ad6101d136600461055e565b60006020819052908152604090205481565b60243560c081901b608052600090608881858237207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f0200000000000000000000000000000000000000000000000000000000000000179392505050565b6000828152600260209081526040808320848452909152812054819060ff166102cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f7072652d696d616765206d757374206578697374000000000000000000000000604482015260640160405180910390fd5b50600083815260208181526040909120546102e78160086105a6565b6102f28560206105a6565b1061031057836103038260086105a6565b61030d91906105be565b91505b506000938452600160209081526040808620948652939052919092205492909150565b6044356000806008830186111561034957600080fd5b60c083901b6080526088838682378087017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80151908490207effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f02000000000000000000000000000000000000000000000000000000000000001760008181526002602090815260408083208b8452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915584845282528083209a83529981528982209390935590815290819052959095209190915550505050565b6000806040838503121561044657600080fd5b50508035926020909101359150565b60008083601f84011261046757600080fd5b50813567ffffffffffffffff81111561047f57600080fd5b60208301915083602082850101111561049757600080fd5b9250929050565b600080602083850312156104b157600080fd5b823567ffffffffffffffff8111156104c857600080fd5b6104d485828601610455565b90969095509350505050565b6000806000604084860312156104f557600080fd5b83359250602084013567ffffffffffffffff81111561051357600080fd5b61051f86828701610455565b9497909650939450505050565b6000806000806080858703121561054257600080fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561057057600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156105b9576105b9610577565b500190565b6000828210156105d0576105d0610577565b50039056fea164736f6c634300080f000a"
var PreimageOracleDeployedSourceMap = "144:4615:58:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;357:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:229;;;401:2;386:18;357:68:58;;;;;;;;501:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:229;;607:22;589:41;;577:2;562:18;501:66:58;449:187:229;2154:850:58;;;;;;:::i;:::-;;:::i;838:564::-;;;;;;:::i;:::-;;:::i;:::-;;;;1581:25:229;;;1637:2;1622:18;;1615:34;;;;1554:18;838:564:58;1407:248:229;3295:1462:58;;;;;;:::i;:::-;;:::i;:::-;;1744:262;;;;;;:::i;:::-;1877:19;;;;:14;:19;;;;;;;;:31;;;;;;;;:38;;;;1911:4;1877:38;;;;;;1925:18;;;;;;;;:30;;;;;;;;;:37;;;;1972:20;;;;;;;;;;:27;1744:262;238:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;2154:850;2321:4;2308:18;2567:3;2563:14;;;2458:4;2551:27;2231:12;;2598:11;2308:18;2718:16;2598:11;2700:41;2840:20;2954:19;2947:27;2976:11;2944:44;;2154:850;-1:-1:-1;;;2154:850:58:o;838:564::-;938:12;991:20;;;:14;:20;;;;;;;;:29;;;;;;;;;938:12;;991:29;;983:62;;;;;;;3101:2:229;983:62:58;;;3083:21:229;3140:2;3120:18;;;3113:30;3179:22;3159:18;;;3152:50;3219:18;;983:62:58;;;;;;;;-1:-1:-1;1176:14:58;1193:21;;;1164:2;1193:21;;;;;;;;1244:10;1193:21;1253:1;1244:10;:::i;:::-;1228:12;:7;1238:2;1228:12;:::i;:::-;:26;1224:87;;1293:7;1280:10;:6;1289:1;1280:10;:::i;:::-;:20;;;;:::i;:::-;1270:30;;1224:87;-1:-1:-1;1367:19:58;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;838:564;;-1:-1:-1;838:564:58:o;3295:1462::-;3591:4;3578:18;3396:12;;3720:1;3710:12;;3694:29;;3691:77;;;3752:1;3749;3742:12;3691:77;4011:3;4007:14;;;3911:4;3995:27;4042:11;4016:4;4161:16;4042:11;4143:41;4374:29;;;4378:11;4374:29;4368:36;4426:20;;;;4573:19;4566:27;4595:11;4563:44;4626:19;;;;4604:1;4626:19;;;;;;;;:32;;;;;;;;:39;;;;4661:4;4626:39;;;;;;4675:18;;;;;;;;:31;;;;;;;;;:38;;;;4723:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;3295:1462:58:o;14:248:229:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:229;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:229:o;641:347::-;692:8;702:6;756:3;749:4;741:6;737:17;733:27;723:55;;774:1;771;764:12;723:55;-1:-1:-1;797:20:229;;840:18;829:30;;826:50;;;872:1;869;862:12;826:50;909:4;901:6;897:17;885:29;;961:3;954:4;945:6;937;933:19;929:30;926:39;923:59;;;978:1;975;968:12;923:59;641:347;;;;;:::o;993:409::-;1063:6;1071;1124:2;1112:9;1103:7;1099:23;1095:32;1092:52;;;1140:1;1137;1130:12;1092:52;1180:9;1167:23;1213:18;1205:6;1202:30;1199:50;;;1245:1;1242;1235:12;1199:50;1284:58;1334:7;1325:6;1314:9;1310:22;1284:58;:::i;:::-;1361:8;;1258:84;;-1:-1:-1;993:409:229;-1:-1:-1;;;;993:409:229:o;1660:477::-;1739:6;1747;1755;1808:2;1796:9;1787:7;1783:23;1779:32;1776:52;;;1824:1;1821;1814:12;1776:52;1860:9;1847:23;1837:33;;1921:2;1910:9;1906:18;1893:32;1948:18;1940:6;1937:30;1934:50;;;1980:1;1977;1970:12;1934:50;2019:58;2069:7;2060:6;2049:9;2045:22;2019:58;:::i;:::-;1660:477;;2096:8;;-1:-1:-1;1993:84:229;;-1:-1:-1;;;;1660:477:229:o;2142:385::-;2228:6;2236;2244;2252;2305:3;2293:9;2284:7;2280:23;2276:33;2273:53;;;2322:1;2319;2312:12;2273:53;-1:-1:-1;;2345:23:229;;;2415:2;2400:18;;2387:32;;-1:-1:-1;2466:2:229;2451:18;;2438:32;;2517:2;2502:18;2489:32;;-1:-1:-1;2142:385:229;-1:-1:-1;2142:385:229:o;2532:180::-;2591:6;2644:2;2632:9;2623:7;2619:23;2615:32;2612:52;;;2660:1;2657;2650:12;2612:52;-1:-1:-1;2683:23:229;;2532:180;-1:-1:-1;2532:180:229:o;3248:184::-;3300:77;3297:1;3290:88;3397:4;3394:1;3387:15;3421:4;3418:1;3411:15;3437:128;3477:3;3508:1;3504:6;3501:1;3498:13;3495:39;;;3514:18;;:::i;:::-;-1:-1:-1;3550:9:229;;3437:128::o;3570:125::-;3610:4;3638:1;3635;3632:8;3629:34;;;3643:18;;:::i;:::-;-1:-1:-1;3680:9:229;;3570:125::o" var PreimageOracleDeployedSourceMap = "144:4615:67:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;357:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;413:25:283;;;401:2;386:18;357:68:67;;;;;;;;501:66;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;614:14:283;;607:22;589:41;;577:2;562:18;501:66:67;449:187:283;2154:850:67;;;;;;:::i;:::-;;:::i;838:564::-;;;;;;:::i;:::-;;:::i;:::-;;;;1581:25:283;;;1637:2;1622:18;;1615:34;;;;1554:18;838:564:67;1407:248:283;3295:1462:67;;;;;;:::i;:::-;;:::i;:::-;;1744:262;;;;;;:::i;:::-;1877:19;;;;:14;:19;;;;;;;;:31;;;;;;;;:38;;;;1911:4;1877:38;;;;;;1925:18;;;;;;;;:30;;;;;;;;;:37;;;;1972:20;;;;;;;;;;:27;1744:262;238:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;2154:850;2321:4;2308:18;2567:3;2563:14;;;2458:4;2551:27;2231:12;;2598:11;2308:18;2718:16;2598:11;2700:41;2840:20;2954:19;2947:27;2976:11;2944:44;;2154:850;-1:-1:-1;;;2154:850:67:o;838:564::-;938:12;991:20;;;:14;:20;;;;;;;;:29;;;;;;;;;938:12;;991:29;;983:62;;;;;;;3101:2:283;983:62:67;;;3083:21:283;3140:2;3120:18;;;3113:30;3179:22;3159:18;;;3152:50;3219:18;;983:62:67;;;;;;;;-1:-1:-1;1176:14:67;1193:21;;;1164:2;1193:21;;;;;;;;1244:10;1193:21;1253:1;1244:10;:::i;:::-;1228:12;:7;1238:2;1228:12;:::i;:::-;:26;1224:87;;1293:7;1280:10;:6;1289:1;1280:10;:::i;:::-;:20;;;;:::i;:::-;1270:30;;1224:87;-1:-1:-1;1367:19:67;;;;:13;:19;;;;;;;;:28;;;;;;;;;;;;838:564;;-1:-1:-1;838:564:67:o;3295:1462::-;3591:4;3578:18;3396:12;;3720:1;3710:12;;3694:29;;3691:77;;;3752:1;3749;3742:12;3691:77;4011:3;4007:14;;;3911:4;3995:27;4042:11;4016:4;4161:16;4042:11;4143:41;4374:29;;;4378:11;4374:29;4368:36;4426:20;;;;4573:19;4566:27;4595:11;4563:44;4626:19;;;;4604:1;4626:19;;;;;;;;:32;;;;;;;;:39;;;;4661:4;4626:39;;;;;;4675:18;;;;;;;;:31;;;;;;;;;:38;;;;4723:20;;;;;;;;;;;:27;;;;-1:-1:-1;;;;3295:1462:67:o;14:248:283:-;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:283;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:283:o;641:347::-;692:8;702:6;756:3;749:4;741:6;737:17;733:27;723:55;;774:1;771;764:12;723:55;-1:-1:-1;797:20:283;;840:18;829:30;;826:50;;;872:1;869;862:12;826:50;909:4;901:6;897:17;885:29;;961:3;954:4;945:6;937;933:19;929:30;926:39;923:59;;;978:1;975;968:12;923:59;641:347;;;;;:::o;993:409::-;1063:6;1071;1124:2;1112:9;1103:7;1099:23;1095:32;1092:52;;;1140:1;1137;1130:12;1092:52;1180:9;1167:23;1213:18;1205:6;1202:30;1199:50;;;1245:1;1242;1235:12;1199:50;1284:58;1334:7;1325:6;1314:9;1310:22;1284:58;:::i;:::-;1361:8;;1258:84;;-1:-1:-1;993:409:283;-1:-1:-1;;;;993:409:283:o;1660:477::-;1739:6;1747;1755;1808:2;1796:9;1787:7;1783:23;1779:32;1776:52;;;1824:1;1821;1814:12;1776:52;1860:9;1847:23;1837:33;;1921:2;1910:9;1906:18;1893:32;1948:18;1940:6;1937:30;1934:50;;;1980:1;1977;1970:12;1934:50;2019:58;2069:7;2060:6;2049:9;2045:22;2019:58;:::i;:::-;1660:477;;2096:8;;-1:-1:-1;1993:84:283;;-1:-1:-1;;;;1660:477:283:o;2142:385::-;2228:6;2236;2244;2252;2305:3;2293:9;2284:7;2280:23;2276:33;2273:53;;;2322:1;2319;2312:12;2273:53;-1:-1:-1;;2345:23:283;;;2415:2;2400:18;;2387:32;;-1:-1:-1;2466:2:283;2451:18;;2438:32;;2517:2;2502:18;2489:32;;-1:-1:-1;2142:385:283;-1:-1:-1;2142:385:283:o;2532:180::-;2591:6;2644:2;2632:9;2623:7;2619:23;2615:32;2612:52;;;2660:1;2657;2650:12;2612:52;-1:-1:-1;2683:23:283;;2532:180;-1:-1:-1;2532:180:283:o;3248:184::-;3300:77;3297:1;3290:88;3397:4;3394:1;3387:15;3421:4;3418:1;3411:15;3437:128;3477:3;3508:1;3504:6;3501:1;3498:13;3495:39;;;3514:18;;:::i;:::-;-1:-1:-1;3550:9:283;;3437:128::o;3570:125::-;3610:4;3638:1;3635;3632:8;3629:34;;;3643:18;;:::i;:::-;-1:-1:-1;3680:9:283;;3570:125::o"
func init() { func init() {
if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil { if err := json.Unmarshal([]byte(PreimageOracleStorageLayoutJSON), PreimageOracleStorageLayout); err != nil {
......
...@@ -22,6 +22,7 @@ type flags struct { ...@@ -22,6 +22,7 @@ type flags struct {
SourceMaps string SourceMaps string
OutDir string OutDir string
Package string Package string
MonorepoBase string
} }
type data struct { type data struct {
...@@ -39,8 +40,14 @@ func main() { ...@@ -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.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.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.Package, "package", "artifacts", "Go package name")
flag.StringVar(&f.MonorepoBase, "monorepo-base", "", "Base of the monorepo")
flag.Parse() 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) contractData, err := os.ReadFile(f.Contracts)
if err != nil { if err != nil {
log.Fatal("error reading contract list: %w\n", err) log.Fatal("error reading contract list: %w\n", err)
...@@ -72,21 +79,47 @@ func main() { ...@@ -72,21 +79,47 @@ func main() {
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
log.Printf("created temp dir %s\n", 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 { for _, name := range contracts {
log.Printf("generating code for %s\n", name) 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) { if errors.Is(err, os.ErrNotExist) {
log.Fatalf("cannot find forge-artifact of %q\n", name) 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 var artifact foundry.Artifact
if err := json.Unmarshal(forgeArtifactData, &artifact); err != nil { if err := json.Unmarshal(forgeArtifactData, &artifact); err != nil {
log.Fatalf("failed to parse forge artifact of %q: %v\n", name, err) 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 rawAbi := artifact.Abi
if err != nil { if err != nil {
...@@ -121,7 +154,7 @@ func main() { ...@@ -121,7 +154,7 @@ func main() {
} }
storage := artifact.StorageLayout storage := artifact.StorageLayout
canonicalStorage := ast.CanonicalizeASTIDs(&storage) canonicalStorage := ast.CanonicalizeASTIDs(&storage, f.MonorepoBase)
ser, err := json.Marshal(canonicalStorage) ser, err := json.Marshal(canonicalStorage)
if err != nil { if err != nil {
log.Fatalf("error marshaling storage: %v\n", err) log.Fatalf("error marshaling storage: %v\n", err)
......
...@@ -10,7 +10,6 @@ import ( ...@@ -10,7 +10,6 @@ import (
type Agent struct { type Agent struct {
solver *Solver solver *Solver
trace TraceProvider
loader Loader loader Loader
responder Responder responder Responder
maxDepth int maxDepth int
...@@ -21,7 +20,6 @@ type Agent struct { ...@@ -21,7 +20,6 @@ type Agent struct {
func NewAgent(loader Loader, maxDepth int, trace TraceProvider, responder Responder, agreeWithProposedOutput bool, log log.Logger) Agent { func NewAgent(loader Loader, maxDepth int, trace TraceProvider, responder Responder, agreeWithProposedOutput bool, log log.Logger) Agent {
return Agent{ return Agent{
solver: NewSolver(maxDepth, trace), solver: NewSolver(maxDepth, trace),
trace: trace,
loader: loader, loader: loader,
responder: responder, responder: responder,
maxDepth: maxDepth, maxDepth: maxDepth,
...@@ -102,19 +100,13 @@ func (a *Agent) step(claim Claim, game Game) error { ...@@ -102,19 +100,13 @@ func (a *Agent) step(claim Claim, game Game) error {
a.log.Warn("Failed to get a step", "err", err) a.log.Warn("Failed to get a step", "err", err)
return err return err
} }
stateData, err := a.trace.GetPreimage(step.PreStateTraceIndex)
if err != nil {
a.log.Warn("Failed to get a state data", "err", err)
return err
}
a.log.Info("Performing step", a.log.Info("Performing step", "is_attack", step.IsAttack,
"depth", step.LeafClaim.Depth(), "index_at_depth", step.LeafClaim.IndexAtDepth(), "value", step.LeafClaim.Value, "depth", step.LeafClaim.Depth(), "index_at_depth", step.LeafClaim.IndexAtDepth(), "value", step.LeafClaim.Value)
"is_attack", step.IsAttack, "prestate_trace_index", step.PreStateTraceIndex)
callData := StepCallData{ callData := StepCallData{
ClaimIndex: uint64(step.LeafClaim.ContractIndex), ClaimIndex: uint64(step.LeafClaim.ContractIndex),
IsAttack: step.IsAttack, IsAttack: step.IsAttack,
StateData: stateData, StateData: step.PreState,
} }
return a.responder.Step(context.TODO(), callData) return a.responder.Step(context.TODO(), callData)
} }
...@@ -8,6 +8,8 @@ import ( ...@@ -8,6 +8,8 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
var _ TraceProvider = (*AlphabetProvider)(nil)
// AlphabetProvider is a [TraceProvider] that provides claims for specific // AlphabetProvider is a [TraceProvider] that provides claims for specific
// indices in the given trace. // indices in the given trace.
type AlphabetProvider struct { type AlphabetProvider struct {
...@@ -45,6 +47,12 @@ func (ap *AlphabetProvider) Get(i uint64) (common.Hash, error) { ...@@ -45,6 +47,12 @@ func (ap *AlphabetProvider) Get(i uint64) (common.Hash, error) {
return crypto.Keccak256Hash(claimBytes), nil return crypto.Keccak256Hash(claimBytes), nil
} }
func (ap *AlphabetProvider) AbsolutePreState() []byte {
out := make([]byte, 32)
out[31] = 140 // ascii character 140 is "`"
return out
}
// BuildAlphabetPreimage constructs the claim bytes for the index and state item. // BuildAlphabetPreimage constructs the claim bytes for the index and state item.
func BuildAlphabetPreimage(i uint64, letter string) []byte { func BuildAlphabetPreimage(i uint64, letter string) []byte {
return append(IndexToBytes(i), LetterToBytes(letter)...) return append(IndexToBytes(i), LetterToBytes(letter)...)
......
package examples
import (
"os"
"github.com/ethereum-optimism/optimism/op-challenger/fault"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
func FullGame() {
log.Root().SetHandler(
log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stdout, log.TerminalFormat(true))),
)
canonical := "abcdefgh"
disputed := "abcdexyz"
maxDepth := uint64(3)
canonicalProvider := fault.NewAlphabetProvider(canonical, maxDepth)
disputedProvider := fault.NewAlphabetProvider(disputed, maxDepth)
root := fault.Claim{
ClaimData: fault.ClaimData{
Value: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000077a"),
Position: fault.NewPosition(0, 0),
},
}
o := fault.NewOrchestrator(maxDepth, []fault.TraceProvider{canonicalProvider, disputedProvider}, []string{"charlie", "mallory"}, []bool{false, true}, root)
o.Start()
}
package examples
import (
"github.com/ethereum-optimism/optimism/op-challenger/fault"
)
func PositionExampleOne() {
// Example 1
// abcdefgh
// abcdexyz
// go left to d, then right to f, then left to e
p := fault.Position{}
p.Print(3)
p = p.Attack()
p.Print(3)
p = p.Defend()
p.Print(3)
p = p.Attack()
p.Print(3)
}
func PositionExampleTwo() {
// Example 2
// abcdefgh
// abqrstuv
// go left r, then left to b, then right to q
p := fault.Position{}
p.Print(3)
p = p.Attack()
p.Print(3)
p = p.Attack()
p.Print(3)
p = p.Defend()
p.Print(3)
}
package examples
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum-optimism/optimism/op-challenger/fault"
)
func PrettyPrintAlphabetClaim(name string, claim fault.Claim) {
value := claim.Value
idx := value[30]
letter := value[31]
if claim.IsRoot() {
fmt.Printf("%s\ttrace %v letter %c\n", name, idx, letter)
} else {
fmt.Printf("%s\ttrace %v letter %c is attack %v\n", name, idx, letter, !claim.DefendsParent())
}
}
// SolverExampleOne uses the [fault.Solver] with a [fault.AlphabetProvider]
// to print out fault game traces for the "abcdexyz" counter-state.
func SolverExampleOne() {
fmt.Println("Solver: Example 1")
// Construct the fault position.
canonical := "abcdefgh"
disputed := "abcdexyz"
maxDepth := 3
// Root claim is z at trace index 7 from the disputed provider
root := fault.Claim{
ClaimData: fault.ClaimData{
Value: common.HexToHash("0x000000000000000000000000000000000000000000000000000000000000077a"),
Position: fault.NewPosition(0, 0),
},
}
canonicalProvider := fault.NewAlphabetProvider(canonical, uint64(maxDepth))
disputedProvider := fault.NewAlphabetProvider(disputed, uint64(maxDepth))
// Create a solver with the canonical provider.
cannonicalSolver := fault.NewSolver(maxDepth, canonicalProvider)
disputedSolver := fault.NewSolver(maxDepth, disputedProvider)
// Print the initial state.
fmt.Println("Canonical state: ", canonical)
fmt.Println("Disputed state: ", disputed)
fmt.Println()
fmt.Println("Proceeding with the following moves:")
fmt.Println("go left to d, then right to x (cannonical is f), then left to e")
fmt.Println()
PrettyPrintAlphabetClaim("Root claim", root)
claim1, err := cannonicalSolver.NextMove(root, false)
if err != nil {
fmt.Printf("error getting claim from provider: %v", err)
}
PrettyPrintAlphabetClaim("Cannonical move", *claim1)
claim2, err := disputedSolver.NextMove(*claim1, false)
if err != nil {
fmt.Printf("error getting claim from provider: %v", err)
}
PrettyPrintAlphabetClaim("Disputed moved", *claim2)
claim3, err := cannonicalSolver.NextMove(*claim2, false)
if err != nil {
fmt.Printf("error getting claim from provider: %v", err)
}
PrettyPrintAlphabetClaim("Cannonical move", *claim3)
}
package main
import (
"github.com/ethereum-optimism/optimism/op-challenger/fault/cmd/examples"
)
func main() {
examples.FullGame()
// examples.SolverExampleOne()
// examples.PositionExampleOne()
// examples.PositionExampleTwo()
}
...@@ -26,14 +26,6 @@ type Game interface { ...@@ -26,14 +26,6 @@ type Game interface {
// IsDuplicate returns true if the provided [Claim] already exists in the game state. // IsDuplicate returns true if the provided [Claim] already exists in the game state.
IsDuplicate(claim Claim) bool IsDuplicate(claim Claim) bool
// PreStateClaim gets the claim which commits to the pre-state of this specific claim.
// This will return an error if it is called with a non-leaf claim.
PreStateClaim(claim Claim) (Claim, error)
// PostStateClaim gets the claim which commits to the post-state of this specific claim.
// This will return an error if it is called with a non-leaf claim.
PostStateClaim(claim Claim) (Claim, error)
// AgreeWithLevel returns if the game state agrees with the provided claim level. // AgreeWithLevel returns if the game state agrees with the provided claim level.
AgreeWithClaimLevel(claim Claim) bool AgreeWithClaimLevel(claim Claim) bool
} }
...@@ -140,45 +132,3 @@ func (g *gameState) getParent(claim Claim) (Claim, error) { ...@@ -140,45 +132,3 @@ func (g *gameState) getParent(claim Claim) (Claim, error) {
return parent.self, nil return parent.self, nil
} }
} }
func (g *gameState) PreStateClaim(claim Claim) (Claim, error) {
// Do checks in PreStateClaim because these do not hold while walking the tree
if claim.Depth() != int(g.depth) {
return Claim{}, errors.New("Only leaf claims have pre or post state")
}
// If the claim is the far left most claim, the pre-state is pulled from the contracts & we can supply at contract index.
if claim.IndexAtDepth() == 0 {
return Claim{
ContractIndex: -1,
}, nil
}
return g.preStateClaim(claim)
}
// preStateClaim is the internal tree walker which does not do error handling
func (g *gameState) preStateClaim(claim Claim) (Claim, error) {
parent, _ := g.getParent(claim)
if claim.DefendsParent() {
return parent, nil
} else {
return g.preStateClaim(parent)
}
}
func (g *gameState) PostStateClaim(claim Claim) (Claim, error) {
// Do checks in PostStateClaim because these do not hold while walking the tree
if claim.Depth() != int(g.depth) {
return Claim{}, errors.New("Only leaf claims have pre or post state")
}
return g.postStateClaim(claim)
}
// postStateClaim is the internal tree walker which does not do error handling
func (g *gameState) postStateClaim(claim Claim) (Claim, error) {
parent, _ := g.getParent(claim)
if claim.DefendsParent() {
return g.postStateClaim(parent)
} else {
return parent, nil
}
}
...@@ -195,46 +195,6 @@ func TestGame_ClaimPairs(t *testing.T) { ...@@ -195,46 +195,6 @@ func TestGame_ClaimPairs(t *testing.T) {
require.ElementsMatch(t, expected, claims) require.ElementsMatch(t, expected, claims)
} }
// TestPrePostStateOnlyOnLeafClaim tests that if PreStateClaim or PostStateClaim is called with an non-leaf claim
// those functions return an error.
func TestPrePostStateOnlyOnLeafClaim(t *testing.T) {
root, top, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.PutAll([]Claim{top, middle, bottom}))
_, err := g.PreStateClaim(middle)
require.Error(t, err)
_, err = g.PostStateClaim(middle)
require.Error(t, err)
}
func TestPreStateClaim(t *testing.T) {
root, top, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.Put(top))
require.NoError(t, g.Put(middle))
require.NoError(t, g.Put(bottom))
// Bottom trace index is 4. Pre trace index is then 3
pre, err := g.PreStateClaim(bottom)
require.NoError(t, err)
require.Equal(t, top, pre)
}
func TestPostStateClaim(t *testing.T) {
root, top, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.Put(top))
require.NoError(t, g.Put(middle))
require.NoError(t, g.Put(bottom))
// Bottom trace index is 4. Post trace index is then 5
post, err := g.PostStateClaim(bottom)
require.NoError(t, err)
require.Equal(t, middle, post)
}
func TestAgreeWithClaimLevelDisagreeWithOutput(t *testing.T) { func TestAgreeWithClaimLevelDisagreeWithOutput(t *testing.T) {
// Setup the game state. // Setup the game state.
root, top, middle, bottom := createTestClaims() root, top, middle, bottom := createTestClaims()
......
package fault
import (
"context"
"github.com/ethereum/go-ethereum/log"
)
type Orchestrator struct {
agents []Agent
claims []Claim
steps []StepCallData
// tracking when to exit
claimLen, stepLen, step int
}
func NewOrchestrator(maxDepth uint64, traces []TraceProvider, names []string, agreeWithProposedOutput []bool, root Claim) Orchestrator {
o := Orchestrator{
agents: make([]Agent, len(traces)),
claims: []Claim{root},
steps: make([]StepCallData, 0),
}
log.Info("Starting game", "root_letter", string(root.Value[31:]))
for i, trace := range traces {
o.agents[i] = NewAgent(&o, int(maxDepth), trace, &o, agreeWithProposedOutput[i], log.New("role", names[i]))
}
return o
}
func (o *Orchestrator) Respond(_ context.Context, response Claim) error {
response.ContractIndex = len(o.claims)
o.claims = append(o.claims, response)
return nil
}
func (o *Orchestrator) Step(_ context.Context, stepData StepCallData) error {
log.Info("Step recorded", "step", stepData)
o.steps = append(o.steps, stepData)
return nil
}
func (o *Orchestrator) FetchClaims(ctx context.Context) ([]Claim, error) {
c := make([]Claim, len(o.claims))
copy(c, o.claims)
return c, nil
}
func (o *Orchestrator) Start() {
for {
for _, a := range o.agents {
_ = a.Act()
}
if o.shouldExit() {
log.Info("exiting")
return
}
}
}
func (o *Orchestrator) shouldExit() bool {
cl := o.claimLen
sl := o.stepLen
o.claimLen = len(o.claims)
o.stepLen = len(o.steps)
noProgress := o.claimLen == cl && o.stepLen == sl
if noProgress {
o.step = o.step + 1
} else {
o.step = 0
}
return noProgress && o.step == 1
}
...@@ -36,27 +36,29 @@ type testNodeInfo struct { ...@@ -36,27 +36,29 @@ type testNodeInfo struct {
Depth int Depth int
IndexAtDepth int IndexAtDepth int
TraceIndex uint64 TraceIndex uint64
AttackGIndex uint64 // 0 indicates attack is not possible from this node
DefendGIndex uint64 // 0 indicates defend is not possible from this node
} }
var treeNodesMaxDepth4 = []testNodeInfo{ var treeNodesMaxDepth4 = []testNodeInfo{
{GIndex: 1, Depth: 0, IndexAtDepth: 0, TraceIndex: 15}, {GIndex: 1, Depth: 0, IndexAtDepth: 0, TraceIndex: 15, AttackGIndex: 2},
{GIndex: 2, Depth: 1, IndexAtDepth: 0, TraceIndex: 7}, {GIndex: 2, Depth: 1, IndexAtDepth: 0, TraceIndex: 7, AttackGIndex: 4, DefendGIndex: 6},
{GIndex: 3, Depth: 1, IndexAtDepth: 1, TraceIndex: 15}, {GIndex: 3, Depth: 1, IndexAtDepth: 1, TraceIndex: 15, AttackGIndex: 6},
{GIndex: 4, Depth: 2, IndexAtDepth: 0, TraceIndex: 3}, {GIndex: 4, Depth: 2, IndexAtDepth: 0, TraceIndex: 3, AttackGIndex: 8, DefendGIndex: 10},
{GIndex: 5, Depth: 2, IndexAtDepth: 1, TraceIndex: 7}, {GIndex: 5, Depth: 2, IndexAtDepth: 1, TraceIndex: 7, AttackGIndex: 10},
{GIndex: 6, Depth: 2, IndexAtDepth: 2, TraceIndex: 11}, {GIndex: 6, Depth: 2, IndexAtDepth: 2, TraceIndex: 11, AttackGIndex: 12, DefendGIndex: 14},
{GIndex: 7, Depth: 2, IndexAtDepth: 3, TraceIndex: 15}, {GIndex: 7, Depth: 2, IndexAtDepth: 3, TraceIndex: 15, AttackGIndex: 14},
{GIndex: 8, Depth: 3, IndexAtDepth: 0, TraceIndex: 1}, {GIndex: 8, Depth: 3, IndexAtDepth: 0, TraceIndex: 1, AttackGIndex: 16, DefendGIndex: 18},
{GIndex: 9, Depth: 3, IndexAtDepth: 1, TraceIndex: 3}, {GIndex: 9, Depth: 3, IndexAtDepth: 1, TraceIndex: 3, AttackGIndex: 18},
{GIndex: 10, Depth: 3, IndexAtDepth: 2, TraceIndex: 5}, {GIndex: 10, Depth: 3, IndexAtDepth: 2, TraceIndex: 5, AttackGIndex: 20, DefendGIndex: 22},
{GIndex: 11, Depth: 3, IndexAtDepth: 3, TraceIndex: 7}, {GIndex: 11, Depth: 3, IndexAtDepth: 3, TraceIndex: 7, AttackGIndex: 22},
{GIndex: 12, Depth: 3, IndexAtDepth: 4, TraceIndex: 9}, {GIndex: 12, Depth: 3, IndexAtDepth: 4, TraceIndex: 9, AttackGIndex: 24, DefendGIndex: 26},
{GIndex: 13, Depth: 3, IndexAtDepth: 5, TraceIndex: 11}, {GIndex: 13, Depth: 3, IndexAtDepth: 5, TraceIndex: 11, AttackGIndex: 26},
{GIndex: 14, Depth: 3, IndexAtDepth: 6, TraceIndex: 13}, {GIndex: 14, Depth: 3, IndexAtDepth: 6, TraceIndex: 13, AttackGIndex: 28, DefendGIndex: 30},
{GIndex: 15, Depth: 3, IndexAtDepth: 7, TraceIndex: 15}, {GIndex: 15, Depth: 3, IndexAtDepth: 7, TraceIndex: 15, AttackGIndex: 30},
{GIndex: 16, Depth: 4, IndexAtDepth: 0, TraceIndex: 0}, {GIndex: 16, Depth: 4, IndexAtDepth: 0, TraceIndex: 0},
{GIndex: 17, Depth: 4, IndexAtDepth: 1, TraceIndex: 1}, {GIndex: 17, Depth: 4, IndexAtDepth: 1, TraceIndex: 1},
...@@ -95,3 +97,25 @@ func TestTraceIndex(t *testing.T) { ...@@ -95,3 +97,25 @@ func TestTraceIndex(t *testing.T) {
require.Equal(t, test.TraceIndex, result) require.Equal(t, test.TraceIndex, result)
} }
} }
func TestAttack(t *testing.T) {
for _, test := range treeNodesMaxDepth4 {
if test.AttackGIndex == 0 {
continue
}
pos := NewPosition(test.Depth, test.IndexAtDepth)
result := pos.Attack()
require.Equalf(t, test.AttackGIndex, result.ToGIndex(), "Attack from GIndex %v", pos.ToGIndex())
}
}
func TestDefend(t *testing.T) {
for _, test := range treeNodesMaxDepth4 {
if test.DefendGIndex == 0 {
continue
}
pos := NewPosition(test.Depth, test.IndexAtDepth)
result := pos.Defend()
require.Equalf(t, test.DefendGIndex, result.ToGIndex(), "Defend from GIndex %v", pos.ToGIndex())
}
}
...@@ -64,9 +64,9 @@ func (s *Solver) handleMiddle(claim Claim) (*Claim, error) { ...@@ -64,9 +64,9 @@ func (s *Solver) handleMiddle(claim Claim) (*Claim, error) {
} }
type StepData struct { type StepData struct {
LeafClaim Claim LeafClaim Claim
IsAttack bool IsAttack bool
PreStateTraceIndex uint64 PreState []byte
} }
// AttemptStep determines what step should occur for a given leaf claim. // AttemptStep determines what step should occur for a given leaf claim.
...@@ -80,14 +80,25 @@ func (s *Solver) AttemptStep(claim Claim) (StepData, error) { ...@@ -80,14 +80,25 @@ func (s *Solver) AttemptStep(claim Claim) (StepData, error) {
return StepData{}, err return StepData{}, err
} }
index := claim.TraceIndex(s.gameDepth) index := claim.TraceIndex(s.gameDepth)
// TODO(CLI-4198): Handle case where we dispute trace index 0 var preState []byte
if !claimCorrect { // If we are attacking index 0, we provide the absolute pre-state, not an intermediate state
index -= 1 if index == 0 && !claimCorrect {
preState = s.AbsolutePreState()
} else {
// If attacking, get the state just before, other get the state after
if !claimCorrect {
index = index - 1
}
preState, err = s.GetPreimage(index)
if err != nil {
return StepData{}, err
}
} }
return StepData{ return StepData{
LeafClaim: claim, LeafClaim: claim,
IsAttack: !claimCorrect, IsAttack: !claimCorrect,
PreStateTraceIndex: index, PreState: preState,
}, nil }, nil
} }
......
...@@ -102,17 +102,27 @@ func TestAttemptStep(t *testing.T) { ...@@ -102,17 +102,27 @@ func TestAttemptStep(t *testing.T) {
maxDepth := 3 maxDepth := 3
canonicalProvider := NewAlphabetProvider("abcdefgh", uint64(maxDepth)) canonicalProvider := NewAlphabetProvider("abcdefgh", uint64(maxDepth))
solver := NewSolver(maxDepth, canonicalProvider) solver := NewSolver(maxDepth, canonicalProvider)
root, top, middle, bottom := createTestClaims() _, _, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.Put(top)) zero := Claim{
require.NoError(t, g.Put(middle)) ClaimData: ClaimData{
require.NoError(t, g.Put(bottom)) // Zero value is a purposely disagree with claim value "a"
Position: NewPosition(3, 0),
},
}
step, err := solver.AttemptStep(bottom) step, err := solver.AttemptStep(bottom)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, bottom, step.LeafClaim) require.Equal(t, bottom, step.LeafClaim)
require.True(t, step.IsAttack) require.True(t, step.IsAttack)
require.Equal(t, step.PreState, BuildAlphabetPreimage(3, "d"))
_, err = solver.AttemptStep(middle) _, err = solver.AttemptStep(middle)
require.Error(t, err) require.Error(t, err)
step, err = solver.AttemptStep(zero)
require.NoError(t, err)
require.Equal(t, zero, step.LeafClaim)
require.True(t, step.IsAttack)
require.Equal(t, canonicalProvider.AbsolutePreState(), step.PreState)
} }
...@@ -22,10 +22,12 @@ type StepCallData struct { ...@@ -22,10 +22,12 @@ type StepCallData struct {
// TraceProvider is a generic way to get a claim value at a specific // TraceProvider is a generic way to get a claim value at a specific
// step in the trace. // step in the trace.
// The [AlphabetProvider] is a minimal implementation of this interface. // Get(i) = Keccak256(GetPreimage(i))
// AbsolutePreState is the value of the trace that transitions to the trace value at index 0
type TraceProvider interface { type TraceProvider interface {
Get(i uint64) (common.Hash, error) Get(i uint64) (common.Hash, error)
GetPreimage(i uint64) ([]byte, error) GetPreimage(i uint64) ([]byte, error)
AbsolutePreState() []byte
} }
// ClaimData is the core of a claim. It must be unique inside a specific game. // ClaimData is the core of a claim. It must be unique inside a specific game.
......
...@@ -76,7 +76,7 @@ func TestERC20BridgeDeposits(t *testing.T) { ...@@ -76,7 +76,7 @@ func TestERC20BridgeDeposits(t *testing.T) {
// Approve WETH9 with the bridge // Approve WETH9 with the bridge
tx, err = WETH9.Approve(opts, predeploys.DevL1StandardBridgeAddr, new(big.Int).SetUint64(math.MaxUint64)) tx, err = WETH9.Approve(opts, predeploys.DevL1StandardBridgeAddr, new(big.Int).SetUint64(math.MaxUint64))
require.NoError(t, err) require.NoError(t, err)
_, err = waitForTransaction(tx.Hash(), l1Client, 3*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) _, err = waitForTransaction(tx.Hash(), l1Client, 6*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
require.NoError(t, err) require.NoError(t, err)
// Bridge the WETH9 // Bridge the WETH9
......
...@@ -300,23 +300,25 @@ func createGethNode(l2 bool, nodeCfg *node.Config, ethCfg *ethconfig.Config, pri ...@@ -300,23 +300,25 @@ func createGethNode(l2 bool, nodeCfg *node.Config, ethCfg *ethconfig.Config, pri
return nil, nil, err return nil, nil, err
} }
keydir := n.KeyStoreDir() if !l2 {
scryptN := 2 keydir := n.KeyStoreDir()
scryptP := 1 scryptN := 2
n.AccountManager().AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP)) scryptP := 1
ks := n.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) n.AccountManager().AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP))
ks := n.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
password := "foobar"
for _, pk := range privateKeys { password := "foobar"
act, err := ks.ImportECDSA(pk, password) for _, pk := range privateKeys {
if err != nil { act, err := ks.ImportECDSA(pk, password)
n.Close() if err != nil {
return nil, nil, err n.Close()
} return nil, nil, err
err = ks.Unlock(act, password) }
if err != nil { err = ks.Unlock(act, password)
n.Close() if err != nil {
return nil, nil, err n.Close()
return nil, nil, err
}
} }
} }
...@@ -341,5 +343,4 @@ func createGethNode(l2 bool, nodeCfg *node.Config, ethCfg *ethconfig.Config, pri ...@@ -341,5 +343,4 @@ func createGethNode(l2 bool, nodeCfg *node.Config, ethCfg *ethconfig.Config, pri
} }
} }
return n, backend, nil return n, backend, nil
} }
...@@ -1279,7 +1279,7 @@ func TestStopStartBatcher(t *testing.T) { ...@@ -1279,7 +1279,7 @@ func TestStopStartBatcher(t *testing.T) {
receipt := sendTx() receipt := sendTx()
// wait until the block the tx was first included in shows up in the safe chain on the verifier // wait until the block the tx was first included in shows up in the safe chain on the verifier
safeBlockInclusionDuration := time.Duration(3*cfg.DeployConfig.L1BlockTime) * time.Second safeBlockInclusionDuration := time.Duration(6*cfg.DeployConfig.L1BlockTime) * time.Second
_, err = waitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration) _, err = waitForBlock(receipt.BlockNumber, l2Verif, safeBlockInclusionDuration)
require.Nil(t, err, "Waiting for block on verifier") require.Nil(t, err, "Waiting for block on verifier")
......
...@@ -59,7 +59,11 @@ func (cfg *L2EndpointConfig) Setup(ctx context.Context, log log.Logger, rollupCf ...@@ -59,7 +59,11 @@ func (cfg *L2EndpointConfig) Setup(ctx context.Context, log log.Logger, rollupCf
return nil, nil, err return nil, nil, err
} }
auth := rpc.WithHTTPAuth(gn.NewJWTAuth(cfg.L2EngineJWTSecret)) auth := rpc.WithHTTPAuth(gn.NewJWTAuth(cfg.L2EngineJWTSecret))
l2Node, err := client.NewRPC(ctx, log, cfg.L2EngineAddr, client.WithGethRPCOptions(auth)) opts := []client.RPCOption{
client.WithGethRPCOptions(auth),
client.WithDialBackoff(10),
}
l2Node, err := client.NewRPC(ctx, log, cfg.L2EngineAddr, opts...)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
......
...@@ -56,7 +56,9 @@ RUN apt-get update && \ ...@@ -56,7 +56,9 @@ RUN apt-get update && \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.48.0 && \ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.48.0 && \
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | bash
RUN echo "downloading pnpm" && npm i -g pnpm # We need to isntall yarn because a bespoke dependency installed from github https://codeload.github.com/Saw-mon-and-Natalie/clones-with-immutable-arg needs it
# it is installed from github which means it's postpack script which uses yarn is ran when unpacked into node_modules
RUN echo "downloading pnpm and yarn" && npm i -g pnpm && npm i -g yarn@1 && pnpm --version && yarn --version
RUN echo "downloading solidity compilers" && \ RUN echo "downloading solidity compilers" && \
curl -o solc-linux-amd64-v0.5.17+commit.d19bba13 -sL https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.5.17+commit.d19bba13 && \ curl -o solc-linux-amd64-v0.5.17+commit.d19bba13 -sL https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.5.17+commit.d19bba13 && \
......
...@@ -7,7 +7,7 @@ import { ...@@ -7,7 +7,7 @@ import {
} from '@eth-optimism/common-ts' } from '@eth-optimism/common-ts'
import { Provider } from '@ethersproject/abstract-provider' import { Provider } from '@ethersproject/abstract-provider'
import { ethers } from 'ethers' 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' 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_acrossMultipleWords_works() (gas: 9413)
Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1430) Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1430)
Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17240) Bytes_slice_Test:test_slice_fromNonZeroIdx_works() (gas: 17240)
...@@ -32,12 +50,49 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert ...@@ -32,12 +50,49 @@ DisputeGameFactory_SetImplementation_Test:test_setImplementation_notOwner_revert
DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243) DisputeGameFactory_SetImplementation_Test:test_setImplementation_succeeds() (gas: 44243)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_notOwner_reverts() (gas: 15950)
DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642) DisputeGameFactory_TransferOwnership_Test:test_transferOwnership_succeeds() (gas: 18642)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 491839) Drippie_Test:test_create_calledTwice_reverts() (gas: 168931)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 495751) Drippie_Test:test_create_succeeds() (gas: 183380)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 495049) Drippie_Test:test_drip_amount_succeeds() (gas: 285294)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 490600) Drippie_Test:test_drip_notExist_reverts() (gas: 14876)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 494512) Drippie_Test:test_drip_reentrant_reverts() (gas: 18853)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 493810) 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: 498900)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 503381)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 502679)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 505608)
FaultDisputeGame_ResolvesCorrectly_CorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 504939)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1:test_resolvesCorrectly_succeeds() (gas: 497692)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2:test_resolvesCorrectly_succeeds() (gas: 502173)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3:test_resolvesCorrectly_succeeds() (gas: 501471)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4:test_resolvesCorrectly_succeeds() (gas: 502373)
FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5:test_resolvesCorrectly_succeeds() (gas: 501731)
FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426) FaultDisputeGame_Test:test_extraData_succeeds() (gas: 17426)
FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917) FaultDisputeGame_Test:test_gameData_succeeds() (gas: 17917)
FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315) FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10315)
...@@ -331,6 +386,53 @@ OptimismPortal_Test:test_receive_succeeds() (gas: 127513) ...@@ -331,6 +386,53 @@ OptimismPortal_Test:test_receive_succeeds() (gas: 127513)
OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 32971) OptimismPortal_Test:test_simple_isOutputFinalized_succeeds() (gas: 32971)
OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46098) OptimismPortal_Test:test_unpause_onlyGuardian_reverts() (gas: 46098)
OptimismPortal_Test:test_unpause_succeeds() (gas: 31756) 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_computePreimageKey_succeeds() (gas: 6267)
PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (gas: 9025) PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (gas: 9025)
PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 77552) PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 77552)
...@@ -463,5 +565,10 @@ SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas: ...@@ -463,5 +565,10 @@ SystemConfig_Setters_TestFail:test_setResourceConfig_lowGasLimit_reverts() (gas:
SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 11790) SystemConfig_Setters_TestFail:test_setResourceConfig_notOwner_reverts() (gas: 11790)
SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 13039) SystemConfig_Setters_TestFail:test_setResourceConfig_zeroDenominator_reverts() (gas: 13039)
SystemConfig_Setters_TestFail:test_setUnsafeBlockSigner_notOwner_reverts() (gas: 10616) 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_constructor_succeeds() (gas: 564855)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955) TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
...@@ -59,7 +59,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -59,7 +59,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
Claim _absolutePrestate, Claim _absolutePrestate,
uint256 _maxGameDepth, uint256 _maxGameDepth,
IBigStepper _vm IBigStepper _vm
) Semver(0, 0, 2) { ) Semver(0, 0, 3) {
ABSOLUTE_PRESTATE = _absolutePrestate; ABSOLUTE_PRESTATE = _absolutePrestate;
MAX_GAME_DEPTH = _maxGameDepth; MAX_GAME_DEPTH = _maxGameDepth;
VM = _vm; VM = _vm;
...@@ -92,7 +92,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -92,7 +92,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// Determine the expected pre & post states of the step. // Determine the expected pre & post states of the step.
Claim preStateClaim; Claim preStateClaim;
Claim postStateClaim; ClaimData storage postState;
if (_isAttack) { if (_isAttack) {
if (stepPos.indexAtDepth() == 0) { if (stepPos.indexAtDepth() == 0) {
// If the step position's index at depth is 0, the prestate is the absolute // If the step position's index at depth is 0, the prestate is the absolute
...@@ -104,16 +104,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -104,16 +104,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
preStateClaim = findTraceAncestor( preStateClaim = findTraceAncestor(
Position.wrap(Position.unwrap(parentPos) - 1), Position.wrap(Position.unwrap(parentPos) - 1),
parent.parentIndex parent.parentIndex
); ).claim;
} }
// For all attacks, the poststate is the parent claim. // For all attacks, the poststate is the parent claim.
postStateClaim = parent.claim; postState = parent;
} else { } else {
// If the step is a defense, the poststate exists elsewhere in the game state, // If the step is a defense, the poststate exists elsewhere in the game state,
// and the parent claim is the expected pre-state. // and the parent claim is the expected pre-state.
preStateClaim = parent.claim; preStateClaim = parent.claim;
postStateClaim = findTraceAncestor( postState = findTraceAncestor(
Position.wrap(Position.unwrap(parentPos) + 1), Position.wrap(Position.unwrap(parentPos) + 1),
parent.parentIndex parent.parentIndex
); );
...@@ -123,10 +123,21 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -123,10 +123,21 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// preimage of the prestate claim hash. // preimage of the prestate claim hash.
if (keccak256(_stateData) != Claim.unwrap(preStateClaim)) revert InvalidPrestate(); if (keccak256(_stateData) != Claim.unwrap(preStateClaim)) revert InvalidPrestate();
// INVARIANT: A VM step can never counter a parent claim unless it produces a poststate // INVARIANT: If a step is an attack, the poststate is valid if the step produces
// that is not equal to the claim at `_parentIndex` if the step is an attack, // the same poststate hash as the parent claim's value.
// or the claim at `_stateIndex` if the step is a defense. // If a step is a defense:
if (VM.step(_stateData, _proof) == Claim.unwrap(postStateClaim)) revert ValidStep(); // 1. If the parent claim and the found post state agree with each other
// (depth diff % 2 == 0), the step is valid if it produces the same
// state hash as the post state's claim.
// 2. If the parent claim and the found post state disagree with each other
// (depth diff % 2 != 0), the parent cannot be countered unless the step
// produces the same state hash as `postState.claim`.
// SAFETY: While the `attack` path does not need an extra check for the post
// state's depth in relation to the parent, we don't need another
// branch because (n - n) % 2 == 0.
bool validStep = VM.step(_stateData, _proof) == Claim.unwrap(postState.claim);
bool parentPostAgree = (parentPos.depth() - postState.position.depth()) % 2 == 0;
if ((parentPostAgree && validStep) || (!parentPostAgree && !validStep)) revert ValidStep();
// Set the parent claim as countered. We do not need to append a new claim to the game; // Set the parent claim as countered. We do not need to append a new claim to the game;
// instead, we can just set the existing parent as countered. // instead, we can just set the existing parent as countered.
...@@ -384,17 +395,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver { ...@@ -384,17 +395,16 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
function findTraceAncestor(Position _pos, uint256 _start) function findTraceAncestor(Position _pos, uint256 _start)
internal internal
view view
returns (Claim ancestor_) returns (ClaimData storage ancestor_)
{ {
// Grab the trace ancestor's expected position. // Grab the trace ancestor's expected position.
Position preStateTraceAncestor = _pos.traceAncestor(); Position preStateTraceAncestor = _pos.traceAncestor();
// Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is // Walk up the DAG to find a claim that commits to the same trace index as `_pos`. It is
// guaranteed that such a claim exists. // guaranteed that such a claim exists.
ClaimData storage ancestor = claimData[_start]; ancestor_ = claimData[_start];
while (Position.unwrap(ancestor.position) != Position.unwrap(preStateTraceAncestor)) { while (Position.unwrap(ancestor_.position) != Position.unwrap(preStateTraceAncestor)) {
ancestor = claimData[ancestor.parentIndex]; ancestor_ = claimData[ancestor_.parentIndex];
} }
ancestor_ = ancestor.claim;
} }
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { AssetReceiver } from "../AssetReceiver.sol"; import { AssetReceiver } from "../AssetReceiver.sol";
import { IDripCheck } from "./IDripCheck.sol"; import { IDripCheck } from "./IDripCheck.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { IDripCheck } from "../IDripCheck.sol"; import { IDripCheck } from "../IDripCheck.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol"; import { Semver } from "../../universal/Semver.sol";
/** /**
* @title AttestationStation * @title AttestationStation
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Semver } from "@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol"; import { Semver } from "../../universal/Semver.sol";
import { import {
ERC721BurnableUpgradeable ERC721BurnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; 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 { AttestationStation } from "./AttestationStation.sol";
import { OptimistConstants } from "./libraries/OptimistConstants.sol"; import { OptimistConstants } from "./libraries/OptimistConstants.sol";
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { OptimistConstants } from "./libraries/OptimistConstants.sol"; 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 { AttestationStation } from "./AttestationStation.sol";
import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import { import {
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { AdminFaucetAuthModule } from "../universal/faucet/authmodules/AdminFaucetAuthModule.sol"; import { AdminFaucetAuthModule } from "../periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
import { Faucet } from "../universal/faucet/Faucet.sol"; import { Faucet } from "../periphery/faucet/Faucet.sol";
import { FaucetHelper } from "../testing/helpers/FaucetHelper.sol"; import { FaucetHelper } from "./Helpers.sol";
/** /**
* @title AdminFaucetAuthModuleTest * @title AdminFaucetAuthModuleTest
...@@ -104,7 +104,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -104,7 +104,7 @@ contract AdminFaucetAuthModuleTest is Test {
/** /**
* @notice assert that verify returns true for valid proofs signed by admins. * @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(); bytes32 nonce = faucetHelper.consumeNonce();
address fundsReceiver = makeAddr("fundsReceiver"); address fundsReceiver = makeAddr("fundsReceiver");
bytes memory proof = issueProofWithEIP712Domain( bytes memory proof = issueProofWithEIP712Domain(
...@@ -132,7 +132,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -132,7 +132,7 @@ contract AdminFaucetAuthModuleTest is Test {
/** /**
* @notice assert that verify returns false for proofs signed by nonadmins. * @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(); bytes32 nonce = faucetHelper.consumeNonce();
address fundsReceiver = makeAddr("fundsReceiver"); address fundsReceiver = makeAddr("fundsReceiver");
bytes memory proof = issueProofWithEIP712Domain( bytes memory proof = issueProofWithEIP712Domain(
...@@ -161,7 +161,7 @@ contract AdminFaucetAuthModuleTest is Test { ...@@ -161,7 +161,7 @@ contract AdminFaucetAuthModuleTest is Test {
* @notice assert that verify returns false for proofs where the id in the proof is different * @notice assert that verify returns false for proofs where the id in the proof is different
* than the id in the call to verify. * than the id in the call to verify.
*/ */
function test_proofWithWrongId_verify_returnsFalse() external { function test_proofWithWrongId_verify_succeeds() external {
bytes32 nonce = faucetHelper.consumeNonce(); bytes32 nonce = faucetHelper.consumeNonce();
address fundsReceiver = makeAddr("fundsReceiver"); address fundsReceiver = makeAddr("fundsReceiver");
address randomAddress = makeAddr("randomAddress"); address randomAddress = makeAddr("randomAddress");
......
...@@ -3,9 +3,9 @@ pragma solidity 0.8.15; ...@@ -3,9 +3,9 @@ pragma solidity 0.8.15;
/* Testing utilities */ /* Testing utilities */
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { TestERC20 } from "../testing/helpers/TestERC20.sol"; import { TestERC20 } from "./Helpers.sol";
import { TestERC721 } from "../testing/helpers/TestERC721.sol"; import { TestERC721 } from "./Helpers.sol";
import { AssetReceiver } from "../universal/AssetReceiver.sol"; import { AssetReceiver } from "../periphery/AssetReceiver.sol";
contract AssetReceiver_Initializer is Test { contract AssetReceiver_Initializer is Test {
address alice = address(128); address alice = address(128);
...@@ -54,12 +54,12 @@ contract AssetReceiver_Initializer is Test { ...@@ -54,12 +54,12 @@ contract AssetReceiver_Initializer is Test {
contract AssetReceiverTest is AssetReceiver_Initializer { contract AssetReceiverTest is AssetReceiver_Initializer {
// Tests if the owner was set correctly during deploy // Tests if the owner was set correctly during deploy
function test_constructor() external { function test_constructor_succeeds() external {
assertEq(address(alice), assetReceiver.owner()); assertEq(address(alice), assetReceiver.owner());
} }
// Tests that receive works as inteded // Tests that receive works as inteded
function test_receive() external { function test_receive_succeeds() external {
// Check that contract balance is 0 initially // Check that contract balance is 0 initially
assertEq(address(assetReceiver).balance, 0); assertEq(address(assetReceiver).balance, 0);
...@@ -75,7 +75,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -75,7 +75,7 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
} }
// Tests withdrawETH function with only an address as argument, called by owner // 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 // Check contract initial balance
assertEq(address(assetReceiver).balance, 0); assertEq(address(assetReceiver).balance, 0);
// Fund contract with 1 eth and check caller and contract balances // Fund contract with 1 eth and check caller and contract balances
...@@ -97,14 +97,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -97,14 +97,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
} }
// withdrawETH should fail if called by non-owner // withdrawETH should fail if called by non-owner
function testFail_withdrawETH() external { function test_withdrawETH_unauthorized_reverts() external {
vm.deal(address(assetReceiver), 1 ether); vm.deal(address(assetReceiver), 1 ether);
assetReceiver.withdrawETH(payable(alice));
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawETH(payable(alice));
} }
// Similar as withdrawETH but specify amount to withdraw // Similar as withdrawETH but specify amount to withdraw
function test_withdrawETHwithAmount() external { function test_withdrawETHwithAmount_succeeds() external {
assertEq(address(assetReceiver).balance, 0); assertEq(address(assetReceiver).balance, 0);
vm.deal(address(assetReceiver), 1 ether); vm.deal(address(assetReceiver), 1 ether);
...@@ -125,14 +125,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -125,14 +125,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
} }
// withdrawETH with address and amount as arguments called by non-owner // 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); vm.deal(address(assetReceiver), 1 ether);
assetReceiver.withdrawETH(payable(alice), 0.5 ether);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawETH(payable(alice), 0.5 ether);
} }
// Test withdrawERC20 with token and address arguments, from owner // Test withdrawERC20 with token and address arguments, from owner
function test_withdrawERC20() external { function test_withdrawERC20_succeeds() external {
// check balances before the call // check balances before the call
assertEq(testERC20.balanceOf(address(assetReceiver)), 0); assertEq(testERC20.balanceOf(address(assetReceiver)), 0);
...@@ -153,14 +153,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -153,14 +153,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
} }
// Same as withdrawERC20 but call from non-owner // 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); deal(address(testERC20), address(assetReceiver), 100_000);
assetReceiver.withdrawERC20(testERC20, alice);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawERC20(testERC20, alice);
} }
// Similar as withdrawERC20 but specify amount to withdraw // Similar as withdrawERC20 but specify amount to withdraw
function test_withdrawERC20withAmount() external { function test_withdrawERC20withAmount_succeeds() external {
// check balances before the call // check balances before the call
assertEq(testERC20.balanceOf(address(assetReceiver)), 0); assertEq(testERC20.balanceOf(address(assetReceiver)), 0);
...@@ -181,14 +181,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -181,14 +181,14 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
} }
// Similar as withdrawERC20 with amount but call from non-owner // 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); deal(address(testERC20), address(assetReceiver), 100_000);
assetReceiver.withdrawERC20(testERC20, alice, 50_000);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawERC20(testERC20, alice, 50_000);
} }
// Test withdrawERC721 from owner // Test withdrawERC721 from owner
function test_withdrawERC721() external { function test_withdrawERC721_succeeds() external {
// Check owner of the token before calling withdrawERC721 // Check owner of the token before calling withdrawERC721
assertEq(testERC721.ownerOf(DEFAULT_TOKEN_ID), alice); assertEq(testERC721.ownerOf(DEFAULT_TOKEN_ID), alice);
...@@ -209,10 +209,10 @@ contract AssetReceiverTest is AssetReceiver_Initializer { ...@@ -209,10 +209,10 @@ contract AssetReceiverTest is AssetReceiver_Initializer {
} }
// Similar as withdrawERC721 but call from non-owner // Similar as withdrawERC721 but call from non-owner
function testFail_withdrawERC721() external { function test_withdrawERC721_unauthorized_reverts() external {
vm.prank(alice); vm.prank(alice);
testERC721.transferFrom(alice, address(assetReceiver), DEFAULT_TOKEN_ID); testERC721.transferFrom(alice, address(assetReceiver), DEFAULT_TOKEN_ID);
assetReceiver.withdrawERC721(testERC721, alice, DEFAULT_TOKEN_ID);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
assetReceiver.withdrawERC721(testERC721, alice, DEFAULT_TOKEN_ID);
} }
} }
...@@ -3,7 +3,7 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,7 @@ pragma solidity 0.8.15;
/* Testing utilities */ /* Testing utilities */
import { Test } from "forge-std/Test.sol"; 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 { contract AttestationStation_Initializer is Test {
address alice_attestor = address(128); address alice_attestor = address(128);
...@@ -28,7 +28,7 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -28,7 +28,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
bytes val bytes val
); );
function test_attest_individual() external { function test_attest_individual_succeeds() external {
AttestationStation attestationStation = new AttestationStation(); AttestationStation attestationStation = new AttestationStation();
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
...@@ -38,7 +38,7 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -38,7 +38,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
attestationStation.attest({ _about: bob, _key: bytes32("foo"), _val: bytes("bar") }); 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 attestationStation = new AttestationStation();
AttestationStation.AttestationData[] AttestationStation.AttestationData[]
...@@ -100,7 +100,7 @@ contract AttestationStationTest is AttestationStation_Initializer { ...@@ -100,7 +100,7 @@ contract AttestationStationTest is AttestationStation_Initializer {
); );
} }
function test_attest_bulk() external { function test_attest_bulk_succeeds() external {
AttestationStation attestationStation = new AttestationStation(); AttestationStation attestationStation = new AttestationStation();
vm.prank(alice_attestor); vm.prank(alice_attestor);
......
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; 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 * @title CheckBalanceHighTest
...@@ -43,7 +43,7 @@ contract CheckBalanceHighTest is Test { ...@@ -43,7 +43,7 @@ contract CheckBalanceHighTest is Test {
* @notice Fuzz the `check` function and assert that it always returns false * @notice Fuzz the `check` function and assert that it always returns false
* when the target's balance is smaller than the threshold. * 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({ CheckBalanceHigh.Params memory p = CheckBalanceHigh.Params({
target: _target, target: _target,
threshold: _threshold threshold: _threshold
......
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; 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 * @title CheckBalanceLowTest
...@@ -41,7 +41,7 @@ contract CheckBalanceLowTest is Test { ...@@ -41,7 +41,7 @@ contract CheckBalanceLowTest is Test {
* @notice Fuzz the `check` function and assert that it always returns false * @notice Fuzz the `check` function and assert that it always returns false
* when the target's balance is larger than the threshold. * 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({ CheckBalanceLow.Params memory p = CheckBalanceLow.Params({
target: _target, target: _target,
threshold: _threshold threshold: _threshold
......
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { import {
CheckGelatoLow, CheckGelatoLow,
IGelatoTreasury IGelatoTreasury
} from "../universal/drippie/dripchecks/CheckGelatoLow.sol"; } from "../periphery/drippie/dripchecks/CheckGelatoLow.sol";
/** /**
* @title MockGelatoTreasury * @title MockGelatoTreasury
...@@ -78,7 +78,7 @@ contract CheckGelatoLowTest is Test { ...@@ -78,7 +78,7 @@ contract CheckGelatoLowTest is Test {
* when the user's balance in the treasury is greater than or equal * when the user's balance in the treasury is greater than or equal
* to the threshold. * 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({ CheckGelatoLow.Params memory p = CheckGelatoLow.Params({
treasury: address(gelato), treasury: address(gelato),
threshold: _threshold, threshold: _threshold,
......
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; 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 * @title CheckTrueTest
......
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.8.16; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { Drippie } from "../universal/drippie/Drippie.sol"; import { Drippie } from "../periphery/drippie/Drippie.sol";
import { IDripCheck } from "../universal/drippie/IDripCheck.sol"; import { IDripCheck } from "../periphery/drippie/IDripCheck.sol";
import { CheckTrue } from "../universal/drippie/dripchecks/CheckTrue.sol"; import { CheckTrue } from "../periphery/drippie/dripchecks/CheckTrue.sol";
import { SimpleStorage } from "../testing/helpers/SimpleStorage.sol"; import { SimpleStorage } from "./Helpers.sol";
/** /**
* @title TestDrippie * @title TestDrippie
...@@ -149,7 +149,7 @@ contract Drippie_Test is Test { ...@@ -149,7 +149,7 @@ contract Drippie_Test is Test {
/** /**
* @notice Creates a drip and asserts that it was configured as expected. * @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(); Drippie.DripConfig memory cfg = _defaultConfig();
vm.expectEmit(true, true, true, true); vm.expectEmit(true, true, true, true);
emit DripCreated(dripName, dripName, cfg); emit DripCreated(dripName, dripName, cfg);
...@@ -188,7 +188,7 @@ contract Drippie_Test is Test { ...@@ -188,7 +188,7 @@ contract Drippie_Test is Test {
/** /**
* @notice Ensures that the same drip cannot be created two times. * @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()); vm.startPrank(drippie.owner());
Drippie.DripConfig memory cfg = _defaultConfig(); Drippie.DripConfig memory cfg = _defaultConfig();
drippie.create(dripName, cfg); drippie.create(dripName, cfg);
...@@ -200,7 +200,7 @@ contract Drippie_Test is Test { ...@@ -200,7 +200,7 @@ contract Drippie_Test is Test {
/** /**
* @notice Ensures that only the owner of Drippie can create a drip. * @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.assume(caller != drippie.owner());
vm.prank(caller); vm.prank(caller);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
...@@ -210,7 +210,7 @@ contract Drippie_Test is Test { ...@@ -210,7 +210,7 @@ contract Drippie_Test is Test {
/** /**
* @notice The owner should be able to set the status of the drip. * @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); vm.expectEmit(true, true, true, true);
emit DripCreated(dripName, dripName, _defaultConfig()); emit DripCreated(dripName, dripName, _defaultConfig());
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
...@@ -258,7 +258,7 @@ contract Drippie_Test is Test { ...@@ -258,7 +258,7 @@ contract Drippie_Test is Test {
/** /**
* @notice The drip status cannot be set back to NONE after it is created. * @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); _createDefaultDrip(dripName);
vm.prank(drippie.owner()); vm.prank(drippie.owner());
...@@ -272,7 +272,7 @@ contract Drippie_Test is Test { ...@@ -272,7 +272,7 @@ contract Drippie_Test is Test {
* @notice The owner cannot set the status of the drip to the status that * @notice The owner cannot set the status of the drip to the status that
* it is already set as. * it is already set as.
*/ */
function test_set_status_same_fails() external { function test_set_statusSame_reverts() external {
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
vm.prank(drippie.owner()); vm.prank(drippie.owner());
...@@ -286,7 +286,7 @@ contract Drippie_Test is Test { ...@@ -286,7 +286,7 @@ contract Drippie_Test is Test {
* @notice The owner should be able to archive the drip if it is in the * @notice The owner should be able to archive the drip if it is in the
* paused state. * paused state.
*/ */
function test_should_archive_if_paused_success() external { function test_shouldArchive_ifPaused_succeeds() external {
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
address owner = drippie.owner(); address owner = drippie.owner();
...@@ -310,7 +310,7 @@ contract Drippie_Test is Test { ...@@ -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 * @notice The owner should not be able to archive the drip if it is in the
* active state. * active state.
*/ */
function test_should_not_archive_if_active_fails() external { function test_shouldNotArchive_ifActive_reverts() external {
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
vm.prank(drippie.owner()); vm.prank(drippie.owner());
...@@ -327,7 +327,7 @@ contract Drippie_Test is Test { ...@@ -327,7 +327,7 @@ contract Drippie_Test is Test {
* @notice The owner should not be allowed to pause the drip if it * @notice The owner should not be allowed to pause the drip if it
* has already been archived. * has already been archived.
*/ */
function test_should_not_allow_paused_if_archived_fails() external { function test_shouldNotAllowPaused_ifArchived_reverts() external {
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
_notAllowFromArchive(dripName, Drippie.DripStatus.PAUSED); _notAllowFromArchive(dripName, Drippie.DripStatus.PAUSED);
...@@ -337,7 +337,7 @@ contract Drippie_Test is Test { ...@@ -337,7 +337,7 @@ contract Drippie_Test is Test {
* @notice The owner should not be allowed to make the drip active again if * @notice The owner should not be allowed to make the drip active again if
* it has already been archived. * it has already been archived.
*/ */
function test_should_not_allow_active_if_archived_fails() external { function test_shouldNotAllowActive_ifArchived_reverts() external {
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
_notAllowFromArchive(dripName, Drippie.DripStatus.ACTIVE); _notAllowFromArchive(dripName, Drippie.DripStatus.ACTIVE);
...@@ -361,7 +361,7 @@ contract Drippie_Test is Test { ...@@ -361,7 +361,7 @@ contract Drippie_Test is Test {
/** /**
* @notice Attempt to update a drip that does not exist. * @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"; string memory otherName = "bar";
vm.prank(drippie.owner()); vm.prank(drippie.owner());
...@@ -376,7 +376,7 @@ contract Drippie_Test is Test { ...@@ -376,7 +376,7 @@ contract Drippie_Test is Test {
/** /**
* @notice Expect a revert when attempting to set the status when not the owner. * @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); _createDefaultDrip(dripName);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
...@@ -386,7 +386,7 @@ contract Drippie_Test is Test { ...@@ -386,7 +386,7 @@ contract Drippie_Test is Test {
/** /**
* @notice The drip should execute and be able to transfer value. * @notice The drip should execute and be able to transfer value.
*/ */
function test_drip_amount() external { function test_drip_amount_succeeds() external {
_createDefaultDrip(dripName); _createDefaultDrip(dripName);
vm.prank(drippie.owner()); vm.prank(drippie.owner());
...@@ -418,7 +418,7 @@ contract Drippie_Test is Test { ...@@ -418,7 +418,7 @@ contract Drippie_Test is Test {
/** /**
* @notice A single DripAction should be able to make a state modifying call. * @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(); Drippie.DripConfig memory cfg = _defaultConfig();
bytes32 key = bytes32(uint256(2)); bytes32 key = bytes32(uint256(2));
...@@ -455,7 +455,7 @@ contract Drippie_Test is Test { ...@@ -455,7 +455,7 @@ contract Drippie_Test is Test {
/** /**
* @notice Multiple drip actions should be able to be triggered with the same check. * @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.DripConfig memory cfg = _defaultConfig();
Drippie.DripAction[] memory actions = new Drippie.DripAction[](2); Drippie.DripAction[] memory actions = new Drippie.DripAction[](2);
...@@ -516,7 +516,7 @@ contract Drippie_Test is Test { ...@@ -516,7 +516,7 @@ contract Drippie_Test is Test {
* trigger the same drip multiple times in the same interval. Then * trigger the same drip multiple times in the same interval. Then
* move forward to the next interval and it should trigger. * 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); _createDefaultDrip(dripName);
vm.prank(drippie.owner()); vm.prank(drippie.owner());
...@@ -551,7 +551,7 @@ contract Drippie_Test is Test { ...@@ -551,7 +551,7 @@ contract Drippie_Test is Test {
* @notice It should revert if attempting to trigger a drip that does not exist. * @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. * 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.prank(drippie.owner());
vm.expectRevert("Drippie: selected drip does not exist or is not currently active"); vm.expectRevert("Drippie: selected drip does not exist or is not currently active");
...@@ -562,7 +562,7 @@ contract Drippie_Test is Test { ...@@ -562,7 +562,7 @@ contract Drippie_Test is Test {
/** /**
* @notice The owner cannot trigger the drip when it is paused. * @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); _createDefaultDrip(dripName);
Drippie.DripStatus status = drippie.dripStatus(dripName); Drippie.DripStatus status = drippie.dripStatus(dripName);
...@@ -598,7 +598,7 @@ contract Drippie_Test is Test { ...@@ -598,7 +598,7 @@ contract Drippie_Test is Test {
* @notice A non zero interval when reentrant is true will cause a revert * @notice A non zero interval when reentrant is true will cause a revert
* when creating a drip. * when creating a drip.
*/ */
function test_reentrant_fails() external { function test_drip_reentrant_reverts() external {
address owner = drippie.owner(); address owner = drippie.owner();
Drippie.DripConfig memory cfg = _defaultConfig(); Drippie.DripConfig memory cfg = _defaultConfig();
cfg.reentrant = true; cfg.reentrant = true;
...@@ -614,7 +614,7 @@ contract Drippie_Test is Test { ...@@ -614,7 +614,7 @@ contract Drippie_Test is Test {
* @notice If reentrant is false and the interval is 0 then it should * @notice If reentrant is false and the interval is 0 then it should
* revert when the drip is created. * revert when the drip is created.
*/ */
function test_non_reentrant_zero_interval_fails() external { function test_notReentrant_zeroInterval_reverts() external {
address owner = drippie.owner(); address owner = drippie.owner();
Drippie.DripConfig memory cfg = _defaultConfig(); Drippie.DripConfig memory cfg = _defaultConfig();
cfg.reentrant = false; cfg.reentrant = false;
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { Faucet } from "../universal/faucet/Faucet.sol"; import { Faucet } from "../periphery/faucet/Faucet.sol";
import { AdminFaucetAuthModule } from "../universal/faucet/authmodules/AdminFaucetAuthModule.sol"; import { AdminFaucetAuthModule } from "../periphery/faucet/authmodules/AdminFaucetAuthModule.sol";
import { FaucetHelper } from "../testing/helpers/FaucetHelper.sol"; import { FaucetHelper } from "./Helpers.sol";
contract Faucet_Initializer is Test { contract Faucet_Initializer is Test {
event Drip( event Drip(
...@@ -126,7 +126,7 @@ contract Faucet_Initializer is Test { ...@@ -126,7 +126,7 @@ contract Faucet_Initializer is Test {
} }
contract FaucetTest is Faucet_Initializer { contract FaucetTest is Faucet_Initializer {
function test_initialize() external { function test_initialize_succeeds() external {
assertEq(faucet.ADMIN(), faucetContractAdmin); assertEq(faucet.ADMIN(), faucetContractAdmin);
} }
...@@ -181,7 +181,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -181,7 +181,7 @@ contract FaucetTest is Faucet_Initializer {
); );
} }
function test_drip_optimistNft_sendsCorrectAmount() external { function test_drip_optimistNftSendsCorrectAmount_succeeds() external {
_enableFaucetAuthModules(); _enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce(); bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain( bytes memory signature = issueProofWithEIP712Domain(
...@@ -213,7 +213,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -213,7 +213,7 @@ contract FaucetTest is Faucet_Initializer {
); );
} }
function test_drip_github_sendsCorrectAmount() external { function test_drip_githubSendsCorrectAmount_succeeds() external {
_enableFaucetAuthModules(); _enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce(); bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain( bytes memory signature = issueProofWithEIP712Domain(
...@@ -241,7 +241,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -241,7 +241,7 @@ contract FaucetTest is Faucet_Initializer {
); );
} }
function test_drip_emitsEvent() external { function test_drip_emitsEvent_succeeds() external {
_enableFaucetAuthModules(); _enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce(); bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain( bytes memory signature = issueProofWithEIP712Domain(
...@@ -300,7 +300,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -300,7 +300,7 @@ contract FaucetTest is Faucet_Initializer {
vm.stopPrank(); vm.stopPrank();
} }
function test_drip_preventsReplayAttacks() external { function test_drip_preventsReplayAttacks_succeeds() external {
_enableFaucetAuthModules(); _enableFaucetAuthModules();
bytes32 nonce = faucetHelper.consumeNonce(); bytes32 nonce = faucetHelper.consumeNonce();
bytes memory signature = issueProofWithEIP712Domain( bytes memory signature = issueProofWithEIP712Domain(
...@@ -423,7 +423,7 @@ contract FaucetTest is Faucet_Initializer { ...@@ -423,7 +423,7 @@ contract FaucetTest is Faucet_Initializer {
vm.stopPrank(); vm.stopPrank();
} }
function test_withdraw_nonAdmin_fails() external { function test_withdraw_nonAdmin_reverts() external {
vm.prank(nonAdmin); vm.prank(nonAdmin);
vm.expectRevert("Faucet: function can only be called by admin"); vm.expectRevert("Faucet: function can only be called by admin");
faucet.withdraw(payable(fundsReceiver), 2 ether); faucet.withdraw(payable(fundsReceiver), 2 ether);
......
...@@ -473,6 +473,14 @@ contract GamePlayer { ...@@ -473,6 +473,14 @@ contract GamePlayer {
counterParty.play(gameProxy.claimDataLen() - 1); counterParty.play(gameProxy.claimDataLen() - 1);
} }
} else { } else {
// Don't defend a claim we would've made ourselves.
if (
parentPos.depth() % 2 == 0 &&
Claim.unwrap(claimAt(15)) == Claim.unwrap(gameProxy.rootClaim())
) {
return;
}
// Defend the parent claim. // Defend the parent claim.
gameProxy.defend(_parentIndex, ourClaim); gameProxy.defend(_parentIndex, ourClaim);
// Call out to our counter party to respond. // Call out to our counter party to respond.
...@@ -488,12 +496,23 @@ contract GamePlayer { ...@@ -488,12 +496,23 @@ contract GamePlayer {
/// @notice Returns the state at the trace index within the player's trace. /// @notice Returns the state at the trace index within the player's trace.
function traceAt(uint256 _traceIndex) public view returns (uint256 state_) { function traceAt(uint256 _traceIndex) public view returns (uint256 state_) {
return uint256(uint8(trace[_traceIndex])); return
uint256(
uint8(_traceIndex >= trace.length ? trace[trace.length - 1] : trace[_traceIndex])
);
} }
/// @notice Returns the player's claim that commits to a given trace index. /// @notice Returns the player's claim that commits to a given trace index.
function claimAt(uint256 _traceIndex) public view returns (Claim claim_) { function claimAt(uint256 _traceIndex) public view returns (Claim claim_) {
return Claim.wrap(keccak256(abi.encode(_traceIndex, traceAt(_traceIndex)))); return
Claim.wrap(
keccak256(
abi.encode(
_traceIndex >= trace.length ? trace.length - 1 : _traceIndex,
traceAt(_traceIndex)
)
)
);
} }
/// @notice Returns the player's claim that commits to a given trace index. /// @notice Returns the player's claim that commits to a given trace index.
...@@ -512,8 +531,14 @@ contract OneVsOne_Arena is FaultDisputeGame_Init { ...@@ -512,8 +531,14 @@ contract OneVsOne_Arena is FaultDisputeGame_Init {
/// @dev The challenger. /// @dev The challenger.
GamePlayer internal challenger; GamePlayer internal challenger;
function init(GamePlayer _defender, GamePlayer _challenger) public { function init(
Claim rootClaim = Claim.wrap(keccak256(abi.encode(15, _defender.traceAt(15)))); GamePlayer _defender,
GamePlayer _challenger,
uint256 _finalTraceIndex
) public {
Claim rootClaim = Claim.wrap(
keccak256(abi.encode(_finalTraceIndex, _defender.traceAt(_finalTraceIndex)))
);
super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM); super.init(rootClaim, ABSOLUTE_PRESTATE_CLAIM);
defender = _defender; defender = _defender;
challenger = _challenger; challenger = _challenger;
...@@ -532,7 +557,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1 is OneVsOne_Arena { ...@@ -532,7 +557,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot1 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(dishonest, honest); super.init(dishonest, honest, 15);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
...@@ -553,7 +578,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot1 is OneVsOne_Arena { ...@@ -553,7 +578,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot1 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new FullyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest); super.init(honest, dishonest, 15);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
...@@ -574,7 +599,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena { ...@@ -574,7 +599,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot2 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(dishonest, honest); super.init(dishonest, honest, 15);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
...@@ -595,7 +620,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena { ...@@ -595,7 +620,7 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot2 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new HalfDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest); super.init(honest, dishonest, 15);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
...@@ -616,7 +641,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena { ...@@ -616,7 +641,7 @@ contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot3 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(dishonest, honest); super.init(dishonest, honest, 15);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
...@@ -637,7 +662,91 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena { ...@@ -637,7 +662,91 @@ contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot3 is OneVsOne_Arena {
function setUp() public override { function setUp() public override {
GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE); GamePlayer honest = new HonestPlayer(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE); GamePlayer dishonest = new EarlyDivergentPlayer(ABSOLUTE_PRESTATE);
super.init(honest, dishonest); super.init(honest, dishonest, 15);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot4 is OneVsOne_Arena {
function setUp() public override {
GamePlayer honest = new HonestPlayer_HalfTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new DivergentPlayer_HalfTrace(ABSOLUTE_PRESTATE);
super.init(dishonest, honest, 7);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot4 is OneVsOne_Arena {
function setUp() public override {
GamePlayer honest = new HonestPlayer_HalfTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new DivergentPlayer_HalfTrace(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, 7);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the dishonest player challenged the root
// claim unsuccessfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.DEFENDER_WINS));
assertTrue(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_IncorrectRoot5 is OneVsOne_Arena {
function setUp() public override {
GamePlayer honest = new HonestPlayer_QuarterTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new DivergentPlayer_QuarterTrace(ABSOLUTE_PRESTATE);
super.init(dishonest, honest, 3);
}
function test_resolvesCorrectly_succeeds() public {
// Play the game until a step is forced.
challenger.play(0);
// Warp ahead to expire the other player's clock.
vm.warp(block.timestamp + 3 days + 12 hours + 1 seconds);
// Resolve the game and assert that the honest player challenged the root
// claim successfully.
assertEq(uint8(gameProxy.resolve()), uint8(GameStatus.CHALLENGER_WINS));
assertFalse(challenger.failedToStep());
}
}
contract FaultDisputeGame_ResolvesCorrectly_CorrectRoot5 is OneVsOne_Arena {
function setUp() public override {
GamePlayer honest = new HonestPlayer_QuarterTrace(ABSOLUTE_PRESTATE);
GamePlayer dishonest = new DivergentPlayer_QuarterTrace(ABSOLUTE_PRESTATE);
super.init(honest, dishonest, 3);
} }
function test_resolvesCorrectly_succeeds() public { function test_resolvesCorrectly_succeeds() public {
...@@ -705,6 +814,52 @@ contract EarlyDivergentPlayer is GamePlayer { ...@@ -705,6 +814,52 @@ contract EarlyDivergentPlayer is GamePlayer {
} }
} }
contract HonestPlayer_HalfTrace is GamePlayer {
constructor(bytes memory _absolutePrestate) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]);
bytes memory halfTrace = new bytes(8);
for (uint8 i = 0; i < halfTrace.length; i++) {
halfTrace[i] = bytes1(absolutePrestate + i + 1);
}
trace = halfTrace;
}
}
contract DivergentPlayer_HalfTrace is GamePlayer {
constructor(bytes memory _absolutePrestate) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]);
bytes memory halfTrace = new bytes(8);
for (uint8 i = 0; i < halfTrace.length; i++) {
// Diverge at trace instruction 5.
halfTrace[i] = i > 4 ? bytes1(i) : bytes1(absolutePrestate + i + 1);
}
trace = halfTrace;
}
}
contract HonestPlayer_QuarterTrace is GamePlayer {
constructor(bytes memory _absolutePrestate) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]);
bytes memory halfTrace = new bytes(4);
for (uint8 i = 0; i < halfTrace.length; i++) {
halfTrace[i] = bytes1(absolutePrestate + i + 1);
}
trace = halfTrace;
}
}
contract DivergentPlayer_QuarterTrace is GamePlayer {
constructor(bytes memory _absolutePrestate) {
uint8 absolutePrestate = uint8(_absolutePrestate[31]);
bytes memory halfTrace = new bytes(4);
for (uint8 i = 0; i < halfTrace.length; i++) {
// Diverge at trace instruction 3.
halfTrace[i] = i > 2 ? bytes1(i) : bytes1(absolutePrestate + i + 1);
}
trace = halfTrace;
}
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// MOCK VMS // // MOCK VMS //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
......
//SPDX-License-Identifier: MIT //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 { 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. * Simple helper contract that helps with testing flow and signature for OptimistInviter contract.
...@@ -144,3 +205,106 @@ contract OptimistInviterHelper { ...@@ -144,3 +205,106 @@ contract OptimistInviterHelper {
ECDSA.toTypedDataHash(domainSeparator, getClaimableInviteStructHash(_claimableInvite)); 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.6.2 <0.9.0; ...@@ -3,11 +3,11 @@ pragma solidity >=0.6.2 <0.9.0;
/* Testing utilities */ /* Testing utilities */
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { AttestationStation } from "../universal/op-nft/AttestationStation.sol"; import { AttestationStation } from "../periphery/op-nft/AttestationStation.sol";
import { Optimist } from "../universal/op-nft/Optimist.sol"; import { Optimist } from "../periphery/op-nft/Optimist.sol";
import { OptimistAllowlist } from "../universal/op-nft/OptimistAllowlist.sol"; import { OptimistAllowlist } from "../periphery/op-nft/OptimistAllowlist.sol";
import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol"; import { OptimistInviter } from "../periphery/op-nft/OptimistInviter.sol";
import { OptimistInviterHelper } from "../testing/helpers/OptimistInviterHelper.sol"; import { OptimistInviterHelper } from "./Helpers.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
...@@ -29,6 +29,12 @@ interface IMulticall3 { ...@@ -29,6 +29,12 @@ interface IMulticall3 {
returns (Result[] memory returnData); returns (Result[] memory returnData);
} }
library Multicall {
bytes internal constant code =
hex"6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033";
address internal constant addr = 0xcA11bde05977b3631167028862bE2a173976CA11;
}
contract Optimist_Initializer is Test { contract Optimist_Initializer is Test {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Initialized(uint8); event Initialized(uint8);
...@@ -233,8 +239,8 @@ contract Optimist_Initializer is Test { ...@@ -233,8 +239,8 @@ contract Optimist_Initializer is Test {
_optimistAllowlist: optimistAllowlist _optimistAllowlist: optimistAllowlist
}); });
// address test = deployCode("Multicall3.sol"); multicall3 = IMulticall3(Multicall.addr);
multicall3 = IMulticall3(deployCode("Multicall3.sol")); vm.etch(Multicall.addr, Multicall.code);
} }
} }
...@@ -242,7 +248,7 @@ contract OptimistTest is Optimist_Initializer { ...@@ -242,7 +248,7 @@ contract OptimistTest is Optimist_Initializer {
/** /**
* @notice Check that constructor and initializer parameters are correctly set. * @notice Check that constructor and initializer parameters are correctly set.
*/ */
function test_initialize_success() external { function test_initialize_succeeds() external {
// expect name to be set // expect name to be set
assertEq(optimist.name(), name); assertEq(optimist.name(), name);
// expect symbol to be set // expect symbol to be set
...@@ -471,7 +477,7 @@ contract OptimistTest is Optimist_Initializer { ...@@ -471,7 +477,7 @@ contract OptimistTest is Optimist_Initializer {
/** /**
* @notice transferFrom should revert since Optimist is a SBT. * @notice transferFrom should revert since Optimist is a SBT.
*/ */
function test_transferFrom_reverts() external { function test_transferFrom_soulbound_reverts() external {
_mockAllowlistTrueFor(bob); _mockAllowlistTrueFor(bob);
// mint as bob // mint as bob
...@@ -496,7 +502,7 @@ contract OptimistTest is Optimist_Initializer { ...@@ -496,7 +502,7 @@ contract OptimistTest is Optimist_Initializer {
/** /**
* @notice approve should revert since Optimist is a SBT. * @notice approve should revert since Optimist is a SBT.
*/ */
function test_approve_reverts() external { function test_approve_soulbound_reverts() external {
_mockAllowlistTrueFor(bob); _mockAllowlistTrueFor(bob);
// mint as bob // mint as bob
...@@ -514,7 +520,7 @@ contract OptimistTest is Optimist_Initializer { ...@@ -514,7 +520,7 @@ contract OptimistTest is Optimist_Initializer {
/** /**
* @notice setApprovalForAll should revert since Optimist is a SBT. * @notice setApprovalForAll should revert since Optimist is a SBT.
*/ */
function test_setApprovalForAll_reverts() external { function test_setApprovalForAll_soulbound_reverts() external {
_mockAllowlistTrueFor(bob); _mockAllowlistTrueFor(bob);
// mint as bob // mint as bob
......
...@@ -3,11 +3,11 @@ pragma solidity 0.8.15; ...@@ -3,11 +3,11 @@ pragma solidity 0.8.15;
/* Testing utilities */ /* Testing utilities */
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { AttestationStation } from "../universal/op-nft/AttestationStation.sol"; import { AttestationStation } from "../periphery/op-nft/AttestationStation.sol";
import { OptimistAllowlist } from "../universal/op-nft/OptimistAllowlist.sol"; import { OptimistAllowlist } from "../periphery/op-nft/OptimistAllowlist.sol";
import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol"; import { OptimistInviter } from "../periphery/op-nft/OptimistInviter.sol";
import { OptimistInviterHelper } from "../testing/helpers/OptimistInviterHelper.sol"; import { OptimistInviterHelper } from "./Helpers.sol";
import { OptimistConstants } from "../universal/op-nft/libraries/OptimistConstants.sol"; import { OptimistConstants } from "../periphery/op-nft/libraries/OptimistConstants.sol";
contract OptimistAllowlist_Initializer is Test { contract OptimistAllowlist_Initializer is Test {
event AttestationCreated( event AttestationCreated(
......
...@@ -3,13 +3,13 @@ pragma solidity 0.8.15; ...@@ -3,13 +3,13 @@ pragma solidity 0.8.15;
/* Testing utilities */ /* Testing utilities */
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { AttestationStation } from "../universal/op-nft/AttestationStation.sol"; import { AttestationStation } from "../periphery/op-nft/AttestationStation.sol";
import { OptimistInviter } from "../universal/op-nft/OptimistInviter.sol"; import { OptimistInviter } from "../periphery/op-nft/OptimistInviter.sol";
import { Optimist } from "../universal/op-nft/Optimist.sol"; import { Optimist } from "../periphery/op-nft/Optimist.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { TestERC1271Wallet } from "../testing/helpers/TestERC1271Wallet.sol"; import { TestERC1271Wallet } from "./Helpers.sol";
import { OptimistInviterHelper } from "../testing/helpers/OptimistInviterHelper.sol"; import { OptimistInviterHelper } from "./Helpers.sol";
import { OptimistConstants } from "../universal/op-nft/libraries/OptimistConstants.sol"; import { OptimistConstants } from "../periphery/op-nft/libraries/OptimistConstants.sol";
contract OptimistInviter_Initializer is Test { contract OptimistInviter_Initializer is Test {
event InviteClaimed(address indexed issuer, address indexed claimer); event InviteClaimed(address indexed issuer, address indexed claimer);
...@@ -260,7 +260,7 @@ contract OptimistInviter_Initializer is Test { ...@@ -260,7 +260,7 @@ contract OptimistInviter_Initializer is Test {
} }
contract OptimistInviterTest is OptimistInviter_Initializer { contract OptimistInviterTest is OptimistInviter_Initializer {
function test_initialize() external { function test_initialize_succeeds() external {
// expect attestationStation to be set // expect attestationStation to be set
assertEq(address(optimistInviter.ATTESTATION_STATION()), address(attestationStation)); assertEq(address(optimistInviter.ATTESTATION_STATION()), address(attestationStation));
assertEq(optimistInviter.INVITE_GRANTER(), alice_inviteGranter); assertEq(optimistInviter.INVITE_GRANTER(), alice_inviteGranter);
......
...@@ -3,9 +3,9 @@ pragma solidity 0.8.15; ...@@ -3,9 +3,9 @@ pragma solidity 0.8.15;
/* Testing utilities */ /* Testing utilities */
import { Test } from "forge-std/Test.sol"; import { Test } from "forge-std/Test.sol";
import { CallRecorder } from "../testing/helpers/CallRecorder.sol"; import { CallRecorder } from "./Helpers.sol";
import { Reverter } from "../testing/helpers/Reverter.sol"; import { Reverter } from "./Helpers.sol";
import { Transactor } from "../universal/Transactor.sol"; import { Transactor } from "../periphery/Transactor.sol";
contract Transactor_Initializer is Test { contract Transactor_Initializer is Test {
address alice = address(128); address alice = address(128);
...@@ -35,12 +35,12 @@ contract Transactor_Initializer is Test { ...@@ -35,12 +35,12 @@ contract Transactor_Initializer is Test {
contract TransactorTest is Transactor_Initializer { contract TransactorTest is Transactor_Initializer {
// Tests if the owner was set correctly during deploy // Tests if the owner was set correctly during deploy
function test_constructor() external { function test_constructor_succeeds() external {
assertEq(address(alice), transactor.owner()); assertEq(address(alice), transactor.owner());
} }
// Tests CALL, should do a call to target // Tests CALL, should do a call to target
function test_CALL() external { function test_call_succeeds() external {
// Initialize call data // Initialize call data
bytes memory data = abi.encodeWithSelector(callRecorded.record.selector); bytes memory data = abi.encodeWithSelector(callRecorded.record.selector);
// Run CALL // Run CALL
...@@ -50,16 +50,16 @@ contract TransactorTest is Transactor_Initializer { ...@@ -50,16 +50,16 @@ contract TransactorTest is Transactor_Initializer {
} }
// It should revert if called by non-owner // It should revert if called by non-owner
function testFail_CALL() external { function test_call_unauthorized_reverts() external {
// Initialize call data // Initialize call data
bytes memory data = abi.encodeWithSelector(callRecorded.record.selector); bytes memory data = abi.encodeWithSelector(callRecorded.record.selector);
// Run CALL // Run CALL
vm.prank(bob); vm.prank(bob);
transactor.CALL(address(callRecorded), data, 200_000 wei);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
transactor.CALL(address(callRecorded), data, 200_000 wei);
} }
function test_DELEGATECALL() external { function test_delegateCall_succeeds() external {
// Initialize call data // Initialize call data
bytes memory data = abi.encodeWithSelector(reverter.doRevert.selector); bytes memory data = abi.encodeWithSelector(reverter.doRevert.selector);
// Run CALL // Run CALL
...@@ -69,12 +69,12 @@ contract TransactorTest is Transactor_Initializer { ...@@ -69,12 +69,12 @@ contract TransactorTest is Transactor_Initializer {
} }
// It should revert if called by non-owner // It should revert if called by non-owner
function testFail_DELEGATECALLL() external { function test_delegateCall_unauthorized_reverts() external {
// Initialize call data // Initialize call data
bytes memory data = abi.encodeWithSelector(reverter.doRevert.selector); bytes memory data = abi.encodeWithSelector(reverter.doRevert.selector);
// Run CALL // Run CALL
vm.prank(bob); vm.prank(bob);
transactor.DELEGATECALL(address(reverter), data);
vm.expectRevert("UNAUTHORIZED"); vm.expectRevert("UNAUTHORIZED");
transactor.DELEGATECALL(address(reverter), data);
} }
} }
...@@ -44,6 +44,6 @@ ...@@ -44,6 +44,6 @@
"l1GenesisBlockTimestamp": "0x64935846", "l1GenesisBlockTimestamp": "0x64935846",
"l1StartingBlockTag": "earliest", "l1StartingBlockTag": "earliest",
"l2GenesisRegolithTimeOffset": "0x0", "l2GenesisRegolithTimeOffset": "0x0",
"faultGameAbsolutePrestate": 15, "faultGameAbsolutePrestate": 140,
"faultGameMaxDepth": 4 "faultGameMaxDepth": 4
} }
\ No newline at end of file
{
"address": "0x406905414D6c250C186F4616EFA38D5fc0759437",
"abi": [
{
"inputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "_manager",
"type": "address"
},
{
"internalType": "address",
"name": "_finalOwner",
"type": "address"
},
{
"internalType": "string[]",
"name": "_names",
"type": "string[]"
},
{
"internalType": "address[]",
"name": "_addresses",
"type": "address[]"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "finalOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getNamedAddresses",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"internalType": "struct AddressDictator.NamedAddress[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "manager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "returnOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "setAddresses",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x32ab785cd443eb8290d85810fbd3b76e92016e3ad2bf5298fe593a07188483b5",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x406905414D6c250C186F4616EFA38D5fc0759437",
"transactionIndex": 9,
"gasUsed": "618072",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x45f0f8b061f80949a0520b87f833da7f6c3635abe2c5cf5a9d9c783ec1f1bb6a",
"transactionHash": "0x32ab785cd443eb8290d85810fbd3b76e92016e3ad2bf5298fe593a07188483b5",
"logs": [],
"blockNumber": 7260725,
"cumulativeGasUsed": "1237384",
"status": 1,
"byzantium": true
},
"args": [
"0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"0xf80267194936da1E98dB10bcE06F3147D580a62e",
[
"StateCommitmentChain"
],
[
"0x9c945aC97Baf48cB784AbBB61399beB71aF7A378"
]
],
"numDeployments": 3,
"solcInputHash": "96c709f6604e7bd8a94077f137b56cbc",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_finalOwner\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_names\",\"type\":\"string[]\"},{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"finalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNamedAddresses\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"internalType\":\"struct AddressDictator.NamedAddress[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"returnOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setAddresses\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate many different addresses in the AddressManager without transferring ownership of the AddressManager to a hot wallet or hardware wallet.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_addresses\":\"Array of addresses to associate with the name.\",\"_finalOwner\":\"Address to transfer AddressManager ownership to afterwards.\",\"_manager\":\"Address of the AddressManager contract.\",\"_names\":\"Array of names to associate an address with.\"}}},\"title\":\"AddressDictator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getNamedAddresses()\":{\"notice\":\"Returns the full namedAddresses array.\"},\"returnOwnership()\":{\"notice\":\"Transfers ownership of this contract to the finalOwner. Only callable by the Final Owner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong.\"},\"setAddresses()\":{\"notice\":\"Called to finalize the transfer, this function is callable by anyone, but will only result in an upgrade if this contract is the owner Address Manager.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/deployment/AddressDictator.sol\":\"AddressDictator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/deployment/AddressDictator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Lib_AddressManager } from \\\"../../libraries/resolver/Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title AddressDictator\\n * @dev The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate\\n * many different addresses in the AddressManager without transferring ownership of the\\n * AddressManager to a hot wallet or hardware wallet.\\n */\\ncontract AddressDictator {\\n /*********\\n * Types *\\n *********/\\n\\n struct NamedAddress {\\n string name;\\n address addr;\\n }\\n\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public manager;\\n address public finalOwner;\\n NamedAddress[] namedAddresses;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _manager Address of the AddressManager contract.\\n * @param _finalOwner Address to transfer AddressManager ownership to afterwards.\\n * @param _names Array of names to associate an address with.\\n * @param _addresses Array of addresses to associate with the name.\\n */\\n constructor(\\n Lib_AddressManager _manager,\\n address _finalOwner,\\n string[] memory _names,\\n address[] memory _addresses\\n ) {\\n manager = _manager;\\n finalOwner = _finalOwner;\\n require(\\n _names.length == _addresses.length,\\n \\\"AddressDictator: Must provide an equal number of names and addresses.\\\"\\n );\\n for (uint256 i = 0; i < _names.length; i++) {\\n namedAddresses.push(NamedAddress({ name: _names[i], addr: _addresses[i] }));\\n }\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Called to finalize the transfer, this function is callable by anyone, but will only result in\\n * an upgrade if this contract is the owner Address Manager.\\n */\\n // slither-disable-next-line calls-loop\\n function setAddresses() external {\\n for (uint256 i = 0; i < namedAddresses.length; i++) {\\n manager.setAddress(namedAddresses[i].name, namedAddresses[i].addr);\\n }\\n // note that this will revert if _finalOwner == currentOwner\\n manager.transferOwnership(finalOwner);\\n }\\n\\n /**\\n * Transfers ownership of this contract to the finalOwner.\\n * Only callable by the Final Owner, which is intended to be our multisig.\\n * This function shouldn't be necessary, but it gives a sense of reassurance that we can recover\\n * if something really surprising goes wrong.\\n */\\n function returnOwnership() external {\\n require(msg.sender == finalOwner, \\\"AddressDictator: only callable by finalOwner\\\");\\n manager.transferOwnership(finalOwner);\\n }\\n\\n /******************\\n * View Functions *\\n ******************/\\n\\n /**\\n * Returns the full namedAddresses array.\\n */\\n function getNamedAddresses() external view returns (NamedAddress[] memory) {\\n return namedAddresses;\\n }\\n}\\n\",\"keccak256\":\"0xd67a7b7ca6d5554bca411d64c6b2d633dfe62ab74480494b99cefff2c672d06a\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b5060405162000d5e38038062000d5e83398101604081905262000034916200037a565b600080546001600160a01b038087166001600160a01b03199283161790925560018054928616929091169190911790558051825114620000ee5760405162461bcd60e51b815260206004820152604560248201527f416464726573734469637461746f723a204d7573742070726f7669646520616e60448201527f20657175616c206e756d626572206f66206e616d657320616e6420616464726560648201526439b9b2b99760d91b608482015260a40160405180910390fd5b60005b8251811015620001c357600260405180604001604052808584815181106200011d576200011d62000505565b602002602001015181526020018484815181106200013f576200013f62000505565b6020908102919091018101516001600160a01b0316909152825460018101845560009384529281902082518051939460020290910192620001849284920190620001ce565b5060209190910151600190910180546001600160a01b0319166001600160a01b0390921691909117905580620001ba816200051b565b915050620000f1565b505050505062000582565b828054620001dc9062000545565b90600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b6001600160a01b03811681146200028a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620002ce57620002ce6200028d565b604052919050565b60006001600160401b03821115620002f257620002f26200028d565b5060051b60200190565b600082601f8301126200030e57600080fd5b81516020620003276200032183620002d6565b620002a3565b82815260059290921b840181019181810190868411156200034757600080fd5b8286015b848110156200036f578051620003618162000274565b83529183019183016200034b565b509695505050505050565b600080600080608085870312156200039157600080fd5b84516200039e8162000274565b80945050602080860151620003b38162000274565b60408701519094506001600160401b0380821115620003d157600080fd5b818801915088601f830112620003e657600080fd5b8151620003f76200032182620002d6565b81815260059190911b8301840190848101908b8311156200041757600080fd5b8585015b83811015620004ce57805185811115620004355760008081fd5b8601603f81018e13620004485760008081fd5b87810151868111156200045f576200045f6200028d565b62000473601f8201601f19168a01620002a3565b8181528f60408385010111156200048a5760008081fd5b60005b82811015620004ab57838101604001518282018c01528a016200048d565b82811115620004bd5760008b84840101525b50855250509186019186016200041b565b5060608b01519097509450505080831115620004e957600080fd5b5050620004f987828801620002fc565b91505092959194509250565b634e487b7160e01b600052603260045260246000fd5b60006000198214156200053e57634e487b7160e01b600052601160045260246000fd5b5060010190565b600181811c908216806200055a57607f821691505b602082108114156200057c57634e487b7160e01b600052602260045260246000fd5b50919050565b6107cc80620005926000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80633ccad6fc116100505780633ccad6fc146100c0578063481c6a75146100d5578063bc3a429b146100f557600080fd5b806317ad94ec1461006c578063297d1a34146100b6575b600080fd5b60015461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100be6100fd565b005b6100c8610232565b6040516100ad91906104af565b60005461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100be610343565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f416464726573734469637461746f723a206f6e6c792063616c6c61626c65206260448201527f792066696e616c4f776e65720000000000000000000000000000000000000000606482015260840160405180910390fd5b6000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024015b600060405180830381600087803b15801561021857600080fd5b505af115801561022c573d6000803e3d6000fd5b50505050565b60606002805480602002602001604051908101604052809291908181526020016000905b8282101561033a5783829060005260206000209060020201604051806040016040529081600082018054610289906105ae565b80601f01602080910402602001604051908101604052809291908181526020018280546102b5906105ae565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b505050918352505060019182015473ffffffffffffffffffffffffffffffffffffffff16602091820152918352929092019101610256565b50505050905090565b60005b600254811015610454576000546002805473ffffffffffffffffffffffffffffffffffffffff90921691639b2ea4bd91908490811061038757610387610602565b9060005260206000209060020201600001600284815481106103ab576103ab610602565b60009182526020909120600160029092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815261040f929173ffffffffffffffffffffffffffffffffffffffff1690600401610631565b600060405180830381600087803b15801561042957600080fd5b505af115801561043d573d6000803e3d6000fd5b50505050808061044c90610736565b915050610346565b506000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024016101fe565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561059f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a8503018652825180518886528051808a880152845b81811015610532578281018c0151888201606001528b01610516565b8181111561054357856060838a0101525b50918a015173ffffffffffffffffffffffffffffffffffffffff16868b01525095880195601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690930160600192918701916001016104d7565b50919998505050505050505050565b600181811c908216806105c257607f821691505b602082108114156105fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60408152600080845481600182811c91508083168061065157607f831692505b602080841082141561068a577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b60408801849052606088018280156106a957600181146106d857610703565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00871682528282019750610703565b60008c81526020902060005b878110156106fd578154848201529086019084016106e4565b83019850505b50508596506107298189018a73ffffffffffffffffffffffffffffffffffffffff169052565b5050505050509392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561078f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea26469706673582212207993fbd341ec4f9e20c9ca42c43294b14f2a103fa8da10fc05d197e3abc8766164736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633ccad6fc116100505780633ccad6fc146100c0578063481c6a75146100d5578063bc3a429b146100f557600080fd5b806317ad94ec1461006c578063297d1a34146100b6575b600080fd5b60015461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100be6100fd565b005b6100c8610232565b6040516100ad91906104af565b60005461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100be610343565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f416464726573734469637461746f723a206f6e6c792063616c6c61626c65206260448201527f792066696e616c4f776e65720000000000000000000000000000000000000000606482015260840160405180910390fd5b6000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024015b600060405180830381600087803b15801561021857600080fd5b505af115801561022c573d6000803e3d6000fd5b50505050565b60606002805480602002602001604051908101604052809291908181526020016000905b8282101561033a5783829060005260206000209060020201604051806040016040529081600082018054610289906105ae565b80601f01602080910402602001604051908101604052809291908181526020018280546102b5906105ae565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b505050918352505060019182015473ffffffffffffffffffffffffffffffffffffffff16602091820152918352929092019101610256565b50505050905090565b60005b600254811015610454576000546002805473ffffffffffffffffffffffffffffffffffffffff90921691639b2ea4bd91908490811061038757610387610602565b9060005260206000209060020201600001600284815481106103ab576103ab610602565b60009182526020909120600160029092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815261040f929173ffffffffffffffffffffffffffffffffffffffff1690600401610631565b600060405180830381600087803b15801561042957600080fd5b505af115801561043d573d6000803e3d6000fd5b50505050808061044c90610736565b915050610346565b506000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024016101fe565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561059f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a8503018652825180518886528051808a880152845b81811015610532578281018c0151888201606001528b01610516565b8181111561054357856060838a0101525b50918a015173ffffffffffffffffffffffffffffffffffffffff16868b01525095880195601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690930160600192918701916001016104d7565b50919998505050505050505050565b600181811c908216806105c257607f821691505b602082108114156105fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60408152600080845481600182811c91508083168061065157607f831692505b602080841082141561068a577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b60408801849052606088018280156106a957600181146106d857610703565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00871682528282019750610703565b60008c81526020902060005b878110156106fd578154848201529086019084016106e4565b83019850505b50508596506107298189018a73ffffffffffffffffffffffffffffffffffffffff169052565b5050505050509392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561078f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea26469706673582212207993fbd341ec4f9e20c9ca42c43294b14f2a103fa8da10fc05d197e3abc8766164736f6c63430008090033",
"devdoc": {
"details": "The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate many different addresses in the AddressManager without transferring ownership of the AddressManager to a hot wallet or hardware wallet.",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_addresses": "Array of addresses to associate with the name.",
"_finalOwner": "Address to transfer AddressManager ownership to afterwards.",
"_manager": "Address of the AddressManager contract.",
"_names": "Array of names to associate an address with."
}
}
},
"title": "AddressDictator",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getNamedAddresses()": {
"notice": "Returns the full namedAddresses array."
},
"returnOwnership()": {
"notice": "Transfers ownership of this contract to the finalOwner. Only callable by the Final Owner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong."
},
"setAddresses()": {
"notice": "Called to finalize the transfer, this function is callable by anyone, but will only result in an upgrade if this contract is the owner Address Manager."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 1908,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "manager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)7084"
},
{
"astId": 1910,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "finalOwner",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 1914,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "namedAddresses",
"offset": 0,
"slot": "2",
"type": "t_array(t_struct(NamedAddress)1905_storage)dyn_storage"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_struct(NamedAddress)1905_storage)dyn_storage": {
"base": "t_struct(NamedAddress)1905_storage",
"encoding": "dynamic_array",
"label": "struct AddressDictator.NamedAddress[]",
"numberOfBytes": "32"
},
"t_contract(Lib_AddressManager)7084": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
"t_struct(NamedAddress)1905_storage": {
"encoding": "inplace",
"label": "struct AddressDictator.NamedAddress",
"members": [
{
"astId": 1902,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "name",
"offset": 0,
"slot": "0",
"type": "t_string_storage"
},
{
"astId": 1904,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "addr",
"offset": 0,
"slot": "1",
"type": "t_address"
}
],
"numberOfBytes": "64"
}
}
}
}
\ No newline at end of file
{
"address": "0xfC2ab6987C578218f99E85d61Dcf4814A26637Bd",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "_who",
"type": "address"
}
],
"name": "isCollateralized",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "libAddressManager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x5a8854dcfaaae5c3e79f97062e6b271dea9ef6c8b0726e8675e39793a188dc7c",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0xfC2ab6987C578218f99E85d61Dcf4814A26637Bd",
"transactionIndex": 27,
"gasUsed": "295574",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x6856e28afcb3321e17dff2ade090155e6c8ba7cf41b8d909275f68e052c4c6fd",
"transactionHash": "0x5a8854dcfaaae5c3e79f97062e6b271dea9ef6c8b0726e8675e39793a188dc7c",
"logs": [],
"blockNumber": 7017112,
"cumulativeGasUsed": "1229262",
"status": 1,
"byzantium": true
},
"args": [
"0xa6f73589243a6A7a9023b1Fa0651b1d89c177111"
],
"numDeployments": 1,
"solcInputHash": "1845b32709cda2bc0b584a5e3f043e7b",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"isCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"libAddressManager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is, for now, a stub of the \\\"real\\\" BondManager that does nothing but allow the \\\"OVM_Proposer\\\" to submit state root batches.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\"}},\"isCollateralized(address)\":{\"params\":{\"_who\":\"Address to check.\"},\"returns\":{\"_0\":\"true if the address is properly collateralized, false otherwise.\"}},\"resolve(string)\":{\"params\":{\"_name\":\"Name to resolve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}}},\"title\":\"BondManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"isCollateralized(address)\":{\"notice\":\"Checks whether a given address is properly collateralized and can perform actions within the system.\"},\"resolve(string)\":{\"notice\":\"Resolves the address associated with a given name.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/verification/BondManager.sol\":\"BondManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/verification/BondManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Interface Imports */\\nimport { IBondManager } from \\\"./IBondManager.sol\\\";\\n\\n/* Contract Imports */\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\n\\n/**\\n * @title BondManager\\n * @dev This contract is, for now, a stub of the \\\"real\\\" BondManager that does nothing but\\n * allow the \\\"OVM_Proposer\\\" to submit state root batches.\\n *\\n */\\ncontract BondManager is IBondManager, Lib_AddressResolver {\\n /**\\n * @param _libAddressManager Address of the Address Manager.\\n */\\n constructor(address _libAddressManager) Lib_AddressResolver(_libAddressManager) {}\\n\\n /**\\n * Checks whether a given address is properly collateralized and can perform actions within\\n * the system.\\n * @param _who Address to check.\\n * @return true if the address is properly collateralized, false otherwise.\\n */\\n // slither-disable-next-line external-function\\n function isCollateralized(address _who) public view returns (bool) {\\n // Only authenticate sequencer to submit state root batches.\\n return _who == resolve(\\\"OVM_Proposer\\\");\\n }\\n}\\n\",\"keccak256\":\"0x34bc15756ccd896c32cd20248da3f95a2be8f9b8382674b42bf896b928984380\",\"license\":\"MIT\"},\"contracts/L1/verification/IBondManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title IBondManager\\n */\\ninterface IBondManager {\\n /********************\\n * Public Functions *\\n ********************/\\n\\n function isCollateralized(address _who) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x4ae2dc7bf175626d2930299e73d50a7ba936171d07810497ef71fa38a4e246a7\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\nabstract contract Lib_AddressResolver {\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public libAddressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n */\\n constructor(address _libAddressManager) {\\n libAddressManager = Lib_AddressManager(_libAddressManager);\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Resolves the address associated with a given name.\\n * @param _name Name to resolve an address for.\\n * @return Address associated with the given name.\\n */\\n function resolve(string memory _name) public view returns (address) {\\n return libAddressManager.getAddress(_name);\\n }\\n}\\n\",\"keccak256\":\"0x515c4db671a28e2fe180201f6d11c0208c05f582ca3489fb6b8e81c27659bc62\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5060405161048838038061048883398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6103f5806100936000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806302ad4d2a14610046578063299ca4781461006e578063461a4478146100b3575b600080fd5b61005961005436600461020d565b6100c6565b60405190151581526020015b60405180910390f35b60005461008e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610065565b61008e6100c1366004610260565b61013b565b60006101066040518060400160405280600c81526020017f4f564d5f50726f706f736572000000000000000000000000000000000000000081525061013b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061019290859060040161032f565b60206040518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906103a2565b92915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461020a57600080fd5b50565b60006020828403121561021f57600080fd5b813561022a816101e8565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561027257600080fd5b813567ffffffffffffffff8082111561028a57600080fd5b818401915084601f83011261029e57600080fd5b8135818111156102b0576102b0610231565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156102f6576102f6610231565b8160405282815287602084870101111561030f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b8181101561035c57858101830151858201604001528201610340565b8181111561036e576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156103b457600080fd5b815161022a816101e856fea264697066735822122087d4cb97cd5a4456c2b8ab23d1374b6ac6874a5b854a207714f5b3768ca6d73a64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806302ad4d2a14610046578063299ca4781461006e578063461a4478146100b3575b600080fd5b61005961005436600461020d565b6100c6565b60405190151581526020015b60405180910390f35b60005461008e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610065565b61008e6100c1366004610260565b61013b565b60006101066040518060400160405280600c81526020017f4f564d5f50726f706f736572000000000000000000000000000000000000000081525061013b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061019290859060040161032f565b60206040518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906103a2565b92915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461020a57600080fd5b50565b60006020828403121561021f57600080fd5b813561022a816101e8565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561027257600080fd5b813567ffffffffffffffff8082111561028a57600080fd5b818401915084601f83011261029e57600080fd5b8135818111156102b0576102b0610231565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156102f6576102f6610231565b8160405282815287602084870101111561030f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b8181101561035c57858101830151858201604001528201610340565b8181111561036e576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156103b457600080fd5b815161022a816101e856fea264697066735822122087d4cb97cd5a4456c2b8ab23d1374b6ac6874a5b854a207714f5b3768ca6d73a64736f6c63430008090033",
"devdoc": {
"details": "This contract is, for now, a stub of the \"real\" BondManager that does nothing but allow the \"OVM_Proposer\" to submit state root batches.",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_libAddressManager": "Address of the Address Manager."
}
},
"isCollateralized(address)": {
"params": {
"_who": "Address to check."
},
"returns": {
"_0": "true if the address is properly collateralized, false otherwise."
}
},
"resolve(string)": {
"params": {
"_name": "Name to resolve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
}
},
"title": "BondManager",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"isCollateralized(address)": {
"notice": "Checks whether a given address is properly collateralized and can perform actions within the system."
},
"resolve(string)": {
"notice": "Resolves the address associated with a given name."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 7092,
"contract": "contracts/L1/verification/BondManager.sol:BondManager",
"label": "libAddressManager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)7084"
}
],
"types": {
"t_contract(Lib_AddressManager)7084": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x4325Ac17c7fF5Afc0d05335dD30Db3D010455813",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
},
{
"internalType": "string",
"name": "_owner",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "get",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getGlobalMetadata",
"outputs": [
{
"internalType": "bytes27",
"name": "",
"type": "bytes27"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "length",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "libAddressManager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "setGlobalMetadata",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x7e6cfa76b8aefcb5390169f8566a411fc25db594b91830c434c573b3e33472a6",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x4325Ac17c7fF5Afc0d05335dD30Db3D010455813",
"transactionIndex": 177,
"gasUsed": "946990",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xeec79f4c975f8ce40dbb88fbf5a47ebb50516a532a03a4f0c01d1f461de48fe7",
"transactionHash": "0x7e6cfa76b8aefcb5390169f8566a411fc25db594b91830c434c573b3e33472a6",
"logs": [],
"blockNumber": 7017078,
"cumulativeGasUsed": "7826189",
"status": 1,
"byzantium": true
},
"args": [
"0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"CanonicalTransactionChain"
],
"numDeployments": 1,
"solcInputHash": "5f4e2d2e170708499f05344e000df330",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_owner\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"get\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGlobalMetadata\",\"outputs\":[{\"internalType\":\"bytes27\",\"name\":\"\",\"type\":\"bytes27\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"length\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"libAddressManager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"setGlobalMetadata\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\",\"_owner\":\"Name of the contract that owns this container (will be resolved later).\"}},\"deleteElementsAfterInclusive(uint256)\":{\"params\":{\"_index\":\"Object index to delete from.\"}},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_index\":\"Object index to delete from.\"}},\"get(uint256)\":{\"params\":{\"_index\":\"Index of the particular object to access.\"},\"returns\":{\"_0\":\"32 byte object value.\"}},\"getGlobalMetadata()\":{\"returns\":{\"_0\":\"Container global metadata field.\"}},\"length()\":{\"returns\":{\"_0\":\"Number of objects in the container.\"}},\"push(bytes32)\":{\"params\":{\"_object\":\"A 32 byte value to insert into the container.\"}},\"push(bytes32,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_object\":\"A 32 byte value to insert into the container.\"}},\"resolve(string)\":{\"params\":{\"_name\":\"Name to resolve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"setGlobalMetadata(bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata to set.\"}}},\"title\":\"ChainStorageContainer\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"deleteElementsAfterInclusive(uint256)\":{\"notice\":\"Removes all objects after and including a given index.\"},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"notice\":\"Removes all objects after and including a given index. Also allows setting the global metadata field.\"},\"get(uint256)\":{\"notice\":\"Retrieves an object from the container.\"},\"getGlobalMetadata()\":{\"notice\":\"Retrieves the container's global metadata field.\"},\"length()\":{\"notice\":\"Retrieves the number of objects stored in the container.\"},\"push(bytes32)\":{\"notice\":\"Pushes an object into the container.\"},\"push(bytes32,bytes27)\":{\"notice\":\"Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global metadata (it's an optimization).\"},\"resolve(string)\":{\"notice\":\"Resolves the address associated with a given name.\"},\"setGlobalMetadata(bytes27)\":{\"notice\":\"Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/rollup/ChainStorageContainer.sol\":\"ChainStorageContainer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/rollup/ChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_Buffer } from \\\"../../libraries/utils/Lib_Buffer.sol\\\";\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\n\\n/* Interface Imports */\\nimport { IChainStorageContainer } from \\\"./IChainStorageContainer.sol\\\";\\n\\n/**\\n * @title ChainStorageContainer\\n * @dev The Chain Storage Container provides its owner contract with read, write and delete\\n * functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which\\n * can no longer be used in a fraud proof due to the fraud window having passed, and the associated\\n * chain state or transactions being finalized.\\n * Three distinct Chain Storage Containers will be deployed on Layer 1:\\n * 1. Stores transaction batches for the Canonical Transaction Chain\\n * 2. Stores queued transactions for the Canonical Transaction Chain\\n * 3. Stores chain state batches for the State Commitment Chain\\n *\\n */\\ncontract ChainStorageContainer is IChainStorageContainer, Lib_AddressResolver {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Lib_Buffer.Buffer;\\n\\n /*************\\n * Variables *\\n *************/\\n\\n string public owner;\\n Lib_Buffer.Buffer internal buffer;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Address Manager.\\n * @param _owner Name of the contract that owns this container (will be resolved later).\\n */\\n constructor(address _libAddressManager, string memory _owner)\\n Lib_AddressResolver(_libAddressManager)\\n {\\n owner = _owner;\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n modifier onlyOwner() {\\n require(\\n msg.sender == resolve(owner),\\n \\\"ChainStorageContainer: Function can only be called by the owner.\\\"\\n );\\n _;\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function setGlobalMetadata(bytes27 _globalMetadata) public onlyOwner {\\n return buffer.setExtraData(_globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function getGlobalMetadata() public view returns (bytes27) {\\n return buffer.getExtraData();\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function length() public view returns (uint256) {\\n return uint256(buffer.getLength());\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function push(bytes32 _object) public onlyOwner {\\n buffer.push(_object);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function push(bytes32 _object, bytes27 _globalMetadata) public onlyOwner {\\n buffer.push(_object, _globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function get(uint256 _index) public view returns (bytes32) {\\n return buffer.get(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function deleteElementsAfterInclusive(uint256 _index) public onlyOwner {\\n buffer.deleteElementsAfterInclusive(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata)\\n public\\n onlyOwner\\n {\\n buffer.deleteElementsAfterInclusive(uint40(_index), _globalMetadata);\\n }\\n}\\n\",\"keccak256\":\"0x5acd889488ab8eab50d5527d1b18b00214a3242acbf9d89fbeaf188322f81a58\",\"license\":\"MIT\"},\"contracts/L1/rollup/IChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title IChainStorageContainer\\n */\\ninterface IChainStorageContainer {\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the container's global metadata field. We're using `bytes27` here because we use five\\n * bytes to maintain the length of the underlying data structure, meaning we have an extra\\n * 27 bytes to store arbitrary data.\\n * @param _globalMetadata New global metadata to set.\\n */\\n function setGlobalMetadata(bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves the container's global metadata field.\\n * @return Container global metadata field.\\n */\\n function getGlobalMetadata() external view returns (bytes27);\\n\\n /**\\n * Retrieves the number of objects stored in the container.\\n * @return Number of objects in the container.\\n */\\n function length() external view returns (uint256);\\n\\n /**\\n * Pushes an object into the container.\\n * @param _object A 32 byte value to insert into the container.\\n */\\n function push(bytes32 _object) external;\\n\\n /**\\n * Pushes an object into the container. Function allows setting the global metadata since\\n * we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global\\n * metadata (it's an optimization).\\n * @param _object A 32 byte value to insert into the container.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function push(bytes32 _object, bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves an object from the container.\\n * @param _index Index of the particular object to access.\\n * @return 32 byte object value.\\n */\\n function get(uint256 _index) external view returns (bytes32);\\n\\n /**\\n * Removes all objects after and including a given index.\\n * @param _index Object index to delete from.\\n */\\n function deleteElementsAfterInclusive(uint256 _index) external;\\n\\n /**\\n * Removes all objects after and including a given index. Also allows setting the global\\n * metadata field.\\n * @param _index Object index to delete from.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external;\\n}\\n\",\"keccak256\":\"0xe55ad72572ec47dc09a02228d0c5a438571c76a41d16d92b35add057811977ce\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\nabstract contract Lib_AddressResolver {\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public libAddressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n */\\n constructor(address _libAddressManager) {\\n libAddressManager = Lib_AddressManager(_libAddressManager);\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Resolves the address associated with a given name.\\n * @param _name Name to resolve an address for.\\n * @return Address associated with the given name.\\n */\\n function resolve(string memory _name) public view returns (address) {\\n return libAddressManager.getAddress(_name);\\n }\\n}\\n\",\"keccak256\":\"0x515c4db671a28e2fe180201f6d11c0208c05f582ca3489fb6b8e81c27659bc62\",\"license\":\"MIT\"},\"contracts/libraries/utils/Lib_Buffer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Lib_Buffer\\n * @dev This library implements a bytes32 storage array with some additional gas-optimized\\n * functionality. In particular, it encodes its length as a uint40, and tightly packs this with an\\n * overwritable \\\"extra data\\\" field so we can store more information with a single SSTORE.\\n */\\nlibrary Lib_Buffer {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Buffer;\\n\\n /***********\\n * Structs *\\n ***********/\\n\\n struct Buffer {\\n bytes32 context;\\n mapping(uint256 => bytes32) buf;\\n }\\n\\n struct BufferContext {\\n // Stores the length of the array. Uint40 is way more elements than we'll ever reasonably\\n // need in an array and we get an extra 27 bytes of extra data to play with.\\n uint40 length;\\n // Arbitrary extra data that can be modified whenever the length is updated. Useful for\\n // squeezing out some gas optimizations.\\n bytes27 extraData;\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n * @param _extraData Global extra data.\\n */\\n function push(\\n Buffer storage _self,\\n bytes32 _value,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.buf[ctx.length] = _value;\\n\\n // Bump the global index and insert our extra data, then save the context.\\n ctx.length++;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n */\\n function push(Buffer storage _self, bytes32 _value) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.push(_value, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves an element from the buffer.\\n * @param _self Buffer to access.\\n * @param _index Element index to retrieve.\\n * @return Value of the element at the given index.\\n */\\n function get(Buffer storage _self, uint256 _index) internal view returns (bytes32) {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n return _self.buf[_index];\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n * @param _extraData Optional global extra data.\\n */\\n function deleteElementsAfterInclusive(\\n Buffer storage _self,\\n uint40 _index,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n // Set our length and extra data, save the context.\\n ctx.length = _index;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n */\\n function deleteElementsAfterInclusive(Buffer storage _self, uint40 _index) internal {\\n BufferContext memory ctx = _self.getContext();\\n _self.deleteElementsAfterInclusive(_index, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves the current global index.\\n * @param _self Buffer to access.\\n * @return Current global index.\\n */\\n function getLength(Buffer storage _self) internal view returns (uint40) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.length;\\n }\\n\\n /**\\n * Changes current global extra data.\\n * @param _self Buffer to access.\\n * @param _extraData New global extra data.\\n */\\n function setExtraData(Buffer storage _self, bytes27 _extraData) internal {\\n BufferContext memory ctx = _self.getContext();\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Retrieves the current global extra data.\\n * @param _self Buffer to access.\\n * @return Current global extra data.\\n */\\n function getExtraData(Buffer storage _self) internal view returns (bytes27) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.extraData;\\n }\\n\\n /**\\n * Sets the current buffer context.\\n * @param _self Buffer to access.\\n * @param _ctx Current buffer context.\\n */\\n function setContext(Buffer storage _self, BufferContext memory _ctx) internal {\\n bytes32 context;\\n uint40 length = _ctx.length;\\n bytes27 extraData = _ctx.extraData;\\n assembly {\\n context := length\\n context := or(context, extraData)\\n }\\n\\n if (_self.context != context) {\\n _self.context = context;\\n }\\n }\\n\\n /**\\n * Retrieves the current buffer context.\\n * @param _self Buffer to access.\\n * @return Current buffer context.\\n */\\n function getContext(Buffer storage _self) internal view returns (BufferContext memory) {\\n bytes32 context = _self.context;\\n uint40 length;\\n bytes27 extraData;\\n assembly {\\n length := and(\\n context,\\n 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF\\n )\\n extraData := and(\\n context,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000\\n )\\n }\\n\\n return BufferContext({ length: length, extraData: extraData });\\n }\\n}\\n\",\"keccak256\":\"0x38917b618db448e356c76c999ce9aaca094541eb1f9bc65b06b8d4d84308f056\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b50604051620011b3380380620011b3833981016040819052620000349162000129565b600080546001600160a01b0319166001600160a01b0384161790558051620000649060019060208401906200006d565b50505062000266565b8280546200007b9062000229565b90600052602060002090601f0160209004810192826200009f5760008555620000ea565b82601f10620000ba57805160ff1916838001178555620000ea565b82800160010185558215620000ea579182015b82811115620000ea578251825591602001919060010190620000cd565b50620000f8929150620000fc565b5090565b5b80821115620000f85760008155600101620000fd565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200013d57600080fd5b82516001600160a01b03811681146200015557600080fd5b602084810151919350906001600160401b03808211156200017557600080fd5b818601915086601f8301126200018a57600080fd5b8151818111156200019f576200019f62000113565b604051601f8201601f19908116603f01168101908382118183101715620001ca57620001ca62000113565b816040528281528986848701011115620001e357600080fd5b600093505b82841015620002075784840186015181850187015292850192620001e8565b82841115620002195760008684830101525b8096505050505050509250929050565b600181811c908216806200023e57607f821691505b602082108114156200026057634e487b7160e01b600052602260045260246000fd5b50919050565b610f3d80620002766000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea2646970667358221220e1995ee56c4c5e67de41c56ad510b16704727d3ab1fa5bb2e3c62b0bd7c0597564736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea2646970667358221220e1995ee56c4c5e67de41c56ad510b16704727d3ab1fa5bb2e3c62b0bd7c0597564736f6c63430008090033",
"devdoc": {
"details": "The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_libAddressManager": "Address of the Address Manager.",
"_owner": "Name of the contract that owns this container (will be resolved later)."
}
},
"deleteElementsAfterInclusive(uint256)": {
"params": {
"_index": "Object index to delete from."
}
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_index": "Object index to delete from."
}
},
"get(uint256)": {
"params": {
"_index": "Index of the particular object to access."
},
"returns": {
"_0": "32 byte object value."
}
},
"getGlobalMetadata()": {
"returns": {
"_0": "Container global metadata field."
}
},
"length()": {
"returns": {
"_0": "Number of objects in the container."
}
},
"push(bytes32)": {
"params": {
"_object": "A 32 byte value to insert into the container."
}
},
"push(bytes32,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_object": "A 32 byte value to insert into the container."
}
},
"resolve(string)": {
"params": {
"_name": "Name to resolve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
},
"setGlobalMetadata(bytes27)": {
"params": {
"_globalMetadata": "New global metadata to set."
}
}
},
"title": "ChainStorageContainer",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"deleteElementsAfterInclusive(uint256)": {
"notice": "Removes all objects after and including a given index."
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"notice": "Removes all objects after and including a given index. Also allows setting the global metadata field."
},
"get(uint256)": {
"notice": "Retrieves an object from the container."
},
"getGlobalMetadata()": {
"notice": "Retrieves the container's global metadata field."
},
"length()": {
"notice": "Retrieves the number of objects stored in the container."
},
"push(bytes32)": {
"notice": "Pushes an object into the container."
},
"push(bytes32,bytes27)": {
"notice": "Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \"length\" storage slot anyway, which also contains the global metadata (it's an optimization)."
},
"resolve(string)": {
"notice": "Resolves the address associated with a given name."
},
"setGlobalMetadata(bytes27)": {
"notice": "Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 7092,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "libAddressManager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)7084"
},
{
"astId": 4067,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "owner",
"offset": 0,
"slot": "1",
"type": "t_string_storage"
},
{
"astId": 4070,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buffer",
"offset": 0,
"slot": "2",
"type": "t_struct(Buffer)9208_storage"
}
],
"types": {
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(Lib_AddressManager)7084": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_mapping(t_uint256,t_bytes32)": {
"encoding": "mapping",
"key": "t_uint256",
"label": "mapping(uint256 => bytes32)",
"numberOfBytes": "32",
"value": "t_bytes32"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
"t_struct(Buffer)9208_storage": {
"encoding": "inplace",
"label": "struct Lib_Buffer.Buffer",
"members": [
{
"astId": 9203,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "context",
"offset": 0,
"slot": "0",
"type": "t_bytes32"
},
{
"astId": 9207,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buf",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_uint256,t_bytes32)"
}
],
"numberOfBytes": "64"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0x41eF5DaF4A7719bfe89A88BA3DD0DCFF5feCeD39",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
},
{
"internalType": "string",
"name": "_owner",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "get",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getGlobalMetadata",
"outputs": [
{
"internalType": "bytes27",
"name": "",
"type": "bytes27"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "length",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "libAddressManager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "setGlobalMetadata",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x9c4f789a1d2a40be2f1f5683152d04161cb79a08e902b2022b31bedfcddffc91",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x41eF5DaF4A7719bfe89A88BA3DD0DCFF5feCeD39",
"transactionIndex": 13,
"gasUsed": "946930",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x744227b3c2462fd8099c203dc7d98bbb506a3d919e8d457634816ba58c2941c3",
"transactionHash": "0x9c4f789a1d2a40be2f1f5683152d04161cb79a08e902b2022b31bedfcddffc91",
"logs": [],
"blockNumber": 7017084,
"cumulativeGasUsed": "1670652",
"status": 1,
"byzantium": true
},
"args": [
"0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"StateCommitmentChain"
],
"numDeployments": 1,
"solcInputHash": "5f4e2d2e170708499f05344e000df330",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_owner\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"get\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGlobalMetadata\",\"outputs\":[{\"internalType\":\"bytes27\",\"name\":\"\",\"type\":\"bytes27\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"length\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"libAddressManager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"setGlobalMetadata\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\",\"_owner\":\"Name of the contract that owns this container (will be resolved later).\"}},\"deleteElementsAfterInclusive(uint256)\":{\"params\":{\"_index\":\"Object index to delete from.\"}},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_index\":\"Object index to delete from.\"}},\"get(uint256)\":{\"params\":{\"_index\":\"Index of the particular object to access.\"},\"returns\":{\"_0\":\"32 byte object value.\"}},\"getGlobalMetadata()\":{\"returns\":{\"_0\":\"Container global metadata field.\"}},\"length()\":{\"returns\":{\"_0\":\"Number of objects in the container.\"}},\"push(bytes32)\":{\"params\":{\"_object\":\"A 32 byte value to insert into the container.\"}},\"push(bytes32,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_object\":\"A 32 byte value to insert into the container.\"}},\"resolve(string)\":{\"params\":{\"_name\":\"Name to resolve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"setGlobalMetadata(bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata to set.\"}}},\"title\":\"ChainStorageContainer\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"deleteElementsAfterInclusive(uint256)\":{\"notice\":\"Removes all objects after and including a given index.\"},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"notice\":\"Removes all objects after and including a given index. Also allows setting the global metadata field.\"},\"get(uint256)\":{\"notice\":\"Retrieves an object from the container.\"},\"getGlobalMetadata()\":{\"notice\":\"Retrieves the container's global metadata field.\"},\"length()\":{\"notice\":\"Retrieves the number of objects stored in the container.\"},\"push(bytes32)\":{\"notice\":\"Pushes an object into the container.\"},\"push(bytes32,bytes27)\":{\"notice\":\"Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global metadata (it's an optimization).\"},\"resolve(string)\":{\"notice\":\"Resolves the address associated with a given name.\"},\"setGlobalMetadata(bytes27)\":{\"notice\":\"Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/rollup/ChainStorageContainer.sol\":\"ChainStorageContainer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/rollup/ChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_Buffer } from \\\"../../libraries/utils/Lib_Buffer.sol\\\";\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\n\\n/* Interface Imports */\\nimport { IChainStorageContainer } from \\\"./IChainStorageContainer.sol\\\";\\n\\n/**\\n * @title ChainStorageContainer\\n * @dev The Chain Storage Container provides its owner contract with read, write and delete\\n * functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which\\n * can no longer be used in a fraud proof due to the fraud window having passed, and the associated\\n * chain state or transactions being finalized.\\n * Three distinct Chain Storage Containers will be deployed on Layer 1:\\n * 1. Stores transaction batches for the Canonical Transaction Chain\\n * 2. Stores queued transactions for the Canonical Transaction Chain\\n * 3. Stores chain state batches for the State Commitment Chain\\n *\\n */\\ncontract ChainStorageContainer is IChainStorageContainer, Lib_AddressResolver {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Lib_Buffer.Buffer;\\n\\n /*************\\n * Variables *\\n *************/\\n\\n string public owner;\\n Lib_Buffer.Buffer internal buffer;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Address Manager.\\n * @param _owner Name of the contract that owns this container (will be resolved later).\\n */\\n constructor(address _libAddressManager, string memory _owner)\\n Lib_AddressResolver(_libAddressManager)\\n {\\n owner = _owner;\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n modifier onlyOwner() {\\n require(\\n msg.sender == resolve(owner),\\n \\\"ChainStorageContainer: Function can only be called by the owner.\\\"\\n );\\n _;\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function setGlobalMetadata(bytes27 _globalMetadata) public onlyOwner {\\n return buffer.setExtraData(_globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function getGlobalMetadata() public view returns (bytes27) {\\n return buffer.getExtraData();\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function length() public view returns (uint256) {\\n return uint256(buffer.getLength());\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function push(bytes32 _object) public onlyOwner {\\n buffer.push(_object);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function push(bytes32 _object, bytes27 _globalMetadata) public onlyOwner {\\n buffer.push(_object, _globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function get(uint256 _index) public view returns (bytes32) {\\n return buffer.get(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function deleteElementsAfterInclusive(uint256 _index) public onlyOwner {\\n buffer.deleteElementsAfterInclusive(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n // slither-disable-next-line external-function\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata)\\n public\\n onlyOwner\\n {\\n buffer.deleteElementsAfterInclusive(uint40(_index), _globalMetadata);\\n }\\n}\\n\",\"keccak256\":\"0x5acd889488ab8eab50d5527d1b18b00214a3242acbf9d89fbeaf188322f81a58\",\"license\":\"MIT\"},\"contracts/L1/rollup/IChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title IChainStorageContainer\\n */\\ninterface IChainStorageContainer {\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the container's global metadata field. We're using `bytes27` here because we use five\\n * bytes to maintain the length of the underlying data structure, meaning we have an extra\\n * 27 bytes to store arbitrary data.\\n * @param _globalMetadata New global metadata to set.\\n */\\n function setGlobalMetadata(bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves the container's global metadata field.\\n * @return Container global metadata field.\\n */\\n function getGlobalMetadata() external view returns (bytes27);\\n\\n /**\\n * Retrieves the number of objects stored in the container.\\n * @return Number of objects in the container.\\n */\\n function length() external view returns (uint256);\\n\\n /**\\n * Pushes an object into the container.\\n * @param _object A 32 byte value to insert into the container.\\n */\\n function push(bytes32 _object) external;\\n\\n /**\\n * Pushes an object into the container. Function allows setting the global metadata since\\n * we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global\\n * metadata (it's an optimization).\\n * @param _object A 32 byte value to insert into the container.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function push(bytes32 _object, bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves an object from the container.\\n * @param _index Index of the particular object to access.\\n * @return 32 byte object value.\\n */\\n function get(uint256 _index) external view returns (bytes32);\\n\\n /**\\n * Removes all objects after and including a given index.\\n * @param _index Object index to delete from.\\n */\\n function deleteElementsAfterInclusive(uint256 _index) external;\\n\\n /**\\n * Removes all objects after and including a given index. Also allows setting the global\\n * metadata field.\\n * @param _index Object index to delete from.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external;\\n}\\n\",\"keccak256\":\"0xe55ad72572ec47dc09a02228d0c5a438571c76a41d16d92b35add057811977ce\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\nabstract contract Lib_AddressResolver {\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public libAddressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n */\\n constructor(address _libAddressManager) {\\n libAddressManager = Lib_AddressManager(_libAddressManager);\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Resolves the address associated with a given name.\\n * @param _name Name to resolve an address for.\\n * @return Address associated with the given name.\\n */\\n function resolve(string memory _name) public view returns (address) {\\n return libAddressManager.getAddress(_name);\\n }\\n}\\n\",\"keccak256\":\"0x515c4db671a28e2fe180201f6d11c0208c05f582ca3489fb6b8e81c27659bc62\",\"license\":\"MIT\"},\"contracts/libraries/utils/Lib_Buffer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Lib_Buffer\\n * @dev This library implements a bytes32 storage array with some additional gas-optimized\\n * functionality. In particular, it encodes its length as a uint40, and tightly packs this with an\\n * overwritable \\\"extra data\\\" field so we can store more information with a single SSTORE.\\n */\\nlibrary Lib_Buffer {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Buffer;\\n\\n /***********\\n * Structs *\\n ***********/\\n\\n struct Buffer {\\n bytes32 context;\\n mapping(uint256 => bytes32) buf;\\n }\\n\\n struct BufferContext {\\n // Stores the length of the array. Uint40 is way more elements than we'll ever reasonably\\n // need in an array and we get an extra 27 bytes of extra data to play with.\\n uint40 length;\\n // Arbitrary extra data that can be modified whenever the length is updated. Useful for\\n // squeezing out some gas optimizations.\\n bytes27 extraData;\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n * @param _extraData Global extra data.\\n */\\n function push(\\n Buffer storage _self,\\n bytes32 _value,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.buf[ctx.length] = _value;\\n\\n // Bump the global index and insert our extra data, then save the context.\\n ctx.length++;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n */\\n function push(Buffer storage _self, bytes32 _value) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.push(_value, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves an element from the buffer.\\n * @param _self Buffer to access.\\n * @param _index Element index to retrieve.\\n * @return Value of the element at the given index.\\n */\\n function get(Buffer storage _self, uint256 _index) internal view returns (bytes32) {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n return _self.buf[_index];\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n * @param _extraData Optional global extra data.\\n */\\n function deleteElementsAfterInclusive(\\n Buffer storage _self,\\n uint40 _index,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n // Set our length and extra data, save the context.\\n ctx.length = _index;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n */\\n function deleteElementsAfterInclusive(Buffer storage _self, uint40 _index) internal {\\n BufferContext memory ctx = _self.getContext();\\n _self.deleteElementsAfterInclusive(_index, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves the current global index.\\n * @param _self Buffer to access.\\n * @return Current global index.\\n */\\n function getLength(Buffer storage _self) internal view returns (uint40) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.length;\\n }\\n\\n /**\\n * Changes current global extra data.\\n * @param _self Buffer to access.\\n * @param _extraData New global extra data.\\n */\\n function setExtraData(Buffer storage _self, bytes27 _extraData) internal {\\n BufferContext memory ctx = _self.getContext();\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Retrieves the current global extra data.\\n * @param _self Buffer to access.\\n * @return Current global extra data.\\n */\\n function getExtraData(Buffer storage _self) internal view returns (bytes27) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.extraData;\\n }\\n\\n /**\\n * Sets the current buffer context.\\n * @param _self Buffer to access.\\n * @param _ctx Current buffer context.\\n */\\n function setContext(Buffer storage _self, BufferContext memory _ctx) internal {\\n bytes32 context;\\n uint40 length = _ctx.length;\\n bytes27 extraData = _ctx.extraData;\\n assembly {\\n context := length\\n context := or(context, extraData)\\n }\\n\\n if (_self.context != context) {\\n _self.context = context;\\n }\\n }\\n\\n /**\\n * Retrieves the current buffer context.\\n * @param _self Buffer to access.\\n * @return Current buffer context.\\n */\\n function getContext(Buffer storage _self) internal view returns (BufferContext memory) {\\n bytes32 context = _self.context;\\n uint40 length;\\n bytes27 extraData;\\n assembly {\\n length := and(\\n context,\\n 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF\\n )\\n extraData := and(\\n context,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000\\n )\\n }\\n\\n return BufferContext({ length: length, extraData: extraData });\\n }\\n}\\n\",\"keccak256\":\"0x38917b618db448e356c76c999ce9aaca094541eb1f9bc65b06b8d4d84308f056\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b50604051620011b3380380620011b3833981016040819052620000349162000129565b600080546001600160a01b0319166001600160a01b0384161790558051620000649060019060208401906200006d565b50505062000266565b8280546200007b9062000229565b90600052602060002090601f0160209004810192826200009f5760008555620000ea565b82601f10620000ba57805160ff1916838001178555620000ea565b82800160010185558215620000ea579182015b82811115620000ea578251825591602001919060010190620000cd565b50620000f8929150620000fc565b5090565b5b80821115620000f85760008155600101620000fd565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200013d57600080fd5b82516001600160a01b03811681146200015557600080fd5b602084810151919350906001600160401b03808211156200017557600080fd5b818601915086601f8301126200018a57600080fd5b8151818111156200019f576200019f62000113565b604051601f8201601f19908116603f01168101908382118183101715620001ca57620001ca62000113565b816040528281528986848701011115620001e357600080fd5b600093505b82841015620002075784840186015181850187015292850192620001e8565b82841115620002195760008684830101525b8096505050505050509250929050565b600181811c908216806200023e57607f821691505b602082108114156200026057634e487b7160e01b600052602260045260246000fd5b50919050565b610f3d80620002766000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea2646970667358221220e1995ee56c4c5e67de41c56ad510b16704727d3ab1fa5bb2e3c62b0bd7c0597564736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea2646970667358221220e1995ee56c4c5e67de41c56ad510b16704727d3ab1fa5bb2e3c62b0bd7c0597564736f6c63430008090033",
"devdoc": {
"details": "The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_libAddressManager": "Address of the Address Manager.",
"_owner": "Name of the contract that owns this container (will be resolved later)."
}
},
"deleteElementsAfterInclusive(uint256)": {
"params": {
"_index": "Object index to delete from."
}
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_index": "Object index to delete from."
}
},
"get(uint256)": {
"params": {
"_index": "Index of the particular object to access."
},
"returns": {
"_0": "32 byte object value."
}
},
"getGlobalMetadata()": {
"returns": {
"_0": "Container global metadata field."
}
},
"length()": {
"returns": {
"_0": "Number of objects in the container."
}
},
"push(bytes32)": {
"params": {
"_object": "A 32 byte value to insert into the container."
}
},
"push(bytes32,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_object": "A 32 byte value to insert into the container."
}
},
"resolve(string)": {
"params": {
"_name": "Name to resolve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
},
"setGlobalMetadata(bytes27)": {
"params": {
"_globalMetadata": "New global metadata to set."
}
}
},
"title": "ChainStorageContainer",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"deleteElementsAfterInclusive(uint256)": {
"notice": "Removes all objects after and including a given index."
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"notice": "Removes all objects after and including a given index. Also allows setting the global metadata field."
},
"get(uint256)": {
"notice": "Retrieves an object from the container."
},
"getGlobalMetadata()": {
"notice": "Retrieves the container's global metadata field."
},
"length()": {
"notice": "Retrieves the number of objects stored in the container."
},
"push(bytes32)": {
"notice": "Pushes an object into the container."
},
"push(bytes32,bytes27)": {
"notice": "Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \"length\" storage slot anyway, which also contains the global metadata (it's an optimization)."
},
"resolve(string)": {
"notice": "Resolves the address associated with a given name."
},
"setGlobalMetadata(bytes27)": {
"notice": "Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 7092,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "libAddressManager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)7084"
},
{
"astId": 4067,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "owner",
"offset": 0,
"slot": "1",
"type": "t_string_storage"
},
{
"astId": 4070,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buffer",
"offset": 0,
"slot": "2",
"type": "t_struct(Buffer)9208_storage"
}
],
"types": {
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(Lib_AddressManager)7084": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_mapping(t_uint256,t_bytes32)": {
"encoding": "mapping",
"key": "t_uint256",
"label": "mapping(uint256 => bytes32)",
"numberOfBytes": "32",
"value": "t_bytes32"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
"t_struct(Buffer)9208_storage": {
"encoding": "inplace",
"label": "struct Lib_Buffer.Buffer",
"members": [
{
"astId": 9203,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "context",
"offset": 0,
"slot": "0",
"type": "t_bytes32"
},
{
"astId": 9207,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buf",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_uint256,t_bytes32)"
}
],
"numberOfBytes": "64"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0x0e62FAf76a0239827f35f41478b521293e06195a",
"abi": [
{
"inputs": [
{
"internalType": "contract L1ChugSplashProxy",
"name": "_target",
"type": "address"
},
{
"internalType": "address",
"name": "_finalOwner",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_codeHash",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_messengerSlotKey",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_messengerSlotVal",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_bridgeSlotKey",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_bridgeSlotVal",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "bridgeSlotKey",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bridgeSlotVal",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "codeHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_code",
"type": "bytes"
}
],
"name": "doActions",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "finalOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isUpgrading",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "messengerSlotKey",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "messengerSlotVal",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "returnOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "target",
"outputs": [
{
"internalType": "contract L1ChugSplashProxy",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x9ca0a256d3e3a39d145e6ceb6eb2880814741a2b812ff6a1fcc68141f4ca5364",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x0e62FAf76a0239827f35f41478b521293e06195a",
"transactionIndex": 56,
"gasUsed": "600252",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x969fb92426c43e6e7c3789ddcae6190afb1188255b3cabfb7cd54d08c29da204",
"transactionHash": "0x9ca0a256d3e3a39d145e6ceb6eb2880814741a2b812ff6a1fcc68141f4ca5364",
"logs": [],
"blockNumber": 7017164,
"cumulativeGasUsed": "4082294",
"status": 1,
"byzantium": true
},
"args": [
"0x636Af16bf2f682dD3109e60102b8E1A089FedAa8",
"0xf80267194936da1E98dB10bcE06F3147D580a62e",
"0x2e552c5e1eaa6bcb8ea89d558309b9a8a26daa8cfe310169433a912499962b95",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000005086d1eEF304eb5284A0f6720f79403b4e9bE294",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000004200000000000000000000000000000000000010"
],
"numDeployments": 1,
"solcInputHash": "1922d6575f24d34049f0f77444309807",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract L1ChugSplashProxy\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_finalOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_codeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_messengerSlotKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_messengerSlotVal\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_bridgeSlotKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_bridgeSlotVal\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"bridgeSlotKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeSlotVal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"codeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"doActions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messengerSlotKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messengerSlotVal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"returnOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"target\",\"outputs\":[{\"internalType\":\"contract L1ChugSplashProxy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're working on a generalized version of this but this is good enough for the moment.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"ChugSplashDictator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"returnOwnership()\":{\"notice\":\"Transfers ownership of this contract to the finalOwner. Only callable by the finalOwner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/deployment/ChugSplashDictator.sol\":\"ChugSplashDictator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/L1/deployment/ChugSplashDictator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { L1ChugSplashProxy } from \\\"../../chugsplash/L1ChugSplashProxy.sol\\\";\\nimport { iL1ChugSplashDeployer } from \\\"../../chugsplash/interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title ChugSplashDictator\\n * @dev Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're\\n * working on a generalized version of this but this is good enough for the moment.\\n */\\ncontract ChugSplashDictator is iL1ChugSplashDeployer {\\n /*************\\n * Variables *\\n *************/\\n\\n // slither-disable-next-line constable-states\\n bool public isUpgrading = true;\\n L1ChugSplashProxy public target;\\n address public finalOwner;\\n bytes32 public codeHash;\\n bytes32 public messengerSlotKey;\\n bytes32 public messengerSlotVal;\\n bytes32 public bridgeSlotKey;\\n bytes32 public bridgeSlotVal;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n constructor(\\n L1ChugSplashProxy _target,\\n address _finalOwner,\\n bytes32 _codeHash,\\n bytes32 _messengerSlotKey,\\n bytes32 _messengerSlotVal,\\n bytes32 _bridgeSlotKey,\\n bytes32 _bridgeSlotVal\\n ) {\\n target = _target;\\n finalOwner = _finalOwner;\\n codeHash = _codeHash;\\n messengerSlotKey = _messengerSlotKey;\\n messengerSlotVal = _messengerSlotVal;\\n bridgeSlotKey = _bridgeSlotKey;\\n bridgeSlotVal = _bridgeSlotVal;\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n function doActions(bytes memory _code) external {\\n require(keccak256(_code) == codeHash, \\\"ChugSplashDictator: Incorrect code hash.\\\");\\n\\n target.setCode(_code);\\n target.setStorage(messengerSlotKey, messengerSlotVal);\\n target.setStorage(bridgeSlotKey, bridgeSlotVal);\\n target.setOwner(finalOwner);\\n }\\n\\n /**\\n * Transfers ownership of this contract to the finalOwner.\\n * Only callable by the finalOwner, which is intended to be our multisig.\\n * This function shouldn't be necessary, but it gives a sense of reassurance that we can\\n * recover if something really surprising goes wrong.\\n */\\n function returnOwnership() external {\\n require(msg.sender == finalOwner, \\\"ChugSplashDictator: only callable by finalOwner\\\");\\n\\n target.setOwner(finalOwner);\\n }\\n}\\n\",\"keccak256\":\"0xb67a727f5db454284c84ba511b11376745f8a2d429b30e9370c15991cde07621\",\"license\":\"MIT\"},\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(address _owner) {\\n _setOwner(_owner);\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector)\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(ret == 0, \\\"L1ChugSplashProxy: system is currently being upgraded\\\");\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n // slither-disable-next-line incorrect-modifier\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n // slither-disable-next-line external-function\\n function setCode(bytes memory _code) public proxyCallIfNotOwner {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n // slither-disable-next-line external-function\\n function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n // slither-disable-next-line external-function\\n function setOwner(address _owner) public proxyCallIfNotOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n // slither-disable-next-line external-function\\n function getOwner() public proxyCallIfNotOwner returns (address) {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n // slither-disable-next-line external-function\\n function getImplementation() public proxyCallIfNotOwner returns (address) {\\n return _getImplementation();\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(address _owner) internal {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal onlyWhenNotPaused {\\n address implementation = _getImplementation();\\n\\n require(implementation != address(0), \\\"L1ChugSplashProxy: implementation is not set yet\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3cb52dfdc2706992572dd5621ae89ba919fd20539b73488a455d564f16f1b8d\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading() external view returns (bool);\\n}\\n\",\"keccak256\":\"0x9a496d99f111c1091f0c33d6bfc7802a522baa7235614b0014f35e4bbe280e57\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040526000805460ff1916600117905534801561001d57600080fd5b5060405161088338038061088383398101604081905261003c916100a8565b60008054610100600160a81b0319166101006001600160a01b03998a1602179055600180546001600160a01b031916969097169590951790955560029290925560035560045560059190915560065561010f565b6001600160a01b03811681146100a557600080fd5b50565b600080600080600080600060e0888a0312156100c357600080fd5b87516100ce81610090565b60208901519097506100df81610090565b604089015160608a015160808b015160a08c015160c0909c01519a9d939c50919a90999198509650945092505050565b6107658061011e6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063708518de11610076578063a3b2d8a51161005b578063a3b2d8a51461015c578063b794726214610165578063d4b839921461018257600080fd5b8063708518de1461014a578063907023dd1461015357600080fd5b806318edaaf2116100a757806318edaaf214610122578063297d1a34146101395780635307023b1461014157600080fd5b80630bf56f21146100c357806317ad94ec146100d8575b600080fd5b6100d66100d13660046105ed565b6101a7565b005b6001546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61012b60025481565b604051908152602001610119565b6100d6610489565b61012b60045481565b61012b60035481565b61012b60065481565b61012b60055481565b6000546101729060ff1681565b6040519015158152602001610119565b6000546100f890610100900473ffffffffffffffffffffffffffffffffffffffff1681565b6002548151602083012014610243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4368756753706c6173684469637461746f723a20496e636f727265637420636f60448201527f646520686173682e00000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000546040517f6c5d4ad000000000000000000000000000000000000000000000000000000000815261010090910473ffffffffffffffffffffffffffffffffffffffff1690636c5d4ad09061029d9084906004016106bc565b600060405180830381600087803b1580156102b757600080fd5b505af11580156102cb573d6000803e3d6000fd5b5050600054600354600480546040517f9b0b0fda00000000000000000000000000000000000000000000000000000000815291820192909252602481019190915261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b15801561034e57600080fd5b505af1158015610362573d6000803e3d6000fd5b50506000546005546006546040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081526004810192909252602482015261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b50506000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526101009092041692506313af40359150602401600060405180830381600087803b15801561046e57600080fd5b505af1158015610482573d6000803e3d6000fd5b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610530576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4368756753706c6173684469637461746f723a206f6e6c792063616c6c61626c60448201527f652062792066696e616c4f776e65720000000000000000000000000000000000606482015260840161023a565b6000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015261010090920416906313af403590602401600060405180830381600087803b1580156105a457600080fd5b505af11580156105b8573d6000803e3d6000fd5b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105ff57600080fd5b813567ffffffffffffffff8082111561061757600080fd5b818401915084601f83011261062b57600080fd5b81358181111561063d5761063d6105be565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610683576106836105be565b8160405282815287602084870101111561069c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156106e9578581018301518582016040015282016106cd565b818111156106fb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea2646970667358221220d6996ebde67a73563bf52d2b5545adec064534b2fcd91ec70e83fc1ef951152464736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063708518de11610076578063a3b2d8a51161005b578063a3b2d8a51461015c578063b794726214610165578063d4b839921461018257600080fd5b8063708518de1461014a578063907023dd1461015357600080fd5b806318edaaf2116100a757806318edaaf214610122578063297d1a34146101395780635307023b1461014157600080fd5b80630bf56f21146100c357806317ad94ec146100d8575b600080fd5b6100d66100d13660046105ed565b6101a7565b005b6001546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61012b60025481565b604051908152602001610119565b6100d6610489565b61012b60045481565b61012b60035481565b61012b60065481565b61012b60055481565b6000546101729060ff1681565b6040519015158152602001610119565b6000546100f890610100900473ffffffffffffffffffffffffffffffffffffffff1681565b6002548151602083012014610243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4368756753706c6173684469637461746f723a20496e636f727265637420636f60448201527f646520686173682e00000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000546040517f6c5d4ad000000000000000000000000000000000000000000000000000000000815261010090910473ffffffffffffffffffffffffffffffffffffffff1690636c5d4ad09061029d9084906004016106bc565b600060405180830381600087803b1580156102b757600080fd5b505af11580156102cb573d6000803e3d6000fd5b5050600054600354600480546040517f9b0b0fda00000000000000000000000000000000000000000000000000000000815291820192909252602481019190915261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b15801561034e57600080fd5b505af1158015610362573d6000803e3d6000fd5b50506000546005546006546040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081526004810192909252602482015261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b50506000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526101009092041692506313af40359150602401600060405180830381600087803b15801561046e57600080fd5b505af1158015610482573d6000803e3d6000fd5b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610530576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4368756753706c6173684469637461746f723a206f6e6c792063616c6c61626c60448201527f652062792066696e616c4f776e65720000000000000000000000000000000000606482015260840161023a565b6000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015261010090920416906313af403590602401600060405180830381600087803b1580156105a457600080fd5b505af11580156105b8573d6000803e3d6000fd5b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105ff57600080fd5b813567ffffffffffffffff8082111561061757600080fd5b818401915084601f83011261062b57600080fd5b81358181111561063d5761063d6105be565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610683576106836105be565b8160405282815287602084870101111561069c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156106e9578581018301518582016040015282016106cd565b818111156106fb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea2646970667358221220d6996ebde67a73563bf52d2b5545adec064534b2fcd91ec70e83fc1ef951152464736f6c63430008090033",
"devdoc": {
"details": "Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're working on a generalized version of this but this is good enough for the moment.",
"kind": "dev",
"methods": {},
"title": "ChugSplashDictator",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"returnOwnership()": {
"notice": "Transfers ownership of this contract to the finalOwner. Only callable by the finalOwner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 11,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "isUpgrading",
"offset": 0,
"slot": "0",
"type": "t_bool"
},
{
"astId": 14,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "target",
"offset": 1,
"slot": "0",
"type": "t_contract(L1ChugSplashProxy)420"
},
{
"astId": 16,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "finalOwner",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 18,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "codeHash",
"offset": 0,
"slot": "2",
"type": "t_bytes32"
},
{
"astId": 20,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "messengerSlotKey",
"offset": 0,
"slot": "3",
"type": "t_bytes32"
},
{
"astId": 22,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "messengerSlotVal",
"offset": 0,
"slot": "4",
"type": "t_bytes32"
},
{
"astId": 24,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "bridgeSlotKey",
"offset": 0,
"slot": "5",
"type": "t_bytes32"
},
{
"astId": 26,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "bridgeSlotVal",
"offset": 0,
"slot": "6",
"type": "t_bytes32"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"encoding": "inplace",
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(L1ChugSplashProxy)420": {
"encoding": "inplace",
"label": "contract L1ChugSplashProxy",
"numberOfBytes": "20"
}
}
}
}
\ No newline at end of file
{
"address": "0x65DD71354923A51fC00DaE41A39F37eBB66549d4",
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ERC20DepositInitiated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ERC20WithdrawalFinalized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ETHDepositInitiated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ETHWithdrawalFinalized",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositERC20To",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositETH",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositETHTo",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "deposits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "donateETH",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "finalizeERC20Withdrawal",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "finalizeETHWithdrawal",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1messenger",
"type": "address"
},
{
"internalType": "address",
"name": "_l2TokenBridge",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "l2TokenBridge",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "messenger",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0xa9bfe8e196ae906c39a556f86f080b285da42034f7a733bf6b6dbba6f27111f6",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x65DD71354923A51fC00DaE41A39F37eBB66549d4",
"transactionIndex": 18,
"gasUsed": "1467241",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xe9b8bc37502e8825f3767797f4c9b6bda30a40d16046b27adb353d73b7510ae7",
"transactionHash": "0xa9bfe8e196ae906c39a556f86f080b285da42034f7a733bf6b6dbba6f27111f6",
"logs": [],
"blockNumber": 7017179,
"cumulativeGasUsed": "2738197",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "8d6d99a3584a757f4a6db32b22382ae9",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ERC20DepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ERC20WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ETHDepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ETHWithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeERC20Withdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeETHWithdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1messenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2TokenBridge\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits and listening to it for newly finalized withdrawals.\",\"kind\":\"dev\",\"methods\":{\"depositERC20(address,address,uint256,uint32,bytes)\":{\"details\":\"deposit an amount of the ERC20 to the caller's balance on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit\",\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l1Token\":\"Address of the L1 ERC20 we are depositing\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\",\"_l2Token\":\"Address of the L1 respective L2 ERC20\"}},\"depositERC20To(address,address,address,uint256,uint32,bytes)\":{\"details\":\"deposit an amount of ERC20 to a recipient's balance on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l1Token\":\"Address of the L1 ERC20 we are depositing\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\",\"_l2Token\":\"Address of the L1 respective L2 ERC20\",\"_to\":\"L2 address to credit the withdrawal to.\"}},\"depositETH(uint32,bytes)\":{\"details\":\"Deposit an amount of the ETH to the caller's balance on L2.\",\"params\":{\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\"}},\"depositETHTo(address,uint32,bytes)\":{\"details\":\"Deposit an amount of ETH to a recipient's balance on L2.\",\"params\":{\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\",\"_to\":\"L2 address to credit the withdrawal to.\"}},\"donateETH()\":{\"details\":\"Adds ETH balance to the account. This is meant to allow for ETH to be migrated from an old gateway to a new gateway. NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the old contract\"},\"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)\":{\"details\":\"Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ERC20 token. This call will fail if the initialized withdrawal from L2 has not been finalized.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_data\":\"Data provided by the sender on L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_from\":\"L2 address initiating the transfer.\",\"_l1Token\":\"Address of L1 token to finalizeWithdrawal for.\",\"_l2Token\":\"Address of L2 token where withdrawal was initiated.\",\"_to\":\"L1 address to credit the withdrawal to.\"}},\"finalizeETHWithdrawal(address,address,uint256,bytes)\":{\"details\":\"Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_from\":\"L2 address initiating the transfer.\",\"_to\":\"L1 address to credit the withdrawal to.\"}},\"initialize(address,address)\":{\"params\":{\"_l1messenger\":\"L1 Messenger address being used for cross-chain communications.\",\"_l2TokenBridge\":\"L2 standard bridge address.\"}}},\"stateVariables\":{\"l2TokenBridge\":{\"details\":\"get the address of the corresponding L2 bridge contract.\",\"return\":\"Address of the corresponding L2 bridge contract.\",\"returns\":{\"_0\":\"Address of the corresponding L2 bridge contract.\"}}},\"title\":\"L1StandardBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/messaging/L1StandardBridge.sol\":\"L1StandardBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"contracts/L1/messaging/IL1ERC20Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title IL1ERC20Bridge\\n */\\ninterface IL1ERC20Bridge {\\n /**********\\n * Events *\\n **********/\\n\\n event ERC20DepositInitiated(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event ERC20WithdrawalFinalized(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @dev get the address of the corresponding L2 bridge contract.\\n * @return Address of the corresponding L2 bridge contract.\\n */\\n function l2TokenBridge() external returns (address);\\n\\n /**\\n * @dev deposit an amount of the ERC20 to the caller's balance on L2.\\n * @param _l1Token Address of the L1 ERC20 we are depositing\\n * @param _l2Token Address of the L1 respective L2 ERC20\\n * @param _amount Amount of the ERC20 to deposit\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositERC20(\\n address _l1Token,\\n address _l2Token,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external;\\n\\n /**\\n * @dev deposit an amount of ERC20 to a recipient's balance on L2.\\n * @param _l1Token Address of the L1 ERC20 we are depositing\\n * @param _l2Token Address of the L1 respective L2 ERC20\\n * @param _to L2 address to credit the withdrawal to.\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositERC20To(\\n address _l1Token,\\n address _l2Token,\\n address _to,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external;\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the\\n * L1 ERC20 token.\\n * This call will fail if the initialized withdrawal from L2 has not been finalized.\\n *\\n * @param _l1Token Address of L1 token to finalizeWithdrawal for.\\n * @param _l2Token Address of L2 token where withdrawal was initiated.\\n * @param _from L2 address initiating the transfer.\\n * @param _to L1 address to credit the withdrawal to.\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _data Data provided by the sender on L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function finalizeERC20Withdrawal(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external;\\n}\\n\",\"keccak256\":\"0x69f831896dcbb6bef4f2d6c8be6cd1bf352f5910074d3ce973b9f8e0a4f4c1dd\",\"license\":\"MIT\"},\"contracts/L1/messaging/IL1StandardBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\nimport \\\"./IL1ERC20Bridge.sol\\\";\\n\\n/**\\n * @title IL1StandardBridge\\n */\\ninterface IL1StandardBridge is IL1ERC20Bridge {\\n /**********\\n * Events *\\n **********/\\n event ETHDepositInitiated(\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event ETHWithdrawalFinalized(\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @dev Deposit an amount of the ETH to the caller's balance on L2.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositETH(uint32 _l2Gas, bytes calldata _data) external payable;\\n\\n /**\\n * @dev Deposit an amount of ETH to a recipient's balance on L2.\\n * @param _to L2 address to credit the withdrawal to.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositETHTo(\\n address _to,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external payable;\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the\\n * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called\\n * before the withdrawal is finalized.\\n * @param _from L2 address initiating the transfer.\\n * @param _to L1 address to credit the withdrawal to.\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function finalizeETHWithdrawal(\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external;\\n}\\n\",\"keccak256\":\"0x3d511f1bcea86aa88a9c41798926ea75b5b3f455c0377e63223a123a9e714ddc\",\"license\":\"MIT\"},\"contracts/L1/messaging/L1StandardBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Interface Imports */\\nimport { IL1StandardBridge } from \\\"./IL1StandardBridge.sol\\\";\\nimport { IL1ERC20Bridge } from \\\"./IL1ERC20Bridge.sol\\\";\\nimport { IL2ERC20Bridge } from \\\"../../L2/messaging/IL2ERC20Bridge.sol\\\";\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/* Library Imports */\\nimport { CrossDomainEnabled } from \\\"../../libraries/bridge/CrossDomainEnabled.sol\\\";\\nimport { Lib_PredeployAddresses } from \\\"../../libraries/constants/Lib_PredeployAddresses.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/**\\n * @title L1StandardBridge\\n * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard\\n * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits\\n * and listening to it for newly finalized withdrawals.\\n *\\n */\\ncontract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled {\\n using SafeERC20 for IERC20;\\n\\n /********************************\\n * External Contract References *\\n ********************************/\\n\\n address public l2TokenBridge;\\n\\n // Maps L1 token to L2 token to balance of the L1 token deposited\\n mapping(address => mapping(address => uint256)) public deposits;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n // This contract lives behind a proxy, so the constructor parameters will go unused.\\n constructor() CrossDomainEnabled(address(0)) {}\\n\\n /******************\\n * Initialization *\\n ******************/\\n\\n /**\\n * @param _l1messenger L1 Messenger address being used for cross-chain communications.\\n * @param _l2TokenBridge L2 standard bridge address.\\n */\\n // slither-disable-next-line external-function\\n function initialize(address _l1messenger, address _l2TokenBridge) public {\\n require(messenger == address(0), \\\"Contract has already been initialized.\\\");\\n messenger = _l1messenger;\\n l2TokenBridge = _l2TokenBridge;\\n }\\n\\n /**************\\n * Depositing *\\n **************/\\n\\n /** @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious\\n * contract via initcode, but it takes care of the user error we want to avoid.\\n */\\n modifier onlyEOA() {\\n // Used to stop deposits from contracts (avoid accidentally lost tokens)\\n require(!Address.isContract(msg.sender), \\\"Account not EOA\\\");\\n _;\\n }\\n\\n /**\\n * @dev This function can be called with no data\\n * to deposit an amount of ETH to the caller's balance on L2.\\n * Since the receive function doesn't take data, a conservative\\n * default amount is forwarded to L2.\\n */\\n receive() external payable onlyEOA {\\n _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes(\\\"\\\"));\\n }\\n\\n /**\\n * @inheritdoc IL1StandardBridge\\n */\\n function depositETH(uint32 _l2Gas, bytes calldata _data) external payable onlyEOA {\\n _initiateETHDeposit(msg.sender, msg.sender, _l2Gas, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1StandardBridge\\n */\\n function depositETHTo(\\n address _to,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external payable {\\n _initiateETHDeposit(msg.sender, _to, _l2Gas, _data);\\n }\\n\\n /**\\n * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of\\n * the deposit.\\n * @param _from Account to pull the deposit from on L1.\\n * @param _to Account to give the deposit to on L2.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function _initiateETHDeposit(\\n address _from,\\n address _to,\\n uint32 _l2Gas,\\n bytes memory _data\\n ) internal {\\n // Construct calldata for finalizeDeposit call\\n bytes memory message = abi.encodeWithSelector(\\n IL2ERC20Bridge.finalizeDeposit.selector,\\n address(0),\\n Lib_PredeployAddresses.OVM_ETH,\\n _from,\\n _to,\\n msg.value,\\n _data\\n );\\n\\n // Send calldata into L2\\n // slither-disable-next-line reentrancy-events\\n sendCrossDomainMessage(l2TokenBridge, _l2Gas, message);\\n\\n // slither-disable-next-line reentrancy-events\\n emit ETHDepositInitiated(_from, _to, msg.value, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1ERC20Bridge\\n */\\n function depositERC20(\\n address _l1Token,\\n address _l2Token,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external virtual onlyEOA {\\n _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1ERC20Bridge\\n */\\n function depositERC20To(\\n address _l1Token,\\n address _l2Token,\\n address _to,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external virtual {\\n _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data);\\n }\\n\\n /**\\n * @dev Performs the logic for deposits by informing the L2 Deposited Token\\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\\n *\\n * @param _l1Token Address of the L1 ERC20 we are depositing\\n * @param _l2Token Address of the L1 respective L2 ERC20\\n * @param _from Account to pull the deposit from on L1\\n * @param _to Account to give the deposit to on L2\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function _initiateERC20Deposit(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) internal {\\n // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future\\n // withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if\\n // _from is an EOA or address(0).\\n // slither-disable-next-line reentrancy-events, reentrancy-benign\\n IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount);\\n\\n // Construct calldata for _l2Token.finalizeDeposit(_to, _amount)\\n bytes memory message = abi.encodeWithSelector(\\n IL2ERC20Bridge.finalizeDeposit.selector,\\n _l1Token,\\n _l2Token,\\n _from,\\n _to,\\n _amount,\\n _data\\n );\\n\\n // Send calldata into L2\\n // slither-disable-next-line reentrancy-events, reentrancy-benign\\n sendCrossDomainMessage(l2TokenBridge, _l2Gas, message);\\n\\n // slither-disable-next-line reentrancy-benign\\n deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount;\\n\\n // slither-disable-next-line reentrancy-events\\n emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data);\\n }\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @inheritdoc IL1StandardBridge\\n */\\n function finalizeETHWithdrawal(\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external onlyFromCrossDomainAccount(l2TokenBridge) {\\n // slither-disable-next-line reentrancy-events\\n (bool success, ) = _to.call{ value: _amount }(new bytes(0));\\n require(success, \\\"TransferHelper::safeTransferETH: ETH transfer failed\\\");\\n\\n // slither-disable-next-line reentrancy-events\\n emit ETHWithdrawalFinalized(_from, _to, _amount, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1ERC20Bridge\\n */\\n function finalizeERC20Withdrawal(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external onlyFromCrossDomainAccount(l2TokenBridge) {\\n deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] - _amount;\\n\\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer\\n // slither-disable-next-line reentrancy-events\\n IERC20(_l1Token).safeTransfer(_to, _amount);\\n\\n // slither-disable-next-line reentrancy-events\\n emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);\\n }\\n\\n /*****************************\\n * Temporary - Migrating ETH *\\n *****************************/\\n\\n /**\\n * @dev Adds ETH balance to the account. This is meant to allow for ETH\\n * to be migrated from an old gateway to a new gateway.\\n * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the\\n * old contract\\n */\\n function donateETH() external payable {}\\n}\\n\",\"keccak256\":\"0x9b87d80b31401c4907c73ea1b73365a618d3c3d9e67e36fb74d25c0880e1b2bc\",\"license\":\"MIT\"},\"contracts/L2/messaging/IL2ERC20Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title IL2ERC20Bridge\\n */\\ninterface IL2ERC20Bridge {\\n /**********\\n * Events *\\n **********/\\n\\n event WithdrawalInitiated(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event DepositFinalized(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event DepositFailed(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @dev get the address of the corresponding L1 bridge contract.\\n * @return Address of the corresponding L1 bridge contract.\\n */\\n function l1TokenBridge() external returns (address);\\n\\n /**\\n * @dev initiate a withdraw of some tokens to the caller's account on L1\\n * @param _l2Token Address of L2 token where withdrawal was initiated.\\n * @param _amount Amount of the token to withdraw.\\n * param _l1Gas Unused, but included for potential forward compatibility considerations.\\n * @param _data Optional data to forward to L1. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function withdraw(\\n address _l2Token,\\n uint256 _amount,\\n uint32 _l1Gas,\\n bytes calldata _data\\n ) external;\\n\\n /**\\n * @dev initiate a withdraw of some token to a recipient's account on L1.\\n * @param _l2Token Address of L2 token where withdrawal is initiated.\\n * @param _to L1 adress to credit the withdrawal to.\\n * @param _amount Amount of the token to withdraw.\\n * param _l1Gas Unused, but included for potential forward compatibility considerations.\\n * @param _data Optional data to forward to L1. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function withdrawTo(\\n address _l2Token,\\n address _to,\\n uint256 _amount,\\n uint32 _l1Gas,\\n bytes calldata _data\\n ) external;\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @dev Complete a deposit from L1 to L2, and credits funds to the recipient's balance of this\\n * L2 token. This call will fail if it did not originate from a corresponding deposit in\\n * L1StandardTokenBridge.\\n * @param _l1Token Address for the l1 token this is called with\\n * @param _l2Token Address for the l2 token this is called with\\n * @param _from Account to pull the deposit from on L2.\\n * @param _to Address to receive the withdrawal at\\n * @param _amount Amount of the token to withdraw\\n * @param _data Data provider by the sender on L1. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function finalizeDeposit(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external;\\n}\\n\",\"keccak256\":\"0x4674c3c8733ca0db16c2b81d58227560df36a07ded3b637a0793564d90ac0475\",\"license\":\"MIT\"},\"contracts/libraries/bridge/CrossDomainEnabled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/* Interface Imports */\\nimport { ICrossDomainMessenger } from \\\"./ICrossDomainMessenger.sol\\\";\\n\\n/**\\n * @title CrossDomainEnabled\\n * @dev Helper contract for contracts performing cross-domain communications\\n *\\n * Compiler used: defined by inheriting contract\\n */\\ncontract CrossDomainEnabled {\\n /*************\\n * Variables *\\n *************/\\n\\n // Messenger contract used to send and recieve messages from the other domain.\\n address public messenger;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _messenger Address of the CrossDomainMessenger on the current layer.\\n */\\n constructor(address _messenger) {\\n messenger = _messenger;\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Enforces that the modified function is only callable by a specific cross-domain account.\\n * @param _sourceDomainAccount The only account on the originating domain which is\\n * authenticated to call this function.\\n */\\n modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) {\\n require(\\n msg.sender == address(getCrossDomainMessenger()),\\n \\\"OVM_XCHAIN: messenger contract unauthenticated\\\"\\n );\\n\\n require(\\n getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount,\\n \\\"OVM_XCHAIN: wrong sender of cross-domain message\\\"\\n );\\n\\n _;\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Gets the messenger, usually from storage. This function is exposed in case a child contract\\n * needs to override.\\n * @return The address of the cross-domain messenger contract which should be used.\\n */\\n function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) {\\n return ICrossDomainMessenger(messenger);\\n }\\n\\n /**q\\n * Sends a message to an account on another domain\\n * @param _crossDomainTarget The intended recipient on the destination domain\\n * @param _message The data to send to the target (usually calldata to a function with\\n * `onlyFromCrossDomainAccount()`)\\n * @param _gasLimit The gasLimit for the receipt of the message on the target domain.\\n */\\n function sendCrossDomainMessage(\\n address _crossDomainTarget,\\n uint32 _gasLimit,\\n bytes memory _message\\n ) internal {\\n // slither-disable-next-line reentrancy-events, reentrancy-benign\\n getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit);\\n }\\n}\\n\",\"keccak256\":\"0x9c3cc8b7047c68a403529b15769a21c2e2668ea71db7bef51f123288009811ea\",\"license\":\"MIT\"},\"contracts/libraries/bridge/ICrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title ICrossDomainMessenger\\n */\\ninterface ICrossDomainMessenger {\\n /**********\\n * Events *\\n **********/\\n\\n event SentMessage(\\n address indexed target,\\n address sender,\\n bytes message,\\n uint256 messageNonce,\\n uint256 gasLimit\\n );\\n event RelayedMessage(bytes32 indexed msgHash);\\n event FailedRelayedMessage(bytes32 indexed msgHash);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n function xDomainMessageSender() external view returns (address);\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sends a cross domain message to the target messenger.\\n * @param _target Target contract address.\\n * @param _message Message to send to the target.\\n * @param _gasLimit Gas limit for the provided message.\\n */\\n function sendMessage(\\n address _target,\\n bytes calldata _message,\\n uint32 _gasLimit\\n ) external;\\n}\\n\",\"keccak256\":\"0x8f29ae23021345a20ccac7b5edb3fc38268aef943b65adc8a32e74b80bf1833a\",\"license\":\"MIT\"},\"contracts/libraries/constants/Lib_PredeployAddresses.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Lib_PredeployAddresses\\n */\\nlibrary Lib_PredeployAddresses {\\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\\n address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000);\\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\\n 0x4200000000000000000000000000000000000007;\\n address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008;\\n address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009;\\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\\n address internal constant L2_STANDARD_TOKEN_FACTORY =\\n 0x4200000000000000000000000000000000000012;\\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\\n}\\n\",\"keccak256\":\"0x2bc28307af93e9716151a41a81694b56cbe513ef5eb335fb1d81f35e5db8edfa\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b031916905561199e806100306000396000f3fe6080604052600436106100c05760003560e01c80638b4c40b0116100745780639a2ac6d51161004e5780639a2ac6d514610288578063a9f9e6751461029b578063b1a1a882146102bb57600080fd5b80638b4c40b0146101375780638f601f661461021557806391c49bf81461025b57600080fd5b8063485cc955116100a5578063485cc955146101b557806358a997f6146101d5578063838b2520146101f557600080fd5b80631532ec341461013e5780633cb747bf1461015e57600080fd5b3661013957333b156101195760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f41000000000000000000000000000000000060448201526064015b60405180910390fd5b610137333362030d40604051806020016040528060008152506102ce565b005b600080fd5b34801561014a57600080fd5b50610137610159366004611357565b61041a565b34801561016a57600080fd5b5060005461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c157600080fd5b506101376101d03660046113ca565b610790565b3480156101e157600080fd5b506101376101f036600461141c565b61086f565b34801561020157600080fd5b5061013761021036600461149f565b6108d6565b34801561022157600080fd5b5061024d6102303660046113ca565b600260209081526000928352604080842090915290825290205481565b6040519081526020016101ac565b34801561026757600080fd5b5060015461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b610137610296366004611535565b6108ef565b3480156102a757600080fd5b506101376102b6366004611598565b610937565b6101376102c9366004611611565b610c59565b600063662a633a60e01b600073deaddeaddeaddeaddeaddeaddeaddeaddead000087873487604051602401610308969594939291906116da565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506103ac9073ffffffffffffffffffffffffffffffffffffffff168483610cef565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23348560405161040b929190611735565b60405180910390a35050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661045260005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104f25760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff1661052860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561056d57600080fd5b505afa158015610581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a5919061174e565b73ffffffffffffffffffffffffffffffffffffffff161461062e5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff8716908690604051610665919061176b565b60006040518083038185875af1925050503d80600081146106a2576040519150601f19603f3d011682016040523d82523d6000602084013e6106a7565b606091505b505090508061071e5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c65640000000000000000000000006064820152608401610110565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e63187878760405161077f939291906117d0565b60405180910390a350505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff161561081c5760405162461bcd60e51b815260206004820152602660248201527f436f6e74726163742068617320616c7265616479206265656e20696e6974696160448201527f6c697a65642e00000000000000000000000000000000000000000000000000006064820152608401610110565b6000805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560018054929093169116179055565b333b156108be5760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b6108ce8686333388888888610d77565b505050505050565b6108e68787338888888888610d77565b50505050505050565b61093133858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b50505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661096f60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a0f5760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff16610a4560005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8a57600080fd5b505afa158015610a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac2919061174e565b73ffffffffffffffffffffffffffffffffffffffff1614610b4b5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054610b89908590611822565b73ffffffffffffffffffffffffffffffffffffffff808a166000818152600260209081526040808320948d1683529390529190912091909155610bcd908686610f27565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b388888888604051610c479493929190611839565b60405180910390a45050505050505050565b333b15610ca85760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b610cea33338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b505050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610d4990869085908790600401611879565b600060405180830381600087803b158015610d6357600080fd5b505af11580156108e6573d6000803e3d6000fd5b610d9973ffffffffffffffffffffffffffffffffffffffff8916873087610ffb565b600063662a633a60e01b89898989898888604051602401610dc097969594939291906118be565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600154909150610e649073ffffffffffffffffffffffffffffffffffffffff168583610cef565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c1683529290522054610ea290869061191b565b73ffffffffffffffffffffffffffffffffffffffff808b1660008181526002602090815260408083208e86168085529252918290209490945551918a1692917f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039690610f14908b908b908a908a90611839565b60405180910390a4505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610cea9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611059565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109319085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610f79565b60006110bb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661114b9092919063ffffffff16565b805190915015610cea57808060200190518101906110d99190611933565b610cea5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610110565b606061115a8484600085611164565b90505b9392505050565b6060824710156111dc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610110565b843b61122a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610110565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611253919061176b565b60006040518083038185875af1925050503d8060008114611290576040519150601f19603f3d011682016040523d82523d6000602084013e611295565b606091505b50915091506112a58282866112b0565b979650505050505050565b606083156112bf57508161115d565b8251156112cf5782518084602001fd5b8160405162461bcd60e51b81526004016101109190611955565b73ffffffffffffffffffffffffffffffffffffffff8116811461130b57600080fd5b50565b60008083601f84011261132057600080fd5b50813567ffffffffffffffff81111561133857600080fd5b60208301915083602082850101111561135057600080fd5b9250929050565b60008060008060006080868803121561136f57600080fd5b853561137a816112e9565b9450602086013561138a816112e9565b935060408601359250606086013567ffffffffffffffff8111156113ad57600080fd5b6113b98882890161130e565b969995985093965092949392505050565b600080604083850312156113dd57600080fd5b82356113e8816112e9565b915060208301356113f8816112e9565b809150509250929050565b803563ffffffff8116811461141757600080fd5b919050565b60008060008060008060a0878903121561143557600080fd5b8635611440816112e9565b95506020870135611450816112e9565b94506040870135935061146560608801611403565b9250608087013567ffffffffffffffff81111561148157600080fd5b61148d89828a0161130e565b979a9699509497509295939492505050565b600080600080600080600060c0888a0312156114ba57600080fd5b87356114c5816112e9565b965060208801356114d5816112e9565b955060408801356114e5816112e9565b9450606088013593506114fa60808901611403565b925060a088013567ffffffffffffffff81111561151657600080fd5b6115228a828b0161130e565b989b979a50959850939692959293505050565b6000806000806060858703121561154b57600080fd5b8435611556816112e9565b935061156460208601611403565b9250604085013567ffffffffffffffff81111561158057600080fd5b61158c8782880161130e565b95989497509550505050565b600080600080600080600060c0888a0312156115b357600080fd5b87356115be816112e9565b965060208801356115ce816112e9565b955060408801356115de816112e9565b945060608801356115ee816112e9565b93506080880135925060a088013567ffffffffffffffff81111561151657600080fd5b60008060006040848603121561162657600080fd5b61162f84611403565b9250602084013567ffffffffffffffff81111561164b57600080fd5b6116578682870161130e565b9497909650939450505050565b60005b8381101561167f578181015183820152602001611667565b838111156109315750506000910152565b600081518084526116a8816020860160208601611664565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261172960c0830184611690565b98975050505050505050565b82815260406020820152600061115a6040830184611690565b60006020828403121561176057600080fd5b815161115d816112e9565b6000825161177d818460208701611664565b9190910192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8381526040602082015260006117ea604083018486611787565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611834576118346117f3565b500390565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061186f606083018486611787565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006118a86060830185611690565b905063ffffffff83166040830152949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261190e60c083018486611787565b9998505050505050505050565b6000821982111561192e5761192e6117f3565b500190565b60006020828403121561194557600080fd5b8151801515811461115d57600080fd5b60208152600061115d602083018461169056fea2646970667358221220ab0015e7cee64db6dc95e6eb0899ae4017c78ab54ebce874e3b018a7bc88850364736f6c63430008090033",
"deployedBytecode": "0x6080604052600436106100c05760003560e01c80638b4c40b0116100745780639a2ac6d51161004e5780639a2ac6d514610288578063a9f9e6751461029b578063b1a1a882146102bb57600080fd5b80638b4c40b0146101375780638f601f661461021557806391c49bf81461025b57600080fd5b8063485cc955116100a5578063485cc955146101b557806358a997f6146101d5578063838b2520146101f557600080fd5b80631532ec341461013e5780633cb747bf1461015e57600080fd5b3661013957333b156101195760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f41000000000000000000000000000000000060448201526064015b60405180910390fd5b610137333362030d40604051806020016040528060008152506102ce565b005b600080fd5b34801561014a57600080fd5b50610137610159366004611357565b61041a565b34801561016a57600080fd5b5060005461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c157600080fd5b506101376101d03660046113ca565b610790565b3480156101e157600080fd5b506101376101f036600461141c565b61086f565b34801561020157600080fd5b5061013761021036600461149f565b6108d6565b34801561022157600080fd5b5061024d6102303660046113ca565b600260209081526000928352604080842090915290825290205481565b6040519081526020016101ac565b34801561026757600080fd5b5060015461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b610137610296366004611535565b6108ef565b3480156102a757600080fd5b506101376102b6366004611598565b610937565b6101376102c9366004611611565b610c59565b600063662a633a60e01b600073deaddeaddeaddeaddeaddeaddeaddeaddead000087873487604051602401610308969594939291906116da565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506103ac9073ffffffffffffffffffffffffffffffffffffffff168483610cef565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23348560405161040b929190611735565b60405180910390a35050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661045260005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104f25760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff1661052860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561056d57600080fd5b505afa158015610581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a5919061174e565b73ffffffffffffffffffffffffffffffffffffffff161461062e5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff8716908690604051610665919061176b565b60006040518083038185875af1925050503d80600081146106a2576040519150601f19603f3d011682016040523d82523d6000602084013e6106a7565b606091505b505090508061071e5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c65640000000000000000000000006064820152608401610110565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e63187878760405161077f939291906117d0565b60405180910390a350505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff161561081c5760405162461bcd60e51b815260206004820152602660248201527f436f6e74726163742068617320616c7265616479206265656e20696e6974696160448201527f6c697a65642e00000000000000000000000000000000000000000000000000006064820152608401610110565b6000805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560018054929093169116179055565b333b156108be5760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b6108ce8686333388888888610d77565b505050505050565b6108e68787338888888888610d77565b50505050505050565b61093133858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b50505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661096f60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a0f5760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff16610a4560005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8a57600080fd5b505afa158015610a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac2919061174e565b73ffffffffffffffffffffffffffffffffffffffff1614610b4b5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054610b89908590611822565b73ffffffffffffffffffffffffffffffffffffffff808a166000818152600260209081526040808320948d1683529390529190912091909155610bcd908686610f27565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b388888888604051610c479493929190611839565b60405180910390a45050505050505050565b333b15610ca85760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b610cea33338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b505050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610d4990869085908790600401611879565b600060405180830381600087803b158015610d6357600080fd5b505af11580156108e6573d6000803e3d6000fd5b610d9973ffffffffffffffffffffffffffffffffffffffff8916873087610ffb565b600063662a633a60e01b89898989898888604051602401610dc097969594939291906118be565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600154909150610e649073ffffffffffffffffffffffffffffffffffffffff168583610cef565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c1683529290522054610ea290869061191b565b73ffffffffffffffffffffffffffffffffffffffff808b1660008181526002602090815260408083208e86168085529252918290209490945551918a1692917f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039690610f14908b908b908a908a90611839565b60405180910390a4505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610cea9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611059565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109319085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610f79565b60006110bb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661114b9092919063ffffffff16565b805190915015610cea57808060200190518101906110d99190611933565b610cea5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610110565b606061115a8484600085611164565b90505b9392505050565b6060824710156111dc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610110565b843b61122a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610110565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611253919061176b565b60006040518083038185875af1925050503d8060008114611290576040519150601f19603f3d011682016040523d82523d6000602084013e611295565b606091505b50915091506112a58282866112b0565b979650505050505050565b606083156112bf57508161115d565b8251156112cf5782518084602001fd5b8160405162461bcd60e51b81526004016101109190611955565b73ffffffffffffffffffffffffffffffffffffffff8116811461130b57600080fd5b50565b60008083601f84011261132057600080fd5b50813567ffffffffffffffff81111561133857600080fd5b60208301915083602082850101111561135057600080fd5b9250929050565b60008060008060006080868803121561136f57600080fd5b853561137a816112e9565b9450602086013561138a816112e9565b935060408601359250606086013567ffffffffffffffff8111156113ad57600080fd5b6113b98882890161130e565b969995985093965092949392505050565b600080604083850312156113dd57600080fd5b82356113e8816112e9565b915060208301356113f8816112e9565b809150509250929050565b803563ffffffff8116811461141757600080fd5b919050565b60008060008060008060a0878903121561143557600080fd5b8635611440816112e9565b95506020870135611450816112e9565b94506040870135935061146560608801611403565b9250608087013567ffffffffffffffff81111561148157600080fd5b61148d89828a0161130e565b979a9699509497509295939492505050565b600080600080600080600060c0888a0312156114ba57600080fd5b87356114c5816112e9565b965060208801356114d5816112e9565b955060408801356114e5816112e9565b9450606088013593506114fa60808901611403565b925060a088013567ffffffffffffffff81111561151657600080fd5b6115228a828b0161130e565b989b979a50959850939692959293505050565b6000806000806060858703121561154b57600080fd5b8435611556816112e9565b935061156460208601611403565b9250604085013567ffffffffffffffff81111561158057600080fd5b61158c8782880161130e565b95989497509550505050565b600080600080600080600060c0888a0312156115b357600080fd5b87356115be816112e9565b965060208801356115ce816112e9565b955060408801356115de816112e9565b945060608801356115ee816112e9565b93506080880135925060a088013567ffffffffffffffff81111561151657600080fd5b60008060006040848603121561162657600080fd5b61162f84611403565b9250602084013567ffffffffffffffff81111561164b57600080fd5b6116578682870161130e565b9497909650939450505050565b60005b8381101561167f578181015183820152602001611667565b838111156109315750506000910152565b600081518084526116a8816020860160208601611664565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261172960c0830184611690565b98975050505050505050565b82815260406020820152600061115a6040830184611690565b60006020828403121561176057600080fd5b815161115d816112e9565b6000825161177d818460208701611664565b9190910192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8381526040602082015260006117ea604083018486611787565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611834576118346117f3565b500390565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061186f606083018486611787565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006118a86060830185611690565b905063ffffffff83166040830152949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261190e60c083018486611787565b9998505050505050505050565b6000821982111561192e5761192e6117f3565b500190565b60006020828403121561194557600080fd5b8151801515811461115d57600080fd5b60208152600061115d602083018461169056fea2646970667358221220ab0015e7cee64db6dc95e6eb0899ae4017c78ab54ebce874e3b018a7bc88850364736f6c63430008090033",
"devdoc": {
"details": "The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits and listening to it for newly finalized withdrawals.",
"kind": "dev",
"methods": {
"depositERC20(address,address,uint256,uint32,bytes)": {
"details": "deposit an amount of the ERC20 to the caller's balance on L2.",
"params": {
"_amount": "Amount of the ERC20 to deposit",
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l1Token": "Address of the L1 ERC20 we are depositing",
"_l2Gas": "Gas limit required to complete the deposit on L2.",
"_l2Token": "Address of the L1 respective L2 ERC20"
}
},
"depositERC20To(address,address,address,uint256,uint32,bytes)": {
"details": "deposit an amount of ERC20 to a recipient's balance on L2.",
"params": {
"_amount": "Amount of the ERC20 to deposit.",
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l1Token": "Address of the L1 ERC20 we are depositing",
"_l2Gas": "Gas limit required to complete the deposit on L2.",
"_l2Token": "Address of the L1 respective L2 ERC20",
"_to": "L2 address to credit the withdrawal to."
}
},
"depositETH(uint32,bytes)": {
"details": "Deposit an amount of the ETH to the caller's balance on L2.",
"params": {
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l2Gas": "Gas limit required to complete the deposit on L2."
}
},
"depositETHTo(address,uint32,bytes)": {
"details": "Deposit an amount of ETH to a recipient's balance on L2.",
"params": {
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l2Gas": "Gas limit required to complete the deposit on L2.",
"_to": "L2 address to credit the withdrawal to."
}
},
"donateETH()": {
"details": "Adds ETH balance to the account. This is meant to allow for ETH to be migrated from an old gateway to a new gateway. NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the old contract"
},
"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)": {
"details": "Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ERC20 token. This call will fail if the initialized withdrawal from L2 has not been finalized.",
"params": {
"_amount": "Amount of the ERC20 to deposit.",
"_data": "Data provided by the sender on L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_from": "L2 address initiating the transfer.",
"_l1Token": "Address of L1 token to finalizeWithdrawal for.",
"_l2Token": "Address of L2 token where withdrawal was initiated.",
"_to": "L1 address to credit the withdrawal to."
}
},
"finalizeETHWithdrawal(address,address,uint256,bytes)": {
"details": "Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized.",
"params": {
"_amount": "Amount of the ERC20 to deposit.",
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_from": "L2 address initiating the transfer.",
"_to": "L1 address to credit the withdrawal to."
}
},
"initialize(address,address)": {
"params": {
"_l1messenger": "L1 Messenger address being used for cross-chain communications.",
"_l2TokenBridge": "L2 standard bridge address."
}
}
},
"stateVariables": {
"l2TokenBridge": {
"details": "get the address of the corresponding L2 bridge contract.",
"return": "Address of the corresponding L2 bridge contract.",
"returns": {
"_0": "Address of the corresponding L2 bridge contract."
}
}
},
"title": "L1StandardBridge",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 6621,
"contract": "contracts/L1/messaging/L1StandardBridge.sol:L1StandardBridge",
"label": "messenger",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 2874,
"contract": "contracts/L1/messaging/L1StandardBridge.sol:L1StandardBridge",
"label": "l2TokenBridge",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 2880,
"contract": "contracts/L1/messaging/L1StandardBridge.sol:L1StandardBridge",
"label": "deposits",
"offset": 0,
"slot": "2",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_mapping(t_address,t_uint256))": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => mapping(address => uint256))",
"numberOfBytes": "32",
"value": "t_mapping(t_address,t_uint256)"
},
"t_mapping(t_address,t_uint256)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => uint256)",
"numberOfBytes": "32",
"value": "t_uint256"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"indexed": false,
"internalType": "address",
"name": "_newAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "_oldAddress",
"type": "address"
}
],
"name": "AddressSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "getAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "address",
"name": "_address",
"type": "address"
}
],
"name": "setAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x5048d305a449374d0903384f23c112696557878bf4b1ac52e8e7530898cc03e8",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"transactionIndex": 6,
"gasUsed": "463444",
"logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000001000000000000000001000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000200200000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x59b45b1099d0a874e3bbb89d53ec856f7a7ae3a98013b5be0d3ceff8172240b3",
"transactionHash": "0x5048d305a449374d0903384f23c112696557878bf4b1ac52e8e7530898cc03e8",
"logs": [
{
"transactionIndex": 6,
"blockNumber": 7017076,
"transactionHash": "0x5048d305a449374d0903384f23c112696557878bf4b1ac52e8e7530898cc03e8",
"address": "0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000003a605b442055df2898e18cf518feb2e2a6bd0d31"
],
"data": "0x",
"logIndex": 103,
"blockHash": "0x59b45b1099d0a874e3bbb89d53ec856f7a7ae3a98013b5be0d3ceff8172240b3"
}
],
"blockNumber": 7017076,
"cumulativeGasUsed": "3261100",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "5f4e2d2e170708499f05344e000df330",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oldAddress\",\"type\":\"address\"}],\"name\":\"AddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getAddress(string)\":{\"params\":{\"_name\":\"Name to retrieve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"params\":{\"_address\":\"Address to associate with the name.\",\"_name\":\"String name to associate an address with.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Lib_AddressManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAddress(string)\":{\"notice\":\"Retrieves the address associated with a given name.\"},\"setAddress(string,address)\":{\"notice\":\"Changes the address associated with a particular name.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/resolver/Lib_AddressManager.sol\":\"Lib_AddressManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6107028061007e6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046105e4565b610184565b6100906100da366004610632565b6102d0565b6100746100ed36600461066f565b61030c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b610182600061043c565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610205576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b6000610210836104b1565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000083161790925591519293501690610273908590610691565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006102df846104b1565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b73ffffffffffffffffffffffffffffffffffffffff8116610430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161016f565b6104398161043c565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016104c49190610691565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261052157600080fd5b813567ffffffffffffffff8082111561053c5761053c6104e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610582576105826104e1565b8160405283815286602085880101111561059b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146105df57600080fd5b919050565b600080604083850312156105f757600080fd5b823567ffffffffffffffff81111561060e57600080fd5b61061a85828601610510565b925050610629602084016105bb565b90509250929050565b60006020828403121561064457600080fd5b813567ffffffffffffffff81111561065b57600080fd5b61066784828501610510565b949350505050565b60006020828403121561068157600080fd5b61068a826105bb565b9392505050565b6000825160005b818110156106b25760208186018101518583015201610698565b818111156106c1576000828501525b50919091019291505056fea2646970667358221220882d6a267e1fbcc015c1726b422a6847e08c6be7e987e8b5ec1f7e85aa5095bb64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80639b2ea4bd116100505780639b2ea4bd146100b9578063bf40fac1146100cc578063f2fde38b146100df57600080fd5b8063715018a61461006c5780638da5cb5b14610076575b600080fd5b6100746100f2565b005b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100746100c73660046105e4565b610184565b6100906100da366004610632565b6102d0565b6100746100ed36600461066f565b61030c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b610182600061043c565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610205576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b6000610210836104b1565b60008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff8681167fffffffffffffffffffffffff000000000000000000000000000000000000000083161790925591519293501690610273908590610691565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c910160405180910390a250505050565b6000600160006102df846104b1565b815260208101919091526040016000205473ffffffffffffffffffffffffffffffffffffffff1692915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461038d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161016f565b73ffffffffffffffffffffffffffffffffffffffff8116610430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161016f565b6104398161043c565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000816040516020016104c49190610691565b604051602081830303815290604052805190602001209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261052157600080fd5b813567ffffffffffffffff8082111561053c5761053c6104e1565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610582576105826104e1565b8160405283815286602085880101111561059b57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146105df57600080fd5b919050565b600080604083850312156105f757600080fd5b823567ffffffffffffffff81111561060e57600080fd5b61061a85828601610510565b925050610629602084016105bb565b90509250929050565b60006020828403121561064457600080fd5b813567ffffffffffffffff81111561065b57600080fd5b61066784828501610510565b949350505050565b60006020828403121561068157600080fd5b61068a826105bb565b9392505050565b6000825160005b818110156106b25760208186018101518583015201610698565b818111156106c1576000828501525b50919091019291505056fea2646970667358221220882d6a267e1fbcc015c1726b422a6847e08c6be7e987e8b5ec1f7e85aa5095bb64736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {
"getAddress(string)": {
"params": {
"_name": "Name to retrieve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
},
"owner()": {
"details": "Returns the address of the current owner."
},
"renounceOwnership()": {
"details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
},
"setAddress(string,address)": {
"params": {
"_address": "Address to associate with the name.",
"_name": "String name to associate an address with."
}
},
"transferOwnership(address)": {
"details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
}
},
"title": "Lib_AddressManager",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getAddress(string)": {
"notice": "Retrieves the address associated with a given name."
},
"setAddress(string,address)": {
"notice": "Changes the address associated with a particular name."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 393,
"contract": "contracts/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 7017,
"contract": "contracts/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager",
"label": "addresses",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_bytes32,t_address)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_mapping(t_bytes32,t_address)": {
"encoding": "mapping",
"key": "t_bytes32",
"label": "mapping(bytes32 => address)",
"numberOfBytes": "32",
"value": "t_address"
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
},
{
"internalType": "string",
"name": "_implementationName",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"stateMutability": "payable",
"type": "fallback"
}
],
"transactionHash": "0xc547cd677c4bcb87deead498c827b1dfcfd5d14826f58a0f7416a46024a03e85",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294",
"transactionIndex": 13,
"gasUsed": "291461",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x3e18927a7be75d3ac2b6f54f8c40d781756e78327f9cedd8dff5e79dd49403ff",
"transactionHash": "0xc547cd677c4bcb87deead498c827b1dfcfd5d14826f58a0f7416a46024a03e85",
"logs": [],
"blockNumber": 7017129,
"cumulativeGasUsed": "1033610",
"status": 1,
"byzantium": true
},
"args": [
"0xa6f73589243a6A7a9023b1Fa0651b1d89c177111",
"OVM_L1CrossDomainMessenger"
],
"numDeployments": 1,
"solcInputHash": "76c096070f4b72a86045eb6ab63709ed",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_implementationName\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_implementationName\":\"implementationName of the contract to proxy to.\",\"_libAddressManager\":\"Address of the Lib_AddressManager.\"}}},\"title\":\"Lib_ResolvedDelegateProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":\"Lib_ResolvedDelegateProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_ResolvedDelegateProxy\\n */\\ncontract Lib_ResolvedDelegateProxy {\\n /*************\\n * Variables *\\n *************/\\n\\n // Using mappings to store fields to avoid overwriting storage slots in the\\n // implementation contract. For example, instead of storing these fields at\\n // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`.\\n // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html\\n // NOTE: Do not use this code in your own contract system.\\n // There is a known flaw in this contract, and we will remove it from the repository\\n // in the near future. Due to the very limited way that we are using it, this flaw is\\n // not an issue in our system.\\n mapping(address => string) private implementationName;\\n mapping(address => Lib_AddressManager) private addressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n * @param _implementationName implementationName of the contract to proxy to.\\n */\\n constructor(address _libAddressManager, string memory _implementationName) {\\n addressManager[address(this)] = Lib_AddressManager(_libAddressManager);\\n implementationName[address(this)] = _implementationName;\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback() external payable {\\n address target = addressManager[address(this)].getAddress(\\n (implementationName[address(this)])\\n );\\n\\n require(target != address(0), \\\"Target address must be initialized.\\\");\\n\\n // slither-disable-next-line controlled-delegatecall\\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\\n\\n if (success == true) {\\n assembly {\\n return(add(returndata, 0x20), mload(returndata))\\n }\\n } else {\\n assembly {\\n revert(add(returndata, 0x20), mload(returndata))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x987774d18365ed25f5be61198e8b241728db6f97c6f2496f4a35bf9dbe0bda2b\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b506040516105b53803806105b583398101604081905261002f91610125565b30600090815260016020908152604080832080546001600160a01b0319166001600160a01b038716179055828252909120825161006e92840190610076565b505050610252565b82805461008290610217565b90600052602060002090601f0160209004810192826100a457600085556100ea565b82601f106100bd57805160ff19168380011785556100ea565b828001600101855582156100ea579182015b828111156100ea5782518255916020019190600101906100cf565b506100f69291506100fa565b5090565b5b808211156100f657600081556001016100fb565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561013857600080fd5b82516001600160a01b038116811461014f57600080fd5b602084810151919350906001600160401b038082111561016e57600080fd5b818601915086601f83011261018257600080fd5b8151818111156101945761019461010f565b604051601f8201601f19908116603f011681019083821181831017156101bc576101bc61010f565b8160405282815289868487010111156101d457600080fd5b600093505b828410156101f657848401860151818501870152928501926101d9565b828411156102075760008684830101525b8096505050505050509250929050565b600181811c9082168061022b57607f821691505b6020821081141561024c57634e487b7160e01b600052602260045260246000fd5b50919050565b610354806102616000396000f3fe608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101f2565b60206040518083038186803b15801561008557600080fd5b505afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906102d1565b905073ffffffffffffffffffffffffffffffffffffffff8116610166576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5461726765742061646472657373206d75737420626520696e697469616c697a60448201527f65642e0000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1660003660405161019192919061030e565b600060405180830381855af49150503d80600081146101cc576040519150601f19603f3d011682016040523d82523d6000602084013e6101d1565b606091505b509092509050600182151514156101ea57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061021457607f831692505b85831081141561024b577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b8786018381526020018180156102685760018114610297576102c2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825287820196506102c2565b60008b81526020902060005b868110156102bc578154848201529085019089016102a3565b83019750505b50949998505050505050505050565b6000602082840312156102e357600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461030757600080fd5b9392505050565b818382376000910190815291905056fea2646970667358221220d66a7dad92a7f7528f41181719174e1d244423b8bb730d2884645c76cfa0944064736f6c63430008090033",
"deployedBytecode": "0x608060408181523060009081526001602090815282822054908290529181207fbf40fac1000000000000000000000000000000000000000000000000000000009093529173ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061006d9060846101f2565b60206040518083038186803b15801561008557600080fd5b505afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906102d1565b905073ffffffffffffffffffffffffffffffffffffffff8116610166576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f5461726765742061646472657373206d75737420626520696e697469616c697a60448201527f65642e0000000000000000000000000000000000000000000000000000000000606482015260840160405180910390fd5b6000808273ffffffffffffffffffffffffffffffffffffffff1660003660405161019192919061030e565b600060405180830381855af49150503d80600081146101cc576040519150601f19603f3d011682016040523d82523d6000602084013e6101d1565b606091505b509092509050600182151514156101ea57805160208201f35b805160208201fd5b600060208083526000845481600182811c91508083168061021457607f831692505b85831081141561024b577f4e487b710000000000000000000000000000000000000000000000000000000085526022600452602485fd5b8786018381526020018180156102685760018114610297576102c2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616825287820196506102c2565b60008b81526020902060005b868110156102bc578154848201529085019089016102a3565b83019750505b50949998505050505050505050565b6000602082840312156102e357600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461030757600080fd5b9392505050565b818382376000910190815291905056fea2646970667358221220d66a7dad92a7f7528f41181719174e1d244423b8bb730d2884645c76cfa0944064736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_implementationName": "implementationName of the contract to proxy to.",
"_libAddressManager": "Address of the Lib_AddressManager."
}
}
},
"title": "Lib_ResolvedDelegateProxy",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 7129,
"contract": "contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy",
"label": "implementationName",
"offset": 0,
"slot": "0",
"type": "t_mapping(t_address,t_string_storage)"
},
{
"astId": 7134,
"contract": "contracts/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy",
"label": "addressManager",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_address,t_contract(Lib_AddressManager)7084)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_contract(Lib_AddressManager)7084": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_contract(Lib_AddressManager)7084)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => contract Lib_AddressManager)",
"numberOfBytes": "32",
"value": "t_contract(Lib_AddressManager)7084"
},
"t_mapping(t_address,t_string_storage)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => string)",
"numberOfBytes": "32",
"value": "t_string_storage"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"stateMutability": "payable",
"type": "fallback"
},
{
"inputs": [],
"name": "getImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_code",
"type": "bytes"
}
],
"name": "setCode",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_key",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_value",
"type": "bytes32"
}
],
"name": "setStorage",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0xd57130025124776619229f980ae08c3097156ab127c897fa9ef17e29bf757a16",
"receipt": {
"to": null,
"from": "0x3a605B442055DF2898E18cF518feb2e2A6BD0D31",
"contractAddress": "0x636Af16bf2f682dD3109e60102b8E1A089FedAa8",
"transactionIndex": 8,
"gasUsed": "614417",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x85ce123b23be93051e83bc9d6dd2bf7817ee0fd338b936684c821020b8285393",
"transactionHash": "0xd57130025124776619229f980ae08c3097156ab127c897fa9ef17e29bf757a16",
"logs": [],
"blockNumber": 7017137,
"cumulativeGasUsed": "5543459",
"status": 1,
"byzantium": true
},
"args": [
"0x3a605B442055DF2898E18cF518feb2e2A6BD0D31"
],
"numDeployments": 1,
"solcInputHash": "0a41276e1e61949b5de1e4f1cd89fb6c",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"setCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"Address of the initial contract owner.\"}},\"getImplementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"getOwner()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"setCode(bytes)\":{\"params\":{\"_code\":\"New contract code to run inside this contract.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"New owner of the proxy contract.\"}},\"setStorage(bytes32,bytes32)\":{\"params\":{\"_key\":\"Storage key to modify.\",\"_value\":\"New value for the storage key.\"}}},\"title\":\"L1ChugSplashProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"getOwner()\":{\"notice\":\"Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"setCode(bytes)\":{\"notice\":\"Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner.\"},\"setOwner(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"setStorage(bytes32,bytes32)\":{\"notice\":\"Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":\"L1ChugSplashProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(address _owner) {\\n _setOwner(_owner);\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector)\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(ret == 0, \\\"L1ChugSplashProxy: system is currently being upgraded\\\");\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n // slither-disable-next-line incorrect-modifier\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n // slither-disable-next-line external-function\\n function setCode(bytes memory _code) public proxyCallIfNotOwner {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n // slither-disable-next-line external-function\\n function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n // slither-disable-next-line external-function\\n function setOwner(address _owner) public proxyCallIfNotOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n // slither-disable-next-line external-function\\n function getOwner() public proxyCallIfNotOwner returns (address) {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n // slither-disable-next-line external-function\\n function getImplementation() public proxyCallIfNotOwner returns (address) {\\n return _getImplementation();\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(address _owner) internal {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal onlyWhenNotPaused {\\n address implementation = _getImplementation();\\n\\n require(implementation != address(0), \\\"L1ChugSplashProxy: implementation is not set yet\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3cb52dfdc2706992572dd5621ae89ba919fd20539b73488a455d564f16f1b8d\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading() external view returns (bool);\\n}\\n\",\"keccak256\":\"0x9a496d99f111c1091f0c33d6bfc7802a522baa7235614b0014f35e4bbe280e57\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50604051610a5d380380610a5d83398101604081905261002f9161005d565b610057817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b5061008d565b60006020828403121561006f57600080fd5b81516001600160a01b038116811461008657600080fd5b9392505050565b6109c18061009c6000396000f3fe60806040526004361061005a5760003560e01c8063893d20e811610043578063893d20e8146100a45780639b0b0fda146100e2578063aaf10f42146101025761005a565b806313af4035146100645780636c5d4ad014610084575b610062610117565b005b34801561007057600080fd5b5061006261007f366004610792565b6103ba565b34801561009057600080fd5b5061006261009f3660046107fe565b61044b565b3480156100b057600080fd5b506100b9610601565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee57600080fd5b506100626100fd3660046108cd565b610698565b34801561010e57600080fd5b506100b9610706565b60006101417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101c3919061092a565b600060405180830381855afa9150503d80600081146101fe576040519150601f19603f3d011682016040523d82523d6000602084013e610203565b606091505b5091509150818015610216575080516020145b156102c8576000818060200190518101906102319190610936565b905080156102c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006102f27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102bd565b3660008037600080366000845af43d6000803e806103b4573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610413575033155b1561044357610440817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610440610117565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104a4575033155b156104435760006104d37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f8251602084012014156104e8575050565b60405160009061051e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161094f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f7965642e0000000000000000000000000060648201526084016102bd565b6105fb817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061062b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610662575033155b1561068d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610695610117565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806106f1575033155b156106fa579055565b610702610117565b5050565b60006107307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610767575033155b1561068d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107a457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107c857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561081057600080fd5b813567ffffffffffffffff8082111561082857600080fd5b818401915084601f83011261083c57600080fd5b81358181111561084e5761084e6107cf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610894576108946107cf565b816040528281528760208487010111156108ad57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108e057600080fd5b50508035926020909101359150565b6000815160005b8181101561091057602081850181015186830152016108f6565b8181111561091f576000828601525b509290920192915050565b60006107c882846108ef565b60006020828403121561094857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610983600d8301846108ef565b94935050505056fea2646970667358221220aea34fd8cdcf3a9cced029d5f7b1e628f42ad1514501878e0040df2afddb6e7164736f6c63430008090033",
"deployedBytecode": "0x60806040526004361061005a5760003560e01c8063893d20e811610043578063893d20e8146100a45780639b0b0fda146100e2578063aaf10f42146101025761005a565b806313af4035146100645780636c5d4ad014610084575b610062610117565b005b34801561007057600080fd5b5061006261007f366004610792565b6103ba565b34801561009057600080fd5b5061006261009f3660046107fe565b61044b565b3480156100b057600080fd5b506100b9610601565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100ee57600080fd5b506100626100fd3660046108cd565b610698565b34801561010e57600080fd5b506100b9610706565b60006101417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fb7947262000000000000000000000000000000000000000000000000000000001790529051919250600091829173ffffffffffffffffffffffffffffffffffffffff8516916101c3919061092a565b600060405180830381855afa9150503d80600081146101fe576040519150601f19603f3d011682016040523d82523d6000602084013e610203565b606091505b5091509150818015610216575080516020145b156102c8576000818060200190518101906102319190610936565b905080156102c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c314368756753706c61736850726f78793a2073797374656d2069732063757260448201527f72656e746c79206265696e67207570677261646564000000000000000000000060648201526084015b60405180910390fd5b505b60006102f27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4c314368756753706c61736850726f78793a20696d706c656d656e746174696f60448201527f6e206973206e6f7420736574207965740000000000000000000000000000000060648201526084016102bd565b3660008037600080366000845af43d6000803e806103b4573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610413575033155b1561044357610440817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b50565b610440610117565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104a4575033155b156104435760006104d37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b9050803f8251602084012014156104e8575050565b60405160009061051e907f600d380380600d6000396000f30000000000000000000000000000000000000090859060200161094f565b604051602081830303815290604052905060008151602083016000f084516020860120909150813f146105d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f4c314368756753706c61736850726f78793a20636f646520776173206e6f742060448201527f636f72726563746c79206465706c6f7965642e0000000000000000000000000060648201526084016102bd565b6105fb817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50505050565b600061062b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610662575033155b1561068d57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b610695610117565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806106f1575033155b156106fa579055565b610702610117565b5050565b60006107307fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610767575033155b1561068d57507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6000602082840312156107a457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146107c857600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561081057600080fd5b813567ffffffffffffffff8082111561082857600080fd5b818401915084601f83011261083c57600080fd5b81358181111561084e5761084e6107cf565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610894576108946107cf565b816040528281528760208487010111156108ad57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600080604083850312156108e057600080fd5b50508035926020909101359150565b6000815160005b8181101561091057602081850181015186830152016108f6565b8181111561091f576000828601525b509290920192915050565b60006107c882846108ef565b60006020828403121561094857600080fd5b5051919050565b7fffffffffffffffffffffffffff00000000000000000000000000000000000000831681526000610983600d8301846108ef565b94935050505056fea2646970667358221220aea34fd8cdcf3a9cced029d5f7b1e628f42ad1514501878e0040df2afddb6e7164736f6c63430008090033",
"devdoc": {
"details": "Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_owner": "Address of the initial contract owner."
}
},
"getImplementation()": {
"returns": {
"_0": "Implementation address."
}
},
"getOwner()": {
"returns": {
"_0": "Owner address."
}
},
"setCode(bytes)": {
"params": {
"_code": "New contract code to run inside this contract."
}
},
"setOwner(address)": {
"params": {
"_owner": "New owner of the proxy contract."
}
},
"setStorage(bytes32,bytes32)": {
"params": {
"_key": "Storage key to modify.",
"_value": "New value for the storage key."
}
}
},
"title": "L1ChugSplashProxy",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getImplementation()": {
"notice": "Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)."
},
"getOwner()": {
"notice": "Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)."
},
"setCode(bytes)": {
"notice": "Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner."
},
"setOwner(address)": {
"notice": "Changes the owner of the proxy contract. Only callable by the owner."
},
"setStorage(bytes32,bytes32)": {
"notice": "Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner."
}
},
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x7a74f7934a233e10E8757264132B2E4EbccF5098",
"abi": [
{
"inputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "_manager",
"type": "address"
},
{
"internalType": "address",
"name": "_finalOwner",
"type": "address"
},
{
"internalType": "string[]",
"name": "_names",
"type": "string[]"
},
{
"internalType": "address[]",
"name": "_addresses",
"type": "address[]"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "finalOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getNamedAddresses",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "address",
"name": "addr",
"type": "address"
}
],
"internalType": "struct AddressDictator.NamedAddress[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "manager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "returnOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "setAddresses",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0xedbb6b8ddf9576d12f37434b146b889ba2874f2683f887f4db7e50b780ab11dc",
"receipt": {
"to": null,
"from": "0x0bb2cA5Ea700ba04c713008E1a3D198B4e8dA7a7",
"contractAddress": "0x7a74f7934a233e10E8757264132B2E4EbccF5098",
"transactionIndex": 12,
"gasUsed": "989432",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x59ae23de1dc7d96c0c6fcd028afc195d3f6ae7d87b86527478dbcfd805e9167e",
"transactionHash": "0xedbb6b8ddf9576d12f37434b146b889ba2874f2683f887f4db7e50b780ab11dc",
"logs": [],
"blockNumber": 13596598,
"cumulativeGasUsed": "2032231",
"status": 1,
"byzantium": true
},
"args": [
"0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A",
[
"ChainStorageContainer-CTC-batches",
"ChainStorageContainer-SCC-batches",
"CanonicalTransactionChain",
"StateCommitmentChain",
"BondManager",
"OVM_L1CrossDomainMessenger",
"L2CrossDomainMessenger"
],
[
"0xD16463EF9b0338CE3D73309028ef1714D220c024",
"0xb0ddFf09c4019e31960de11bD845E836078E8EbE",
"0x5E4e65926BA27467555EB562121fac00D24E9dD2",
"0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19",
"0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1",
"0xd9166833FF12A5F900ccfBf2c8B62a90F1Ca1FD5",
"0x4200000000000000000000000000000000000007"
]
],
"solcInputHash": "8a22f2b322f61ab13865f2d2a82e5f09",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"_manager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_finalOwner\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_names\",\"type\":\"string[]\"},{\"internalType\":\"address[]\",\"name\":\"_addresses\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"finalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNamedAddresses\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"internalType\":\"struct AddressDictator.NamedAddress[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"returnOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setAddresses\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate many different addresses in the AddressManager without transferring ownership of the AddressManager to a hot wallet or hardware wallet.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_addresses\":\"Array of addresses to associate with the name.\",\"_finalOwner\":\"Address to transfer AddressManager ownership to afterwards.\",\"_manager\":\"Address of the AddressManager contract.\",\"_names\":\"Array of names to associate an address with.\"}}},\"title\":\"AddressDictator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getNamedAddresses()\":{\"notice\":\"Returns the full namedAddresses array.\"},\"returnOwnership()\":{\"notice\":\"Transfers ownership of this contract to the finalOwner. Only callable by the Final Owner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong.\"},\"setAddresses()\":{\"notice\":\"Called to finalize the transfer, this function is callable by anyone, but will only result in an upgrade if this contract is the owner Address Manager.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/deployment/AddressDictator.sol\":\"AddressDictator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/deployment/AddressDictator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Lib_AddressManager } from \\\"../../libraries/resolver/Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title AddressDictator\\n * @dev The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate\\n * many different addresses in the AddressManager without transferring ownership of the\\n * AddressManager to a hot wallet or hardware wallet.\\n */\\ncontract AddressDictator {\\n /*********\\n * Types *\\n *********/\\n\\n struct NamedAddress {\\n string name;\\n address addr;\\n }\\n\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public manager;\\n address public finalOwner;\\n NamedAddress[] namedAddresses;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _manager Address of the AddressManager contract.\\n * @param _finalOwner Address to transfer AddressManager ownership to afterwards.\\n * @param _names Array of names to associate an address with.\\n * @param _addresses Array of addresses to associate with the name.\\n */\\n constructor(\\n Lib_AddressManager _manager,\\n address _finalOwner,\\n string[] memory _names,\\n address[] memory _addresses\\n ) {\\n manager = _manager;\\n finalOwner = _finalOwner;\\n require(\\n _names.length == _addresses.length,\\n \\\"AddressDictator: Must provide an equal number of names and addresses.\\\"\\n );\\n for (uint256 i = 0; i < _names.length; i++) {\\n namedAddresses.push(NamedAddress({ name: _names[i], addr: _addresses[i] }));\\n }\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Called to finalize the transfer, this function is callable by anyone, but will only result in\\n * an upgrade if this contract is the owner Address Manager.\\n */\\n function setAddresses() external {\\n for (uint256 i = 0; i < namedAddresses.length; i++) {\\n manager.setAddress(namedAddresses[i].name, namedAddresses[i].addr);\\n }\\n // note that this will revert if _finalOwner == currentOwner\\n manager.transferOwnership(finalOwner);\\n }\\n\\n /**\\n * Transfers ownership of this contract to the finalOwner.\\n * Only callable by the Final Owner, which is intended to be our multisig.\\n * This function shouldn't be necessary, but it gives a sense of reassurance that we can recover\\n * if something really surprising goes wrong.\\n */\\n function returnOwnership() external {\\n require(msg.sender == finalOwner, \\\"AddressDictator: only callable by finalOwner\\\");\\n manager.transferOwnership(finalOwner);\\n }\\n\\n /******************\\n * View Functions *\\n ******************/\\n\\n /**\\n * Returns the full namedAddresses array.\\n */\\n function getNamedAddresses() external view returns (NamedAddress[] memory) {\\n return namedAddresses;\\n }\\n}\\n\",\"keccak256\":\"0xd7257dc5d6c5855f57dc6c42f430f3c7bd4514a26756bac4183c65c77fd7cb70\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b5060405162000d5e38038062000d5e83398101604081905262000034916200037a565b600080546001600160a01b038087166001600160a01b03199283161790925560018054928616929091169190911790558051825114620000ee5760405162461bcd60e51b815260206004820152604560248201527f416464726573734469637461746f723a204d7573742070726f7669646520616e60448201527f20657175616c206e756d626572206f66206e616d657320616e6420616464726560648201526439b9b2b99760d91b608482015260a40160405180910390fd5b60005b8251811015620001c357600260405180604001604052808584815181106200011d576200011d62000505565b602002602001015181526020018484815181106200013f576200013f62000505565b6020908102919091018101516001600160a01b0316909152825460018101845560009384529281902082518051939460020290910192620001849284920190620001ce565b5060209190910151600190910180546001600160a01b0319166001600160a01b0390921691909117905580620001ba816200051b565b915050620000f1565b505050505062000582565b828054620001dc9062000545565b90600052602060002090601f0160209004810192826200020057600085556200024b565b82601f106200021b57805160ff19168380011785556200024b565b828001600101855582156200024b579182015b828111156200024b5782518255916020019190600101906200022e565b50620002599291506200025d565b5090565b5b808211156200025957600081556001016200025e565b6001600160a01b03811681146200028a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620002ce57620002ce6200028d565b604052919050565b60006001600160401b03821115620002f257620002f26200028d565b5060051b60200190565b600082601f8301126200030e57600080fd5b81516020620003276200032183620002d6565b620002a3565b82815260059290921b840181019181810190868411156200034757600080fd5b8286015b848110156200036f578051620003618162000274565b83529183019183016200034b565b509695505050505050565b600080600080608085870312156200039157600080fd5b84516200039e8162000274565b80945050602080860151620003b38162000274565b60408701519094506001600160401b0380821115620003d157600080fd5b818801915088601f830112620003e657600080fd5b8151620003f76200032182620002d6565b81815260059190911b8301840190848101908b8311156200041757600080fd5b8585015b83811015620004ce57805185811115620004355760008081fd5b8601603f81018e13620004485760008081fd5b87810151868111156200045f576200045f6200028d565b62000473601f8201601f19168a01620002a3565b8181528f60408385010111156200048a5760008081fd5b60005b82811015620004ab57838101604001518282018c01528a016200048d565b82811115620004bd5760008b84840101525b50855250509186019186016200041b565b5060608b01519097509450505080831115620004e957600080fd5b5050620004f987828801620002fc565b91505092959194509250565b634e487b7160e01b600052603260045260246000fd5b60006000198214156200053e57634e487b7160e01b600052601160045260246000fd5b5060010190565b600181811c908216806200055a57607f821691505b602082108114156200057c57634e487b7160e01b600052602260045260246000fd5b50919050565b6107cc80620005926000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80633ccad6fc116100505780633ccad6fc146100c0578063481c6a75146100d5578063bc3a429b146100f557600080fd5b806317ad94ec1461006c578063297d1a34146100b6575b600080fd5b60015461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100be6100fd565b005b6100c8610232565b6040516100ad91906104af565b60005461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100be610343565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f416464726573734469637461746f723a206f6e6c792063616c6c61626c65206260448201527f792066696e616c4f776e65720000000000000000000000000000000000000000606482015260840160405180910390fd5b6000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024015b600060405180830381600087803b15801561021857600080fd5b505af115801561022c573d6000803e3d6000fd5b50505050565b60606002805480602002602001604051908101604052809291908181526020016000905b8282101561033a5783829060005260206000209060020201604051806040016040529081600082018054610289906105ae565b80601f01602080910402602001604051908101604052809291908181526020018280546102b5906105ae565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b505050918352505060019182015473ffffffffffffffffffffffffffffffffffffffff16602091820152918352929092019101610256565b50505050905090565b60005b600254811015610454576000546002805473ffffffffffffffffffffffffffffffffffffffff90921691639b2ea4bd91908490811061038757610387610602565b9060005260206000209060020201600001600284815481106103ab576103ab610602565b60009182526020909120600160029092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815261040f929173ffffffffffffffffffffffffffffffffffffffff1690600401610631565b600060405180830381600087803b15801561042957600080fd5b505af115801561043d573d6000803e3d6000fd5b50505050808061044c90610736565b915050610346565b506000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024016101fe565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561059f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a8503018652825180518886528051808a880152845b81811015610532578281018c0151888201606001528b01610516565b8181111561054357856060838a0101525b50918a015173ffffffffffffffffffffffffffffffffffffffff16868b01525095880195601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690930160600192918701916001016104d7565b50919998505050505050505050565b600181811c908216806105c257607f821691505b602082108114156105fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60408152600080845481600182811c91508083168061065157607f831692505b602080841082141561068a577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b60408801849052606088018280156106a957600181146106d857610703565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00871682528282019750610703565b60008c81526020902060005b878110156106fd578154848201529086019084016106e4565b83019850505b50508596506107298189018a73ffffffffffffffffffffffffffffffffffffffff169052565b5050505050509392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561078f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220887af7eba4d3f3d6334054ac570c07f1274d85013ffd1137e64c17b5cc13380864736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633ccad6fc116100505780633ccad6fc146100c0578063481c6a75146100d5578063bc3a429b146100f557600080fd5b806317ad94ec1461006c578063297d1a34146100b6575b600080fd5b60015461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100be6100fd565b005b6100c8610232565b6040516100ad91906104af565b60005461008c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100be610343565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f416464726573734469637461746f723a206f6e6c792063616c6c61626c65206260448201527f792066696e616c4f776e65720000000000000000000000000000000000000000606482015260840160405180910390fd5b6000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024015b600060405180830381600087803b15801561021857600080fd5b505af115801561022c573d6000803e3d6000fd5b50505050565b60606002805480602002602001604051908101604052809291908181526020016000905b8282101561033a5783829060005260206000209060020201604051806040016040529081600082018054610289906105ae565b80601f01602080910402602001604051908101604052809291908181526020018280546102b5906105ae565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b505050918352505060019182015473ffffffffffffffffffffffffffffffffffffffff16602091820152918352929092019101610256565b50505050905090565b60005b600254811015610454576000546002805473ffffffffffffffffffffffffffffffffffffffff90921691639b2ea4bd91908490811061038757610387610602565b9060005260206000209060020201600001600284815481106103ab576103ab610602565b60009182526020909120600160029092020101546040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815261040f929173ffffffffffffffffffffffffffffffffffffffff1690600401610631565b600060405180830381600087803b15801561042957600080fd5b505af115801561043d573d6000803e3d6000fd5b50505050808061044c90610736565b915050610346565b506000546001546040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015291169063f2fde38b906024016101fe565b60006020808301818452808551808352604092508286019150828160051b8701018488016000805b8481101561059f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a8503018652825180518886528051808a880152845b81811015610532578281018c0151888201606001528b01610516565b8181111561054357856060838a0101525b50918a015173ffffffffffffffffffffffffffffffffffffffff16868b01525095880195601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690930160600192918701916001016104d7565b50919998505050505050505050565b600181811c908216806105c257607f821691505b602082108114156105fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60408152600080845481600182811c91508083168061065157607f831692505b602080841082141561068a577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b60408801849052606088018280156106a957600181146106d857610703565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00871682528282019750610703565b60008c81526020902060005b878110156106fd578154848201529086019084016106e4565b83019850505b50508596506107298189018a73ffffffffffffffffffffffffffffffffffffffff169052565b5050505050509392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561078f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220887af7eba4d3f3d6334054ac570c07f1274d85013ffd1137e64c17b5cc13380864736f6c63430008090033",
"devdoc": {
"details": "The AddressDictator (glory to Arstotzka) is a contract that allows us to safely manipulate many different addresses in the AddressManager without transferring ownership of the AddressManager to a hot wallet or hardware wallet.",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_addresses": "Array of addresses to associate with the name.",
"_finalOwner": "Address to transfer AddressManager ownership to afterwards.",
"_manager": "Address of the AddressManager contract.",
"_names": "Array of names to associate an address with."
}
}
},
"title": "AddressDictator",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getNamedAddresses()": {
"notice": "Returns the full namedAddresses array."
},
"returnOwnership()": {
"notice": "Transfers ownership of this contract to the finalOwner. Only callable by the Final Owner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong."
},
"setAddresses()": {
"notice": "Called to finalize the transfer, this function is callable by anyone, but will only result in an upgrade if this contract is the owner Address Manager."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 1908,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "manager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)6645"
},
{
"astId": 1910,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "finalOwner",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 1914,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "namedAddresses",
"offset": 0,
"slot": "2",
"type": "t_array(t_struct(NamedAddress)1905_storage)dyn_storage"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_struct(NamedAddress)1905_storage)dyn_storage": {
"base": "t_struct(NamedAddress)1905_storage",
"encoding": "dynamic_array",
"label": "struct AddressDictator.NamedAddress[]",
"numberOfBytes": "32"
},
"t_contract(Lib_AddressManager)6645": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
"t_struct(NamedAddress)1905_storage": {
"encoding": "inplace",
"label": "struct AddressDictator.NamedAddress",
"members": [
{
"astId": 1902,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "name",
"offset": 0,
"slot": "0",
"type": "t_string_storage"
},
{
"astId": 1904,
"contract": "contracts/L1/deployment/AddressDictator.sol:AddressDictator",
"label": "addr",
"offset": 0,
"slot": "1",
"type": "t_address"
}
],
"numberOfBytes": "64"
}
}
}
}
\ No newline at end of file
{
"address": "0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "_who",
"type": "address"
}
],
"name": "isCollateralized",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "libAddressManager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x75f8426b4aa3d4c56f1eff06a05f17248d48201cb98b52400e60bc9630d1a0f5",
"receipt": {
"to": null,
"from": "0x0bb2cA5Ea700ba04c713008E1a3D198B4e8dA7a7",
"contractAddress": "0xcd626E1328b41fCF24737F137BcD4CE0c32bc8d1",
"transactionIndex": 8,
"gasUsed": "295562",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xce2935bccd22ce502fdaccdb5afdc68dd30c50301d11d8f63c8000a74391d743",
"transactionHash": "0x75f8426b4aa3d4c56f1eff06a05f17248d48201cb98b52400e60bc9630d1a0f5",
"logs": [],
"blockNumber": 13596479,
"cumulativeGasUsed": "899083",
"status": 1,
"byzantium": true
},
"args": [
"0xdE1FCfB0851916CA5101820A69b13a4E276bd81F"
],
"solcInputHash": "e2f1121f17d06f85851dd0c837a00344",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_who\",\"type\":\"address\"}],\"name\":\"isCollateralized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"libAddressManager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract is, for now, a stub of the \\\"real\\\" BondManager that does nothing but allow the \\\"OVM_Proposer\\\" to submit state root batches. Runtime target: EVM\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\"}},\"isCollateralized(address)\":{\"params\":{\"_who\":\"Address to check.\"},\"returns\":{\"_0\":\"true if the address is properly collateralized, false otherwise.\"}},\"resolve(string)\":{\"params\":{\"_name\":\"Name to resolve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}}},\"title\":\"BondManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"isCollateralized(address)\":{\"notice\":\"Checks whether a given address is properly collateralized and can perform actions within the system.\"},\"resolve(string)\":{\"notice\":\"Resolves the address associated with a given name.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/verification/BondManager.sol\":\"BondManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/verification/BondManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Interface Imports */\\nimport { IBondManager } from \\\"./IBondManager.sol\\\";\\n\\n/* Contract Imports */\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\n\\n/**\\n * @title BondManager\\n * @dev This contract is, for now, a stub of the \\\"real\\\" BondManager that does nothing but\\n * allow the \\\"OVM_Proposer\\\" to submit state root batches.\\n *\\n * Runtime target: EVM\\n */\\ncontract BondManager is IBondManager, Lib_AddressResolver {\\n /**\\n * @param _libAddressManager Address of the Address Manager.\\n */\\n constructor(address _libAddressManager) Lib_AddressResolver(_libAddressManager) {}\\n\\n /**\\n * Checks whether a given address is properly collateralized and can perform actions within\\n * the system.\\n * @param _who Address to check.\\n * @return true if the address is properly collateralized, false otherwise.\\n */\\n function isCollateralized(address _who) public view returns (bool) {\\n // Only authenticate sequencer to submit state root batches.\\n return _who == resolve(\\\"OVM_Proposer\\\");\\n }\\n}\\n\",\"keccak256\":\"0x7cf12771514dac1a73702395b9642dacd7190bd7a5d131fb87c0c368236d1ed0\",\"license\":\"MIT\"},\"contracts/L1/verification/IBondManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title IBondManager\\n */\\ninterface IBondManager {\\n /********************\\n * Public Functions *\\n ********************/\\n\\n function isCollateralized(address _who) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x4ae2dc7bf175626d2930299e73d50a7ba936171d07810497ef71fa38a4e246a7\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\nabstract contract Lib_AddressResolver {\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public libAddressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n */\\n constructor(address _libAddressManager) {\\n libAddressManager = Lib_AddressManager(_libAddressManager);\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Resolves the address associated with a given name.\\n * @param _name Name to resolve an address for.\\n * @return Address associated with the given name.\\n */\\n function resolve(string memory _name) public view returns (address) {\\n return libAddressManager.getAddress(_name);\\n }\\n}\\n\",\"keccak256\":\"0x515c4db671a28e2fe180201f6d11c0208c05f582ca3489fb6b8e81c27659bc62\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5060405161048838038061048883398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6103f5806100936000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806302ad4d2a14610046578063299ca4781461006e578063461a4478146100b3575b600080fd5b61005961005436600461020d565b6100c6565b60405190151581526020015b60405180910390f35b60005461008e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610065565b61008e6100c1366004610260565b61013b565b60006101066040518060400160405280600c81526020017f4f564d5f50726f706f736572000000000000000000000000000000000000000081525061013b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061019290859060040161032f565b60206040518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906103a2565b92915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461020a57600080fd5b50565b60006020828403121561021f57600080fd5b813561022a816101e8565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561027257600080fd5b813567ffffffffffffffff8082111561028a57600080fd5b818401915084601f83011261029e57600080fd5b8135818111156102b0576102b0610231565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156102f6576102f6610231565b8160405282815287602084870101111561030f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b8181101561035c57858101830151858201604001528201610340565b8181111561036e576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156103b457600080fd5b815161022a816101e856fea2646970667358221220cdeb219ac692b599b8857e4140f0cfd6d348cfe93163faebdf5a55b11f0009ea64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806302ad4d2a14610046578063299ca4781461006e578063461a4478146100b3575b600080fd5b61005961005436600461020d565b6100c6565b60405190151581526020015b60405180910390f35b60005461008e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610065565b61008e6100c1366004610260565b61013b565b60006101066040518060400160405280600c81526020017f4f564d5f50726f706f736572000000000000000000000000000000000000000081525061013b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061019290859060040161032f565b60206040518083038186803b1580156101aa57600080fd5b505afa1580156101be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e291906103a2565b92915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461020a57600080fd5b50565b60006020828403121561021f57600080fd5b813561022a816101e8565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561027257600080fd5b813567ffffffffffffffff8082111561028a57600080fd5b818401915084601f83011261029e57600080fd5b8135818111156102b0576102b0610231565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156102f6576102f6610231565b8160405282815287602084870101111561030f57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b8181101561035c57858101830151858201604001528201610340565b8181111561036e576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000602082840312156103b457600080fd5b815161022a816101e856fea2646970667358221220cdeb219ac692b599b8857e4140f0cfd6d348cfe93163faebdf5a55b11f0009ea64736f6c63430008090033",
"devdoc": {
"details": "This contract is, for now, a stub of the \"real\" BondManager that does nothing but allow the \"OVM_Proposer\" to submit state root batches. Runtime target: EVM",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_libAddressManager": "Address of the Address Manager."
}
},
"isCollateralized(address)": {
"params": {
"_who": "Address to check."
},
"returns": {
"_0": "true if the address is properly collateralized, false otherwise."
}
},
"resolve(string)": {
"params": {
"_name": "Name to resolve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
}
},
"title": "BondManager",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"isCollateralized(address)": {
"notice": "Checks whether a given address is properly collateralized and can perform actions within the system."
},
"resolve(string)": {
"notice": "Resolves the address associated with a given name."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 6653,
"contract": "contracts/L1/verification/BondManager.sol:BondManager",
"label": "libAddressManager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)6645"
}
],
"types": {
"t_contract(Lib_AddressManager)6645": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0xD16463EF9b0338CE3D73309028ef1714D220c024",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
},
{
"internalType": "string",
"name": "_owner",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "get",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getGlobalMetadata",
"outputs": [
{
"internalType": "bytes27",
"name": "",
"type": "bytes27"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "length",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "libAddressManager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "setGlobalMetadata",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x42e7bc9094a85d8ca8d9029d807f8c8c272c389c54e628c5d0150f1b4f0ffd4e",
"receipt": {
"to": null,
"from": "0x0bb2cA5Ea700ba04c713008E1a3D198B4e8dA7a7",
"contractAddress": "0xD16463EF9b0338CE3D73309028ef1714D220c024",
"transactionIndex": 20,
"gasUsed": "946990",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xdffd74b8ecb09c1ae45b4aeacf97b6e11f8b33fa368ff7fb35d5dbae8d18426a",
"transactionHash": "0x42e7bc9094a85d8ca8d9029d807f8c8c272c389c54e628c5d0150f1b4f0ffd4e",
"logs": [],
"blockNumber": 13596451,
"cumulativeGasUsed": "2732660",
"status": 1,
"byzantium": true
},
"args": [
"0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"CanonicalTransactionChain"
],
"solcInputHash": "8a22f2b322f61ab13865f2d2a82e5f09",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_owner\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"get\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGlobalMetadata\",\"outputs\":[{\"internalType\":\"bytes27\",\"name\":\"\",\"type\":\"bytes27\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"length\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"libAddressManager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"setGlobalMetadata\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain Runtime target: EVM\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\",\"_owner\":\"Name of the contract that owns this container (will be resolved later).\"}},\"deleteElementsAfterInclusive(uint256)\":{\"params\":{\"_index\":\"Object index to delete from.\"}},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_index\":\"Object index to delete from.\"}},\"get(uint256)\":{\"params\":{\"_index\":\"Index of the particular object to access.\"},\"returns\":{\"_0\":\"32 byte object value.\"}},\"getGlobalMetadata()\":{\"returns\":{\"_0\":\"Container global metadata field.\"}},\"length()\":{\"returns\":{\"_0\":\"Number of objects in the container.\"}},\"push(bytes32)\":{\"params\":{\"_object\":\"A 32 byte value to insert into the container.\"}},\"push(bytes32,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_object\":\"A 32 byte value to insert into the container.\"}},\"resolve(string)\":{\"params\":{\"_name\":\"Name to resolve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"setGlobalMetadata(bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata to set.\"}}},\"title\":\"ChainStorageContainer\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"deleteElementsAfterInclusive(uint256)\":{\"notice\":\"Removes all objects after and including a given index.\"},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"notice\":\"Removes all objects after and including a given index. Also allows setting the global metadata field.\"},\"get(uint256)\":{\"notice\":\"Retrieves an object from the container.\"},\"getGlobalMetadata()\":{\"notice\":\"Retrieves the container's global metadata field.\"},\"length()\":{\"notice\":\"Retrieves the number of objects stored in the container.\"},\"push(bytes32)\":{\"notice\":\"Pushes an object into the container.\"},\"push(bytes32,bytes27)\":{\"notice\":\"Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global metadata (it's an optimization).\"},\"resolve(string)\":{\"notice\":\"Resolves the address associated with a given name.\"},\"setGlobalMetadata(bytes27)\":{\"notice\":\"Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/rollup/ChainStorageContainer.sol\":\"ChainStorageContainer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/rollup/ChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_Buffer } from \\\"../../libraries/utils/Lib_Buffer.sol\\\";\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\n\\n/* Interface Imports */\\nimport { IChainStorageContainer } from \\\"./IChainStorageContainer.sol\\\";\\n\\n/**\\n * @title ChainStorageContainer\\n * @dev The Chain Storage Container provides its owner contract with read, write and delete\\n * functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which\\n * can no longer be used in a fraud proof due to the fraud window having passed, and the associated\\n * chain state or transactions being finalized.\\n * Three distinct Chain Storage Containers will be deployed on Layer 1:\\n * 1. Stores transaction batches for the Canonical Transaction Chain\\n * 2. Stores queued transactions for the Canonical Transaction Chain\\n * 3. Stores chain state batches for the State Commitment Chain\\n *\\n * Runtime target: EVM\\n */\\ncontract ChainStorageContainer is IChainStorageContainer, Lib_AddressResolver {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Lib_Buffer.Buffer;\\n\\n /*************\\n * Variables *\\n *************/\\n\\n string public owner;\\n Lib_Buffer.Buffer internal buffer;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Address Manager.\\n * @param _owner Name of the contract that owns this container (will be resolved later).\\n */\\n constructor(address _libAddressManager, string memory _owner)\\n Lib_AddressResolver(_libAddressManager)\\n {\\n owner = _owner;\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n modifier onlyOwner() {\\n require(\\n msg.sender == resolve(owner),\\n \\\"ChainStorageContainer: Function can only be called by the owner.\\\"\\n );\\n _;\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function setGlobalMetadata(bytes27 _globalMetadata) public onlyOwner {\\n return buffer.setExtraData(_globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function getGlobalMetadata() public view returns (bytes27) {\\n return buffer.getExtraData();\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function length() public view returns (uint256) {\\n return uint256(buffer.getLength());\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function push(bytes32 _object) public onlyOwner {\\n buffer.push(_object);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function push(bytes32 _object, bytes27 _globalMetadata) public onlyOwner {\\n buffer.push(_object, _globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function get(uint256 _index) public view returns (bytes32) {\\n return buffer.get(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function deleteElementsAfterInclusive(uint256 _index) public onlyOwner {\\n buffer.deleteElementsAfterInclusive(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata)\\n public\\n onlyOwner\\n {\\n buffer.deleteElementsAfterInclusive(uint40(_index), _globalMetadata);\\n }\\n}\\n\",\"keccak256\":\"0x4364f98f8f4f615cd4043ca64014c4b6c434a575a5709e8e5f35fd53df7370c2\",\"license\":\"MIT\"},\"contracts/L1/rollup/IChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title IChainStorageContainer\\n */\\ninterface IChainStorageContainer {\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the container's global metadata field. We're using `bytes27` here because we use five\\n * bytes to maintain the length of the underlying data structure, meaning we have an extra\\n * 27 bytes to store arbitrary data.\\n * @param _globalMetadata New global metadata to set.\\n */\\n function setGlobalMetadata(bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves the container's global metadata field.\\n * @return Container global metadata field.\\n */\\n function getGlobalMetadata() external view returns (bytes27);\\n\\n /**\\n * Retrieves the number of objects stored in the container.\\n * @return Number of objects in the container.\\n */\\n function length() external view returns (uint256);\\n\\n /**\\n * Pushes an object into the container.\\n * @param _object A 32 byte value to insert into the container.\\n */\\n function push(bytes32 _object) external;\\n\\n /**\\n * Pushes an object into the container. Function allows setting the global metadata since\\n * we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global\\n * metadata (it's an optimization).\\n * @param _object A 32 byte value to insert into the container.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function push(bytes32 _object, bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves an object from the container.\\n * @param _index Index of the particular object to access.\\n * @return 32 byte object value.\\n */\\n function get(uint256 _index) external view returns (bytes32);\\n\\n /**\\n * Removes all objects after and including a given index.\\n * @param _index Object index to delete from.\\n */\\n function deleteElementsAfterInclusive(uint256 _index) external;\\n\\n /**\\n * Removes all objects after and including a given index. Also allows setting the global\\n * metadata field.\\n * @param _index Object index to delete from.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external;\\n}\\n\",\"keccak256\":\"0xe55ad72572ec47dc09a02228d0c5a438571c76a41d16d92b35add057811977ce\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\nabstract contract Lib_AddressResolver {\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public libAddressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n */\\n constructor(address _libAddressManager) {\\n libAddressManager = Lib_AddressManager(_libAddressManager);\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Resolves the address associated with a given name.\\n * @param _name Name to resolve an address for.\\n * @return Address associated with the given name.\\n */\\n function resolve(string memory _name) public view returns (address) {\\n return libAddressManager.getAddress(_name);\\n }\\n}\\n\",\"keccak256\":\"0x515c4db671a28e2fe180201f6d11c0208c05f582ca3489fb6b8e81c27659bc62\",\"license\":\"MIT\"},\"contracts/libraries/utils/Lib_Buffer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Lib_Buffer\\n * @dev This library implements a bytes32 storage array with some additional gas-optimized\\n * functionality. In particular, it encodes its length as a uint40, and tightly packs this with an\\n * overwritable \\\"extra data\\\" field so we can store more information with a single SSTORE.\\n */\\nlibrary Lib_Buffer {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Buffer;\\n\\n /***********\\n * Structs *\\n ***********/\\n\\n struct Buffer {\\n bytes32 context;\\n mapping(uint256 => bytes32) buf;\\n }\\n\\n struct BufferContext {\\n // Stores the length of the array. Uint40 is way more elements than we'll ever reasonably\\n // need in an array and we get an extra 27 bytes of extra data to play with.\\n uint40 length;\\n // Arbitrary extra data that can be modified whenever the length is updated. Useful for\\n // squeezing out some gas optimizations.\\n bytes27 extraData;\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n * @param _extraData Global extra data.\\n */\\n function push(\\n Buffer storage _self,\\n bytes32 _value,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.buf[ctx.length] = _value;\\n\\n // Bump the global index and insert our extra data, then save the context.\\n ctx.length++;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n */\\n function push(Buffer storage _self, bytes32 _value) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.push(_value, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves an element from the buffer.\\n * @param _self Buffer to access.\\n * @param _index Element index to retrieve.\\n * @return Value of the element at the given index.\\n */\\n function get(Buffer storage _self, uint256 _index) internal view returns (bytes32) {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n return _self.buf[_index];\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n * @param _extraData Optional global extra data.\\n */\\n function deleteElementsAfterInclusive(\\n Buffer storage _self,\\n uint40 _index,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n // Set our length and extra data, save the context.\\n ctx.length = _index;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n */\\n function deleteElementsAfterInclusive(Buffer storage _self, uint40 _index) internal {\\n BufferContext memory ctx = _self.getContext();\\n _self.deleteElementsAfterInclusive(_index, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves the current global index.\\n * @param _self Buffer to access.\\n * @return Current global index.\\n */\\n function getLength(Buffer storage _self) internal view returns (uint40) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.length;\\n }\\n\\n /**\\n * Changes current global extra data.\\n * @param _self Buffer to access.\\n * @param _extraData New global extra data.\\n */\\n function setExtraData(Buffer storage _self, bytes27 _extraData) internal {\\n BufferContext memory ctx = _self.getContext();\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Retrieves the current global extra data.\\n * @param _self Buffer to access.\\n * @return Current global extra data.\\n */\\n function getExtraData(Buffer storage _self) internal view returns (bytes27) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.extraData;\\n }\\n\\n /**\\n * Sets the current buffer context.\\n * @param _self Buffer to access.\\n * @param _ctx Current buffer context.\\n */\\n function setContext(Buffer storage _self, BufferContext memory _ctx) internal {\\n bytes32 context;\\n uint40 length = _ctx.length;\\n bytes27 extraData = _ctx.extraData;\\n assembly {\\n context := length\\n context := or(context, extraData)\\n }\\n\\n if (_self.context != context) {\\n _self.context = context;\\n }\\n }\\n\\n /**\\n * Retrieves the current buffer context.\\n * @param _self Buffer to access.\\n * @return Current buffer context.\\n */\\n function getContext(Buffer storage _self) internal view returns (BufferContext memory) {\\n bytes32 context = _self.context;\\n uint40 length;\\n bytes27 extraData;\\n assembly {\\n length := and(\\n context,\\n 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF\\n )\\n extraData := and(\\n context,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000\\n )\\n }\\n\\n return BufferContext({ length: length, extraData: extraData });\\n }\\n}\\n\",\"keccak256\":\"0x38917b618db448e356c76c999ce9aaca094541eb1f9bc65b06b8d4d84308f056\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b50604051620011b3380380620011b3833981016040819052620000349162000129565b600080546001600160a01b0319166001600160a01b0384161790558051620000649060019060208401906200006d565b50505062000266565b8280546200007b9062000229565b90600052602060002090601f0160209004810192826200009f5760008555620000ea565b82601f10620000ba57805160ff1916838001178555620000ea565b82800160010185558215620000ea579182015b82811115620000ea578251825591602001919060010190620000cd565b50620000f8929150620000fc565b5090565b5b80821115620000f85760008155600101620000fd565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200013d57600080fd5b82516001600160a01b03811681146200015557600080fd5b602084810151919350906001600160401b03808211156200017557600080fd5b818601915086601f8301126200018a57600080fd5b8151818111156200019f576200019f62000113565b604051601f8201601f19908116603f01168101908382118183101715620001ca57620001ca62000113565b816040528281528986848701011115620001e357600080fd5b600093505b82841015620002075784840186015181850187015292850192620001e8565b82841115620002195760008684830101525b8096505050505050509250929050565b600181811c908216806200023e57607f821691505b602082108114156200026057634e487b7160e01b600052602260045260246000fd5b50919050565b610f3d80620002766000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea264697066735822122008d3c580919ad7d42388bef81f9dfd29b521ea50250f4eb6e1cff3ebbec420cc64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea264697066735822122008d3c580919ad7d42388bef81f9dfd29b521ea50250f4eb6e1cff3ebbec420cc64736f6c63430008090033",
"devdoc": {
"details": "The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain Runtime target: EVM",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_libAddressManager": "Address of the Address Manager.",
"_owner": "Name of the contract that owns this container (will be resolved later)."
}
},
"deleteElementsAfterInclusive(uint256)": {
"params": {
"_index": "Object index to delete from."
}
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_index": "Object index to delete from."
}
},
"get(uint256)": {
"params": {
"_index": "Index of the particular object to access."
},
"returns": {
"_0": "32 byte object value."
}
},
"getGlobalMetadata()": {
"returns": {
"_0": "Container global metadata field."
}
},
"length()": {
"returns": {
"_0": "Number of objects in the container."
}
},
"push(bytes32)": {
"params": {
"_object": "A 32 byte value to insert into the container."
}
},
"push(bytes32,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_object": "A 32 byte value to insert into the container."
}
},
"resolve(string)": {
"params": {
"_name": "Name to resolve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
},
"setGlobalMetadata(bytes27)": {
"params": {
"_globalMetadata": "New global metadata to set."
}
}
},
"title": "ChainStorageContainer",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"deleteElementsAfterInclusive(uint256)": {
"notice": "Removes all objects after and including a given index."
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"notice": "Removes all objects after and including a given index. Also allows setting the global metadata field."
},
"get(uint256)": {
"notice": "Retrieves an object from the container."
},
"getGlobalMetadata()": {
"notice": "Retrieves the container's global metadata field."
},
"length()": {
"notice": "Retrieves the number of objects stored in the container."
},
"push(bytes32)": {
"notice": "Pushes an object into the container."
},
"push(bytes32,bytes27)": {
"notice": "Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \"length\" storage slot anyway, which also contains the global metadata (it's an optimization)."
},
"resolve(string)": {
"notice": "Resolves the address associated with a given name."
},
"setGlobalMetadata(bytes27)": {
"notice": "Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 6653,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "libAddressManager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)6645"
},
{
"astId": 4067,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "owner",
"offset": 0,
"slot": "1",
"type": "t_string_storage"
},
{
"astId": 4070,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buffer",
"offset": 0,
"slot": "2",
"type": "t_struct(Buffer)10202_storage"
}
],
"types": {
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(Lib_AddressManager)6645": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_mapping(t_uint256,t_bytes32)": {
"encoding": "mapping",
"key": "t_uint256",
"label": "mapping(uint256 => bytes32)",
"numberOfBytes": "32",
"value": "t_bytes32"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
"t_struct(Buffer)10202_storage": {
"encoding": "inplace",
"label": "struct Lib_Buffer.Buffer",
"members": [
{
"astId": 10197,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "context",
"offset": 0,
"slot": "0",
"type": "t_bytes32"
},
{
"astId": 10201,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buf",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_uint256,t_bytes32)"
}
],
"numberOfBytes": "64"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0xb0ddFf09c4019e31960de11bD845E836078E8EbE",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
},
{
"internalType": "string",
"name": "_owner",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "deleteElementsAfterInclusive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_index",
"type": "uint256"
}
],
"name": "get",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getGlobalMetadata",
"outputs": [
{
"internalType": "bytes27",
"name": "",
"type": "bytes27"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "length",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "libAddressManager",
"outputs": [
{
"internalType": "contract Lib_AddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
},
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_object",
"type": "bytes32"
}
],
"name": "push",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "resolve",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes27",
"name": "_globalMetadata",
"type": "bytes27"
}
],
"name": "setGlobalMetadata",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0xd7ecdfd84484e20389bdbf5cba0fa322ab2fbbad9210c336972c1d59c8bfba89",
"receipt": {
"to": null,
"from": "0x0bb2cA5Ea700ba04c713008E1a3D198B4e8dA7a7",
"contractAddress": "0xb0ddFf09c4019e31960de11bD845E836078E8EbE",
"transactionIndex": 36,
"gasUsed": "946930",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x958da862ab834f2bbc56689bdc62ba0d552c87cdfe368111687666885419e552",
"transactionHash": "0xd7ecdfd84484e20389bdbf5cba0fa322ab2fbbad9210c336972c1d59c8bfba89",
"logs": [],
"blockNumber": 13596457,
"cumulativeGasUsed": "5059925",
"status": 1,
"byzantium": true
},
"args": [
"0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"StateCommitmentChain"
],
"solcInputHash": "8a22f2b322f61ab13865f2d2a82e5f09",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_owner\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"deleteElementsAfterInclusive\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"get\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGlobalMetadata\",\"outputs\":[{\"internalType\":\"bytes27\",\"name\":\"\",\"type\":\"bytes27\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"length\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"libAddressManager\",\"outputs\":[{\"internalType\":\"contract Lib_AddressManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"},{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_object\",\"type\":\"bytes32\"}],\"name\":\"push\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes27\",\"name\":\"_globalMetadata\",\"type\":\"bytes27\"}],\"name\":\"setGlobalMetadata\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain Runtime target: EVM\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_libAddressManager\":\"Address of the Address Manager.\",\"_owner\":\"Name of the contract that owns this container (will be resolved later).\"}},\"deleteElementsAfterInclusive(uint256)\":{\"params\":{\"_index\":\"Object index to delete from.\"}},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_index\":\"Object index to delete from.\"}},\"get(uint256)\":{\"params\":{\"_index\":\"Index of the particular object to access.\"},\"returns\":{\"_0\":\"32 byte object value.\"}},\"getGlobalMetadata()\":{\"returns\":{\"_0\":\"Container global metadata field.\"}},\"length()\":{\"returns\":{\"_0\":\"Number of objects in the container.\"}},\"push(bytes32)\":{\"params\":{\"_object\":\"A 32 byte value to insert into the container.\"}},\"push(bytes32,bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata for the container.\",\"_object\":\"A 32 byte value to insert into the container.\"}},\"resolve(string)\":{\"params\":{\"_name\":\"Name to resolve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"setGlobalMetadata(bytes27)\":{\"params\":{\"_globalMetadata\":\"New global metadata to set.\"}}},\"title\":\"ChainStorageContainer\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"deleteElementsAfterInclusive(uint256)\":{\"notice\":\"Removes all objects after and including a given index.\"},\"deleteElementsAfterInclusive(uint256,bytes27)\":{\"notice\":\"Removes all objects after and including a given index. Also allows setting the global metadata field.\"},\"get(uint256)\":{\"notice\":\"Retrieves an object from the container.\"},\"getGlobalMetadata()\":{\"notice\":\"Retrieves the container's global metadata field.\"},\"length()\":{\"notice\":\"Retrieves the number of objects stored in the container.\"},\"push(bytes32)\":{\"notice\":\"Pushes an object into the container.\"},\"push(bytes32,bytes27)\":{\"notice\":\"Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global metadata (it's an optimization).\"},\"resolve(string)\":{\"notice\":\"Resolves the address associated with a given name.\"},\"setGlobalMetadata(bytes27)\":{\"notice\":\"Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/rollup/ChainStorageContainer.sol\":\"ChainStorageContainer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/rollup/ChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_Buffer } from \\\"../../libraries/utils/Lib_Buffer.sol\\\";\\nimport { Lib_AddressResolver } from \\\"../../libraries/resolver/Lib_AddressResolver.sol\\\";\\n\\n/* Interface Imports */\\nimport { IChainStorageContainer } from \\\"./IChainStorageContainer.sol\\\";\\n\\n/**\\n * @title ChainStorageContainer\\n * @dev The Chain Storage Container provides its owner contract with read, write and delete\\n * functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which\\n * can no longer be used in a fraud proof due to the fraud window having passed, and the associated\\n * chain state or transactions being finalized.\\n * Three distinct Chain Storage Containers will be deployed on Layer 1:\\n * 1. Stores transaction batches for the Canonical Transaction Chain\\n * 2. Stores queued transactions for the Canonical Transaction Chain\\n * 3. Stores chain state batches for the State Commitment Chain\\n *\\n * Runtime target: EVM\\n */\\ncontract ChainStorageContainer is IChainStorageContainer, Lib_AddressResolver {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Lib_Buffer.Buffer;\\n\\n /*************\\n * Variables *\\n *************/\\n\\n string public owner;\\n Lib_Buffer.Buffer internal buffer;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Address Manager.\\n * @param _owner Name of the contract that owns this container (will be resolved later).\\n */\\n constructor(address _libAddressManager, string memory _owner)\\n Lib_AddressResolver(_libAddressManager)\\n {\\n owner = _owner;\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n modifier onlyOwner() {\\n require(\\n msg.sender == resolve(owner),\\n \\\"ChainStorageContainer: Function can only be called by the owner.\\\"\\n );\\n _;\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function setGlobalMetadata(bytes27 _globalMetadata) public onlyOwner {\\n return buffer.setExtraData(_globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function getGlobalMetadata() public view returns (bytes27) {\\n return buffer.getExtraData();\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function length() public view returns (uint256) {\\n return uint256(buffer.getLength());\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function push(bytes32 _object) public onlyOwner {\\n buffer.push(_object);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function push(bytes32 _object, bytes27 _globalMetadata) public onlyOwner {\\n buffer.push(_object, _globalMetadata);\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function get(uint256 _index) public view returns (bytes32) {\\n return buffer.get(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function deleteElementsAfterInclusive(uint256 _index) public onlyOwner {\\n buffer.deleteElementsAfterInclusive(uint40(_index));\\n }\\n\\n /**\\n * @inheritdoc IChainStorageContainer\\n */\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata)\\n public\\n onlyOwner\\n {\\n buffer.deleteElementsAfterInclusive(uint40(_index), _globalMetadata);\\n }\\n}\\n\",\"keccak256\":\"0x4364f98f8f4f615cd4043ca64014c4b6c434a575a5709e8e5f35fd53df7370c2\",\"license\":\"MIT\"},\"contracts/L1/rollup/IChainStorageContainer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title IChainStorageContainer\\n */\\ninterface IChainStorageContainer {\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the container's global metadata field. We're using `bytes27` here because we use five\\n * bytes to maintain the length of the underlying data structure, meaning we have an extra\\n * 27 bytes to store arbitrary data.\\n * @param _globalMetadata New global metadata to set.\\n */\\n function setGlobalMetadata(bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves the container's global metadata field.\\n * @return Container global metadata field.\\n */\\n function getGlobalMetadata() external view returns (bytes27);\\n\\n /**\\n * Retrieves the number of objects stored in the container.\\n * @return Number of objects in the container.\\n */\\n function length() external view returns (uint256);\\n\\n /**\\n * Pushes an object into the container.\\n * @param _object A 32 byte value to insert into the container.\\n */\\n function push(bytes32 _object) external;\\n\\n /**\\n * Pushes an object into the container. Function allows setting the global metadata since\\n * we'll need to touch the \\\"length\\\" storage slot anyway, which also contains the global\\n * metadata (it's an optimization).\\n * @param _object A 32 byte value to insert into the container.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function push(bytes32 _object, bytes27 _globalMetadata) external;\\n\\n /**\\n * Retrieves an object from the container.\\n * @param _index Index of the particular object to access.\\n * @return 32 byte object value.\\n */\\n function get(uint256 _index) external view returns (bytes32);\\n\\n /**\\n * Removes all objects after and including a given index.\\n * @param _index Object index to delete from.\\n */\\n function deleteElementsAfterInclusive(uint256 _index) external;\\n\\n /**\\n * Removes all objects after and including a given index. Also allows setting the global\\n * metadata field.\\n * @param _index Object index to delete from.\\n * @param _globalMetadata New global metadata for the container.\\n */\\n function deleteElementsAfterInclusive(uint256 _index, bytes27 _globalMetadata) external;\\n}\\n\",\"keccak256\":\"0xe55ad72572ec47dc09a02228d0c5a438571c76a41d16d92b35add057811977ce\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(string indexed _name, address _newAddress, address _oldAddress);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping(bytes32 => address) private addresses;\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(string memory _name, address _address) external onlyOwner {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(_name, _address, oldAddress);\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(string memory _name) external view returns (address) {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(string memory _name) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0xcde9b29429d512c549f7c1b8a033f161fa71c18cda08b241748663854196ae14\",\"license\":\"MIT\"},\"contracts/libraries/resolver/Lib_AddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_AddressResolver\\n */\\nabstract contract Lib_AddressResolver {\\n /*************\\n * Variables *\\n *************/\\n\\n Lib_AddressManager public libAddressManager;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n */\\n constructor(address _libAddressManager) {\\n libAddressManager = Lib_AddressManager(_libAddressManager);\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Resolves the address associated with a given name.\\n * @param _name Name to resolve an address for.\\n * @return Address associated with the given name.\\n */\\n function resolve(string memory _name) public view returns (address) {\\n return libAddressManager.getAddress(_name);\\n }\\n}\\n\",\"keccak256\":\"0x515c4db671a28e2fe180201f6d11c0208c05f582ca3489fb6b8e81c27659bc62\",\"license\":\"MIT\"},\"contracts/libraries/utils/Lib_Buffer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Lib_Buffer\\n * @dev This library implements a bytes32 storage array with some additional gas-optimized\\n * functionality. In particular, it encodes its length as a uint40, and tightly packs this with an\\n * overwritable \\\"extra data\\\" field so we can store more information with a single SSTORE.\\n */\\nlibrary Lib_Buffer {\\n /*************\\n * Libraries *\\n *************/\\n\\n using Lib_Buffer for Buffer;\\n\\n /***********\\n * Structs *\\n ***********/\\n\\n struct Buffer {\\n bytes32 context;\\n mapping(uint256 => bytes32) buf;\\n }\\n\\n struct BufferContext {\\n // Stores the length of the array. Uint40 is way more elements than we'll ever reasonably\\n // need in an array and we get an extra 27 bytes of extra data to play with.\\n uint40 length;\\n // Arbitrary extra data that can be modified whenever the length is updated. Useful for\\n // squeezing out some gas optimizations.\\n bytes27 extraData;\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n * @param _extraData Global extra data.\\n */\\n function push(\\n Buffer storage _self,\\n bytes32 _value,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.buf[ctx.length] = _value;\\n\\n // Bump the global index and insert our extra data, then save the context.\\n ctx.length++;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Pushes a single element to the buffer.\\n * @param _self Buffer to access.\\n * @param _value Value to push to the buffer.\\n */\\n function push(Buffer storage _self, bytes32 _value) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n _self.push(_value, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves an element from the buffer.\\n * @param _self Buffer to access.\\n * @param _index Element index to retrieve.\\n * @return Value of the element at the given index.\\n */\\n function get(Buffer storage _self, uint256 _index) internal view returns (bytes32) {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n return _self.buf[_index];\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n * @param _extraData Optional global extra data.\\n */\\n function deleteElementsAfterInclusive(\\n Buffer storage _self,\\n uint40 _index,\\n bytes27 _extraData\\n ) internal {\\n BufferContext memory ctx = _self.getContext();\\n\\n require(_index < ctx.length, \\\"Index out of bounds.\\\");\\n\\n // Set our length and extra data, save the context.\\n ctx.length = _index;\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Deletes all elements after (and including) a given index.\\n * @param _self Buffer to access.\\n * @param _index Index of the element to delete from (inclusive).\\n */\\n function deleteElementsAfterInclusive(Buffer storage _self, uint40 _index) internal {\\n BufferContext memory ctx = _self.getContext();\\n _self.deleteElementsAfterInclusive(_index, ctx.extraData);\\n }\\n\\n /**\\n * Retrieves the current global index.\\n * @param _self Buffer to access.\\n * @return Current global index.\\n */\\n function getLength(Buffer storage _self) internal view returns (uint40) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.length;\\n }\\n\\n /**\\n * Changes current global extra data.\\n * @param _self Buffer to access.\\n * @param _extraData New global extra data.\\n */\\n function setExtraData(Buffer storage _self, bytes27 _extraData) internal {\\n BufferContext memory ctx = _self.getContext();\\n ctx.extraData = _extraData;\\n _self.setContext(ctx);\\n }\\n\\n /**\\n * Retrieves the current global extra data.\\n * @param _self Buffer to access.\\n * @return Current global extra data.\\n */\\n function getExtraData(Buffer storage _self) internal view returns (bytes27) {\\n BufferContext memory ctx = _self.getContext();\\n return ctx.extraData;\\n }\\n\\n /**\\n * Sets the current buffer context.\\n * @param _self Buffer to access.\\n * @param _ctx Current buffer context.\\n */\\n function setContext(Buffer storage _self, BufferContext memory _ctx) internal {\\n bytes32 context;\\n uint40 length = _ctx.length;\\n bytes27 extraData = _ctx.extraData;\\n assembly {\\n context := length\\n context := or(context, extraData)\\n }\\n\\n if (_self.context != context) {\\n _self.context = context;\\n }\\n }\\n\\n /**\\n * Retrieves the current buffer context.\\n * @param _self Buffer to access.\\n * @return Current buffer context.\\n */\\n function getContext(Buffer storage _self) internal view returns (BufferContext memory) {\\n bytes32 context = _self.context;\\n uint40 length;\\n bytes27 extraData;\\n assembly {\\n length := and(\\n context,\\n 0x000000000000000000000000000000000000000000000000000000FFFFFFFFFF\\n )\\n extraData := and(\\n context,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000\\n )\\n }\\n\\n return BufferContext({ length: length, extraData: extraData });\\n }\\n}\\n\",\"keccak256\":\"0x38917b618db448e356c76c999ce9aaca094541eb1f9bc65b06b8d4d84308f056\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b50604051620011b3380380620011b3833981016040819052620000349162000129565b600080546001600160a01b0319166001600160a01b0384161790558051620000649060019060208401906200006d565b50505062000266565b8280546200007b9062000229565b90600052602060002090601f0160209004810192826200009f5760008555620000ea565b82601f10620000ba57805160ff1916838001178555620000ea565b82800160010185558215620000ea579182015b82811115620000ea578251825591602001919060010190620000cd565b50620000f8929150620000fc565b5090565b5b80821115620000f85760008155600101620000fd565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156200013d57600080fd5b82516001600160a01b03811681146200015557600080fd5b602084810151919350906001600160401b03808211156200017557600080fd5b818601915086601f8301126200018a57600080fd5b8151818111156200019f576200019f62000113565b604051601f8201601f19908116603f01168101908382118183101715620001ca57620001ca62000113565b816040528281528986848701011115620001e357600080fd5b600093505b82841015620002075784840186015181850187015292850192620001e8565b82841115620002195760008684830101525b8096505050505050509250929050565b600181811c908216806200023e57607f821691505b602082108114156200026057634e487b7160e01b600052602260045260246000fd5b50919050565b610f3d80620002766000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea264697066735822122008d3c580919ad7d42388bef81f9dfd29b521ea50250f4eb6e1cff3ebbec420cc64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063461a4478116100815780639507d39a1161005b5780639507d39a146101a4578063b298e36b146101b7578063ccf8f969146101ca57600080fd5b8063461a4478146101695780634651d91e1461017c5780638da5cb5b1461018f57600080fd5b80632015276c116100b25780632015276c146100fe57806329061de214610111578063299ca4781461012457600080fd5b8063167fd681146100ce5780631f7b6d32146100e3575b600080fd5b6100e16100dc366004610c59565b6101e9565b005b6100eb61034d565b6040519081526020015b60405180910390f35b6100e161010c366004610c59565b610365565b6100e161011f366004610c85565b61043d565b6000546101449073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f5565b610144610177366004610cd6565b610517565b6100e161018a366004610da5565b6105c4565b61019761069b565b6040516100f59190610dbe565b6100eb6101b2366004610da5565b610729565b6100e16101c5366004610da5565b61073d565b6101d2610814565b60405164ffffffffff1990911681526020016100f5565b61027c600180546101f990610e31565b80601f016020809104026020016040519081016040528092919081815260200182805461022590610e31565b80156102725780601f1061024757610100808354040283529160200191610272565b820191906000526020600020905b81548152906001019060200180831161025557829003601f168201915b5050505050610517565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461033d57604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e60648201526084015b60405180910390fd5b61034960028383610825565b5050565b6000610359600261090c565b64ffffffffff16905090565b610375600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043157604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b61034960028383610957565b61044d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461050957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b6105146002826109e6565b50565b600080546040517fbf40fac100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063bf40fac19061056e908590600401610dbe565b60206040518083038186803b15801561058657600080fd5b505afa15801561059a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105be9190610e85565b92915050565b6105d4600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069057604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610a47565b600180546106a890610e31565b80601f01602080910402602001604051908101604052809291908181526020018280546106d490610e31565b80156107215780601f106106f657610100808354040283529160200191610721565b820191906000526020600020905b81548152906001019060200180831161070457829003601f168201915b505050505081565b60006105be600264ffffffffff8416610aa4565b61074d600180546101f990610e31565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080957604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f436861696e53746f72616765436f6e7461696e65723a2046756e6374696f6e2060448201527f63616e206f6e6c792062652063616c6c656420627920746865206f776e65722e6064820152608401610334565b610514600282610b73565b60006108206002610bd0565b905090565b600061086784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050806000015164ffffffffff168364ffffffffff16106108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b64ffffffffff8316815264ffffffffff19821660208201526109068482610c1e565b50505050565b60008061094f83604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b519392505050565b600061099984604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805164ffffffffff16600090815260018601602052604090208490558051909150816109c482610ebb565b64ffffffffff1690525064ffffffffff19821660208201526109068482610c1e565b6000610a2883604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b64ffffffffff19831660208201529050610a428382610c1e565b505050565b6000610a8983604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856108259092919063ffffffff16565b600080610ae784604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b805190915064ffffffffff168310610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e646578206f7574206f6620626f756e64732e0000000000000000000000006044820152606401610334565b50506000908152600191909101602052604090205490565b6000610bb583604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b9050610a42828260200151856109579092919063ffffffff16565b600080610c1383604080518082019091526000808252602082015250546040805180820190915264ffffffffff8216815264ffffffffff19909116602082015290565b602001519392505050565b8051602082015183548183179291908314610c37578285555b5050505050565b803564ffffffffff1981168114610c5457600080fd5b919050565b60008060408385031215610c6c57600080fd5b82359150610c7c60208401610c3e565b90509250929050565b600060208284031215610c9757600080fd5b610ca082610c3e565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610ce857600080fd5b813567ffffffffffffffff80821115610d0057600080fd5b818401915084601f830112610d1457600080fd5b813581811115610d2657610d26610ca7565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610d6c57610d6c610ca7565b81604052828152876020848701011115610d8557600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208284031215610db757600080fd5b5035919050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b81811115610dfd576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600181811c90821680610e4557607f821691505b60208210811415610e7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215610e9757600080fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114610ca057600080fd5b600064ffffffffff80831681811415610efd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600101939250505056fea264697066735822122008d3c580919ad7d42388bef81f9dfd29b521ea50250f4eb6e1cff3ebbec420cc64736f6c63430008090033",
"devdoc": {
"details": "The Chain Storage Container provides its owner contract with read, write and delete functionality. This provides gas efficiency gains by enabling it to overwrite storage slots which can no longer be used in a fraud proof due to the fraud window having passed, and the associated chain state or transactions being finalized. Three distinct Chain Storage Containers will be deployed on Layer 1: 1. Stores transaction batches for the Canonical Transaction Chain 2. Stores queued transactions for the Canonical Transaction Chain 3. Stores chain state batches for the State Commitment Chain Runtime target: EVM",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_libAddressManager": "Address of the Address Manager.",
"_owner": "Name of the contract that owns this container (will be resolved later)."
}
},
"deleteElementsAfterInclusive(uint256)": {
"params": {
"_index": "Object index to delete from."
}
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_index": "Object index to delete from."
}
},
"get(uint256)": {
"params": {
"_index": "Index of the particular object to access."
},
"returns": {
"_0": "32 byte object value."
}
},
"getGlobalMetadata()": {
"returns": {
"_0": "Container global metadata field."
}
},
"length()": {
"returns": {
"_0": "Number of objects in the container."
}
},
"push(bytes32)": {
"params": {
"_object": "A 32 byte value to insert into the container."
}
},
"push(bytes32,bytes27)": {
"params": {
"_globalMetadata": "New global metadata for the container.",
"_object": "A 32 byte value to insert into the container."
}
},
"resolve(string)": {
"params": {
"_name": "Name to resolve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
},
"setGlobalMetadata(bytes27)": {
"params": {
"_globalMetadata": "New global metadata to set."
}
}
},
"title": "ChainStorageContainer",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"deleteElementsAfterInclusive(uint256)": {
"notice": "Removes all objects after and including a given index."
},
"deleteElementsAfterInclusive(uint256,bytes27)": {
"notice": "Removes all objects after and including a given index. Also allows setting the global metadata field."
},
"get(uint256)": {
"notice": "Retrieves an object from the container."
},
"getGlobalMetadata()": {
"notice": "Retrieves the container's global metadata field."
},
"length()": {
"notice": "Retrieves the number of objects stored in the container."
},
"push(bytes32)": {
"notice": "Pushes an object into the container."
},
"push(bytes32,bytes27)": {
"notice": "Pushes an object into the container. Function allows setting the global metadata since we'll need to touch the \"length\" storage slot anyway, which also contains the global metadata (it's an optimization)."
},
"resolve(string)": {
"notice": "Resolves the address associated with a given name."
},
"setGlobalMetadata(bytes27)": {
"notice": "Sets the container's global metadata field. We're using `bytes27` here because we use five bytes to maintain the length of the underlying data structure, meaning we have an extra 27 bytes to store arbitrary data."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 6653,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "libAddressManager",
"offset": 0,
"slot": "0",
"type": "t_contract(Lib_AddressManager)6645"
},
{
"astId": 4067,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "owner",
"offset": 0,
"slot": "1",
"type": "t_string_storage"
},
{
"astId": 4070,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buffer",
"offset": 0,
"slot": "2",
"type": "t_struct(Buffer)10202_storage"
}
],
"types": {
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(Lib_AddressManager)6645": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_mapping(t_uint256,t_bytes32)": {
"encoding": "mapping",
"key": "t_uint256",
"label": "mapping(uint256 => bytes32)",
"numberOfBytes": "32",
"value": "t_bytes32"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
},
"t_struct(Buffer)10202_storage": {
"encoding": "inplace",
"label": "struct Lib_Buffer.Buffer",
"members": [
{
"astId": 10197,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "context",
"offset": 0,
"slot": "0",
"type": "t_bytes32"
},
{
"astId": 10201,
"contract": "contracts/L1/rollup/ChainStorageContainer.sol:ChainStorageContainer",
"label": "buf",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_uint256,t_bytes32)"
}
],
"numberOfBytes": "64"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0xD86065136E3ab1e3FCBbf47B59404c08A431051A",
"abi": [
{
"inputs": [
{
"internalType": "contract L1ChugSplashProxy",
"name": "_target",
"type": "address"
},
{
"internalType": "address",
"name": "_finalOwner",
"type": "address"
},
{
"internalType": "bytes32",
"name": "_codeHash",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_messengerSlotKey",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_messengerSlotVal",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_bridgeSlotKey",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_bridgeSlotVal",
"type": "bytes32"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "bridgeSlotKey",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bridgeSlotVal",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "codeHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_code",
"type": "bytes"
}
],
"name": "doActions",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "finalOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isUpgrading",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "messengerSlotKey",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "messengerSlotVal",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "returnOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "target",
"outputs": [
{
"internalType": "contract L1ChugSplashProxy",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x66aa5170e6ce4a62d40bf909c390b0263ae5df08d922b682374273b34fa03f0f",
"receipt": {
"to": null,
"from": "0x0bb2cA5Ea700ba04c713008E1a3D198B4e8dA7a7",
"contractAddress": "0xD86065136E3ab1e3FCBbf47B59404c08A431051A",
"transactionIndex": 24,
"gasUsed": "600228",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x2fc3021674d5715905434b8544da54a0036c015f330bb803a6f6b863b7459dca",
"transactionHash": "0x66aa5170e6ce4a62d40bf909c390b0263ae5df08d922b682374273b34fa03f0f",
"logs": [],
"blockNumber": 13596791,
"cumulativeGasUsed": "3529686",
"status": 1,
"byzantium": true
},
"args": [
"0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1",
"0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A",
"0x395448fabf9c422ff29a22e5b39869e32d00ca911f7553ec25591d8d47befaa1",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x00000000000000000000000025ace71c97B33Cc4729CF772ae268934F7ab5fA1",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000004200000000000000000000000000000000000010"
],
"solcInputHash": "475653b7e5822844bbc8885f604f5e79",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract L1ChugSplashProxy\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_finalOwner\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_codeHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_messengerSlotKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_messengerSlotVal\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_bridgeSlotKey\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_bridgeSlotVal\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"bridgeSlotKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeSlotVal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"codeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"doActions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"finalOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUpgrading\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messengerSlotKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messengerSlotVal\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"returnOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"target\",\"outputs\":[{\"internalType\":\"contract L1ChugSplashProxy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're working on a generalized version of this but this is good enough for the moment.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"ChugSplashDictator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"returnOwnership()\":{\"notice\":\"Transfers ownership of this contract to the finalOwner. Only callable by the finalOwner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/deployment/ChugSplashDictator.sol\":\"ChugSplashDictator\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/L1/deployment/ChugSplashDictator.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { L1ChugSplashProxy } from \\\"../../chugsplash/L1ChugSplashProxy.sol\\\";\\nimport { iL1ChugSplashDeployer } from \\\"../../chugsplash/interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title ChugSplashDictator\\n * @dev Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're\\n * working on a generalized version of this but this is good enough for the moment.\\n */\\ncontract ChugSplashDictator is iL1ChugSplashDeployer {\\n /*************\\n * Variables *\\n *************/\\n\\n bool public isUpgrading = true;\\n L1ChugSplashProxy public target;\\n address public finalOwner;\\n bytes32 public codeHash;\\n bytes32 public messengerSlotKey;\\n bytes32 public messengerSlotVal;\\n bytes32 public bridgeSlotKey;\\n bytes32 public bridgeSlotVal;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n constructor(\\n L1ChugSplashProxy _target,\\n address _finalOwner,\\n bytes32 _codeHash,\\n bytes32 _messengerSlotKey,\\n bytes32 _messengerSlotVal,\\n bytes32 _bridgeSlotKey,\\n bytes32 _bridgeSlotVal\\n ) {\\n target = _target;\\n finalOwner = _finalOwner;\\n codeHash = _codeHash;\\n messengerSlotKey = _messengerSlotKey;\\n messengerSlotVal = _messengerSlotVal;\\n bridgeSlotKey = _bridgeSlotKey;\\n bridgeSlotVal = _bridgeSlotVal;\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n function doActions(bytes memory _code) external {\\n require(keccak256(_code) == codeHash, \\\"ChugSplashDictator: Incorrect code hash.\\\");\\n\\n target.setCode(_code);\\n target.setStorage(messengerSlotKey, messengerSlotVal);\\n target.setStorage(bridgeSlotKey, bridgeSlotVal);\\n target.setOwner(finalOwner);\\n }\\n\\n /**\\n * Transfers ownership of this contract to the finalOwner.\\n * Only callable by the finalOwner, which is intended to be our multisig.\\n * This function shouldn't be necessary, but it gives a sense of reassurance that we can\\n * recover if something really surprising goes wrong.\\n */\\n function returnOwnership() external {\\n require(msg.sender == finalOwner, \\\"ChugSplashDictator: only callable by finalOwner\\\");\\n\\n target.setOwner(finalOwner);\\n }\\n}\\n\",\"keccak256\":\"0xd6b7d80400d6cafd7d65c00715f3f03305537e96b25ff75f13f5c3163e81256c\",\"license\":\"MIT\"},\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 internal constant DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(address _owner) {\\n _setOwner(_owner);\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(iL1ChugSplashDeployer.isUpgrading.selector)\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(ret == 0, \\\"L1ChugSplashProxy: system is currently being upgraded\\\");\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n function setCode(bytes memory _code) public proxyCallIfNotOwner {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(DEPLOY_CODE_PREFIX, _code);\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n function setStorage(bytes32 _key, bytes32 _value) public proxyCallIfNotOwner {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n function setOwner(address _owner) public proxyCallIfNotOwner {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n function getOwner() public proxyCallIfNotOwner returns (address) {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n function getImplementation() public proxyCallIfNotOwner returns (address) {\\n return _getImplementation();\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(address _owner) internal {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(address _account) internal view returns (bytes32) {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal onlyWhenNotPaused {\\n address implementation = _getImplementation();\\n\\n require(implementation != address(0), \\\"L1ChugSplashProxy: implementation is not set yet\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc30cc735cf86431bd2234a3689d536aa76e5765522ff9f5b7c160deed85fa099\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading() external view returns (bool);\\n}\\n\",\"keccak256\":\"0x9a496d99f111c1091f0c33d6bfc7802a522baa7235614b0014f35e4bbe280e57\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040526000805460ff1916600117905534801561001d57600080fd5b5060405161088338038061088383398101604081905261003c916100a8565b60008054610100600160a81b0319166101006001600160a01b03998a1602179055600180546001600160a01b031916969097169590951790955560029290925560035560045560059190915560065561010f565b6001600160a01b03811681146100a557600080fd5b50565b600080600080600080600060e0888a0312156100c357600080fd5b87516100ce81610090565b60208901519097506100df81610090565b604089015160608a015160808b015160a08c015160c0909c01519a9d939c50919a90999198509650945092505050565b6107658061011e6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063708518de11610076578063a3b2d8a51161005b578063a3b2d8a51461015c578063b794726214610165578063d4b839921461018257600080fd5b8063708518de1461014a578063907023dd1461015357600080fd5b806318edaaf2116100a757806318edaaf214610122578063297d1a34146101395780635307023b1461014157600080fd5b80630bf56f21146100c357806317ad94ec146100d8575b600080fd5b6100d66100d13660046105ed565b6101a7565b005b6001546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61012b60025481565b604051908152602001610119565b6100d6610489565b61012b60045481565b61012b60035481565b61012b60065481565b61012b60055481565b6000546101729060ff1681565b6040519015158152602001610119565b6000546100f890610100900473ffffffffffffffffffffffffffffffffffffffff1681565b6002548151602083012014610243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4368756753706c6173684469637461746f723a20496e636f727265637420636f60448201527f646520686173682e00000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000546040517f6c5d4ad000000000000000000000000000000000000000000000000000000000815261010090910473ffffffffffffffffffffffffffffffffffffffff1690636c5d4ad09061029d9084906004016106bc565b600060405180830381600087803b1580156102b757600080fd5b505af11580156102cb573d6000803e3d6000fd5b5050600054600354600480546040517f9b0b0fda00000000000000000000000000000000000000000000000000000000815291820192909252602481019190915261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b15801561034e57600080fd5b505af1158015610362573d6000803e3d6000fd5b50506000546005546006546040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081526004810192909252602482015261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b50506000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526101009092041692506313af40359150602401600060405180830381600087803b15801561046e57600080fd5b505af1158015610482573d6000803e3d6000fd5b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610530576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4368756753706c6173684469637461746f723a206f6e6c792063616c6c61626c60448201527f652062792066696e616c4f776e65720000000000000000000000000000000000606482015260840161023a565b6000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015261010090920416906313af403590602401600060405180830381600087803b1580156105a457600080fd5b505af11580156105b8573d6000803e3d6000fd5b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105ff57600080fd5b813567ffffffffffffffff8082111561061757600080fd5b818401915084601f83011261062b57600080fd5b81358181111561063d5761063d6105be565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610683576106836105be565b8160405282815287602084870101111561069c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156106e9578581018301518582016040015282016106cd565b818111156106fb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea2646970667358221220ea63e0ffbf6691431ee73a4c29831d3972b1c90e51eb75830c3242850fd79a1c64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063708518de11610076578063a3b2d8a51161005b578063a3b2d8a51461015c578063b794726214610165578063d4b839921461018257600080fd5b8063708518de1461014a578063907023dd1461015357600080fd5b806318edaaf2116100a757806318edaaf214610122578063297d1a34146101395780635307023b1461014157600080fd5b80630bf56f21146100c357806317ad94ec146100d8575b600080fd5b6100d66100d13660046105ed565b6101a7565b005b6001546100f89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61012b60025481565b604051908152602001610119565b6100d6610489565b61012b60045481565b61012b60035481565b61012b60065481565b61012b60055481565b6000546101729060ff1681565b6040519015158152602001610119565b6000546100f890610100900473ffffffffffffffffffffffffffffffffffffffff1681565b6002548151602083012014610243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4368756753706c6173684469637461746f723a20496e636f727265637420636f60448201527f646520686173682e00000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6000546040517f6c5d4ad000000000000000000000000000000000000000000000000000000000815261010090910473ffffffffffffffffffffffffffffffffffffffff1690636c5d4ad09061029d9084906004016106bc565b600060405180830381600087803b1580156102b757600080fd5b505af11580156102cb573d6000803e3d6000fd5b5050600054600354600480546040517f9b0b0fda00000000000000000000000000000000000000000000000000000000815291820192909252602481019190915261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b15801561034e57600080fd5b505af1158015610362573d6000803e3d6000fd5b50506000546005546006546040517f9b0b0fda0000000000000000000000000000000000000000000000000000000081526004810192909252602482015261010090910473ffffffffffffffffffffffffffffffffffffffff169250639b0b0fda9150604401600060405180830381600087803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b50506000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526101009092041692506313af40359150602401600060405180830381600087803b15801561046e57600080fd5b505af1158015610482573d6000803e3d6000fd5b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610530576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4368756753706c6173684469637461746f723a206f6e6c792063616c6c61626c60448201527f652062792066696e616c4f776e65720000000000000000000000000000000000606482015260840161023a565b6000546001546040517f13af403500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015261010090920416906313af403590602401600060405180830381600087803b1580156105a457600080fd5b505af11580156105b8573d6000803e3d6000fd5b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156105ff57600080fd5b813567ffffffffffffffff8082111561061757600080fd5b818401915084601f83011261062b57600080fd5b81358181111561063d5761063d6105be565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610683576106836105be565b8160405282815287602084870101111561069c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156106e9578581018301518582016040015282016106cd565b818111156106fb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201604001939250505056fea2646970667358221220ea63e0ffbf6691431ee73a4c29831d3972b1c90e51eb75830c3242850fd79a1c64736f6c63430008090033",
"devdoc": {
"details": "Like the AddressDictator, but specifically for the Proxy__OVM_L1StandardBridge. We're working on a generalized version of this but this is good enough for the moment.",
"kind": "dev",
"methods": {},
"title": "ChugSplashDictator",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"returnOwnership()": {
"notice": "Transfers ownership of this contract to the finalOwner. Only callable by the finalOwner, which is intended to be our multisig. This function shouldn't be necessary, but it gives a sense of reassurance that we can recover if something really surprising goes wrong."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 11,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "isUpgrading",
"offset": 0,
"slot": "0",
"type": "t_bool"
},
{
"astId": 14,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "target",
"offset": 1,
"slot": "0",
"type": "t_contract(L1ChugSplashProxy)420"
},
{
"astId": 16,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "finalOwner",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 18,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "codeHash",
"offset": 0,
"slot": "2",
"type": "t_bytes32"
},
{
"astId": 20,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "messengerSlotKey",
"offset": 0,
"slot": "3",
"type": "t_bytes32"
},
{
"astId": 22,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "messengerSlotVal",
"offset": 0,
"slot": "4",
"type": "t_bytes32"
},
{
"astId": 24,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "bridgeSlotKey",
"offset": 0,
"slot": "5",
"type": "t_bytes32"
},
{
"astId": 26,
"contract": "contracts/L1/deployment/ChugSplashDictator.sol:ChugSplashDictator",
"label": "bridgeSlotVal",
"offset": 0,
"slot": "6",
"type": "t_bytes32"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"encoding": "inplace",
"label": "bool",
"numberOfBytes": "1"
},
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(L1ChugSplashProxy)420": {
"encoding": "inplace",
"label": "contract L1ChugSplashProxy",
"numberOfBytes": "20"
}
}
}
}
\ No newline at end of file
{
"address": "0x29Ea454F8f2750e345E52e302A0c09f1A5215AC7",
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ERC20DepositInitiated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ERC20WithdrawalFinalized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ETHDepositInitiated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "ETHWithdrawalFinalized",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositERC20To",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositETH",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint32",
"name": "_l2Gas",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "depositETHTo",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "deposits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "donateETH",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1Token",
"type": "address"
},
{
"internalType": "address",
"name": "_l2Token",
"type": "address"
},
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "finalizeERC20Withdrawal",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "finalizeETHWithdrawal",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_l1messenger",
"type": "address"
},
{
"internalType": "address",
"name": "_l2TokenBridge",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "l2TokenBridge",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "messenger",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0x6964eba7d623da75d18f36f26f2f93aed69864593b300b2f8a042b78df2bbfe4",
"receipt": {
"to": null,
"from": "0x0bb2cA5Ea700ba04c713008E1a3D198B4e8dA7a7",
"contractAddress": "0x29Ea454F8f2750e345E52e302A0c09f1A5215AC7",
"transactionIndex": 37,
"gasUsed": "1467253",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xae31bbd7e7a3a852ca8b7074eb8c361afff2a33582459514db9ef42ea1f4a613",
"transactionHash": "0x6964eba7d623da75d18f36f26f2f93aed69864593b300b2f8a042b78df2bbfe4",
"logs": [],
"blockNumber": 13596925,
"cumulativeGasUsed": "3636752",
"status": 1,
"byzantium": true
},
"args": [],
"solcInputHash": "8a22f2b322f61ab13865f2d2a82e5f09",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ERC20DepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ERC20WithdrawalFinalized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ETHDepositInitiated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"ETHWithdrawalFinalized\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositERC20To\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_l2Gas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"depositETHTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"donateETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2Token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeERC20Withdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"finalizeETHWithdrawal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_l1messenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_l2TokenBridge\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2TokenBridge\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messenger\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits and listening to it for newly finalized withdrawals. Runtime target: EVM\",\"kind\":\"dev\",\"methods\":{\"depositERC20(address,address,uint256,uint32,bytes)\":{\"details\":\"deposit an amount of the ERC20 to the caller's balance on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit\",\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l1Token\":\"Address of the L1 ERC20 we are depositing\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\",\"_l2Token\":\"Address of the L1 respective L2 ERC20\"}},\"depositERC20To(address,address,address,uint256,uint32,bytes)\":{\"details\":\"deposit an amount of ERC20 to a recipient's balance on L2.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l1Token\":\"Address of the L1 ERC20 we are depositing\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\",\"_l2Token\":\"Address of the L1 respective L2 ERC20\",\"_to\":\"L2 address to credit the withdrawal to.\"}},\"depositETH(uint32,bytes)\":{\"details\":\"Deposit an amount of the ETH to the caller's balance on L2.\",\"params\":{\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\"}},\"depositETHTo(address,uint32,bytes)\":{\"details\":\"Deposit an amount of ETH to a recipient's balance on L2.\",\"params\":{\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_l2Gas\":\"Gas limit required to complete the deposit on L2.\",\"_to\":\"L2 address to credit the withdrawal to.\"}},\"donateETH()\":{\"details\":\"Adds ETH balance to the account. This is meant to allow for ETH to be migrated from an old gateway to a new gateway. NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the old contract\"},\"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)\":{\"details\":\"Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ERC20 token. This call will fail if the initialized withdrawal from L2 has not been finalized.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_data\":\"Data provided by the sender on L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_from\":\"L2 address initiating the transfer.\",\"_l1Token\":\"Address of L1 token to finalizeWithdrawal for.\",\"_l2Token\":\"Address of L2 token where withdrawal was initiated.\",\"_to\":\"L1 address to credit the withdrawal to.\"}},\"finalizeETHWithdrawal(address,address,uint256,bytes)\":{\"details\":\"Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized.\",\"params\":{\"_amount\":\"Amount of the ERC20 to deposit.\",\"_data\":\"Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.\",\"_from\":\"L2 address initiating the transfer.\",\"_to\":\"L1 address to credit the withdrawal to.\"}},\"initialize(address,address)\":{\"params\":{\"_l1messenger\":\"L1 Messenger address being used for cross-chain communications.\",\"_l2TokenBridge\":\"L2 standard bridge address.\"}}},\"stateVariables\":{\"l2TokenBridge\":{\"details\":\"get the address of the corresponding L2 bridge contract.\",\"return\":\"Address of the corresponding L2 bridge contract.\",\"returns\":{\"_0\":\"Address of the corresponding L2 bridge contract.\"}}},\"title\":\"L1StandardBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/messaging/L1StandardBridge.sol\":\"L1StandardBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"contracts/L1/messaging/IL1ERC20Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title IL1ERC20Bridge\\n */\\ninterface IL1ERC20Bridge {\\n /**********\\n * Events *\\n **********/\\n\\n event ERC20DepositInitiated(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event ERC20WithdrawalFinalized(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @dev get the address of the corresponding L2 bridge contract.\\n * @return Address of the corresponding L2 bridge contract.\\n */\\n function l2TokenBridge() external returns (address);\\n\\n /**\\n * @dev deposit an amount of the ERC20 to the caller's balance on L2.\\n * @param _l1Token Address of the L1 ERC20 we are depositing\\n * @param _l2Token Address of the L1 respective L2 ERC20\\n * @param _amount Amount of the ERC20 to deposit\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositERC20(\\n address _l1Token,\\n address _l2Token,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external;\\n\\n /**\\n * @dev deposit an amount of ERC20 to a recipient's balance on L2.\\n * @param _l1Token Address of the L1 ERC20 we are depositing\\n * @param _l2Token Address of the L1 respective L2 ERC20\\n * @param _to L2 address to credit the withdrawal to.\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositERC20To(\\n address _l1Token,\\n address _l2Token,\\n address _to,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external;\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the\\n * L1 ERC20 token.\\n * This call will fail if the initialized withdrawal from L2 has not been finalized.\\n *\\n * @param _l1Token Address of L1 token to finalizeWithdrawal for.\\n * @param _l2Token Address of L2 token where withdrawal was initiated.\\n * @param _from L2 address initiating the transfer.\\n * @param _to L1 address to credit the withdrawal to.\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _data Data provided by the sender on L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function finalizeERC20Withdrawal(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external;\\n}\\n\",\"keccak256\":\"0x69f831896dcbb6bef4f2d6c8be6cd1bf352f5910074d3ce973b9f8e0a4f4c1dd\",\"license\":\"MIT\"},\"contracts/L1/messaging/IL1StandardBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\nimport \\\"./IL1ERC20Bridge.sol\\\";\\n\\n/**\\n * @title IL1StandardBridge\\n */\\ninterface IL1StandardBridge is IL1ERC20Bridge {\\n /**********\\n * Events *\\n **********/\\n event ETHDepositInitiated(\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event ETHWithdrawalFinalized(\\n address indexed _from,\\n address indexed _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @dev Deposit an amount of the ETH to the caller's balance on L2.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositETH(uint32 _l2Gas, bytes calldata _data) external payable;\\n\\n /**\\n * @dev Deposit an amount of ETH to a recipient's balance on L2.\\n * @param _to L2 address to credit the withdrawal to.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function depositETHTo(\\n address _to,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external payable;\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the\\n * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called\\n * before the withdrawal is finalized.\\n * @param _from L2 address initiating the transfer.\\n * @param _to L1 address to credit the withdrawal to.\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function finalizeETHWithdrawal(\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external;\\n}\\n\",\"keccak256\":\"0x3d511f1bcea86aa88a9c41798926ea75b5b3f455c0377e63223a123a9e714ddc\",\"license\":\"MIT\"},\"contracts/L1/messaging/L1StandardBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/* Interface Imports */\\nimport { IL1StandardBridge } from \\\"./IL1StandardBridge.sol\\\";\\nimport { IL1ERC20Bridge } from \\\"./IL1ERC20Bridge.sol\\\";\\nimport { IL2ERC20Bridge } from \\\"../../L2/messaging/IL2ERC20Bridge.sol\\\";\\nimport { IERC20 } from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/* Library Imports */\\nimport { CrossDomainEnabled } from \\\"../../libraries/bridge/CrossDomainEnabled.sol\\\";\\nimport { Lib_PredeployAddresses } from \\\"../../libraries/constants/Lib_PredeployAddresses.sol\\\";\\nimport { Address } from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport { SafeERC20 } from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/**\\n * @title L1StandardBridge\\n * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard\\n * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits\\n * and listening to it for newly finalized withdrawals.\\n *\\n * Runtime target: EVM\\n */\\ncontract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled {\\n using SafeERC20 for IERC20;\\n\\n /********************************\\n * External Contract References *\\n ********************************/\\n\\n address public l2TokenBridge;\\n\\n // Maps L1 token to L2 token to balance of the L1 token deposited\\n mapping(address => mapping(address => uint256)) public deposits;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n // This contract lives behind a proxy, so the constructor parameters will go unused.\\n constructor() CrossDomainEnabled(address(0)) {}\\n\\n /******************\\n * Initialization *\\n ******************/\\n\\n /**\\n * @param _l1messenger L1 Messenger address being used for cross-chain communications.\\n * @param _l2TokenBridge L2 standard bridge address.\\n */\\n function initialize(address _l1messenger, address _l2TokenBridge) public {\\n require(messenger == address(0), \\\"Contract has already been initialized.\\\");\\n messenger = _l1messenger;\\n l2TokenBridge = _l2TokenBridge;\\n }\\n\\n /**************\\n * Depositing *\\n **************/\\n\\n /** @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious\\n * contract via initcode, but it takes care of the user error we want to avoid.\\n */\\n modifier onlyEOA() {\\n // Used to stop deposits from contracts (avoid accidentally lost tokens)\\n require(!Address.isContract(msg.sender), \\\"Account not EOA\\\");\\n _;\\n }\\n\\n /**\\n * @dev This function can be called with no data\\n * to deposit an amount of ETH to the caller's balance on L2.\\n * Since the receive function doesn't take data, a conservative\\n * default amount is forwarded to L2.\\n */\\n receive() external payable onlyEOA {\\n _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes(\\\"\\\"));\\n }\\n\\n /**\\n * @inheritdoc IL1StandardBridge\\n */\\n function depositETH(uint32 _l2Gas, bytes calldata _data) external payable onlyEOA {\\n _initiateETHDeposit(msg.sender, msg.sender, _l2Gas, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1StandardBridge\\n */\\n function depositETHTo(\\n address _to,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external payable {\\n _initiateETHDeposit(msg.sender, _to, _l2Gas, _data);\\n }\\n\\n /**\\n * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of\\n * the deposit.\\n * @param _from Account to pull the deposit from on L1.\\n * @param _to Account to give the deposit to on L2.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function _initiateETHDeposit(\\n address _from,\\n address _to,\\n uint32 _l2Gas,\\n bytes memory _data\\n ) internal {\\n // Construct calldata for finalizeDeposit call\\n bytes memory message = abi.encodeWithSelector(\\n IL2ERC20Bridge.finalizeDeposit.selector,\\n address(0),\\n Lib_PredeployAddresses.OVM_ETH,\\n _from,\\n _to,\\n msg.value,\\n _data\\n );\\n\\n // Send calldata into L2\\n sendCrossDomainMessage(l2TokenBridge, _l2Gas, message);\\n\\n emit ETHDepositInitiated(_from, _to, msg.value, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1ERC20Bridge\\n */\\n function depositERC20(\\n address _l1Token,\\n address _l2Token,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external virtual onlyEOA {\\n _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1ERC20Bridge\\n */\\n function depositERC20To(\\n address _l1Token,\\n address _l2Token,\\n address _to,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) external virtual {\\n _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data);\\n }\\n\\n /**\\n * @dev Performs the logic for deposits by informing the L2 Deposited Token\\n * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom)\\n *\\n * @param _l1Token Address of the L1 ERC20 we are depositing\\n * @param _l2Token Address of the L1 respective L2 ERC20\\n * @param _from Account to pull the deposit from on L1\\n * @param _to Account to give the deposit to on L2\\n * @param _amount Amount of the ERC20 to deposit.\\n * @param _l2Gas Gas limit required to complete the deposit on L2.\\n * @param _data Optional data to forward to L2. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function _initiateERC20Deposit(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n uint32 _l2Gas,\\n bytes calldata _data\\n ) internal {\\n // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future\\n // withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if\\n // _from is an EOA or address(0).\\n IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount);\\n\\n // Construct calldata for _l2Token.finalizeDeposit(_to, _amount)\\n bytes memory message = abi.encodeWithSelector(\\n IL2ERC20Bridge.finalizeDeposit.selector,\\n _l1Token,\\n _l2Token,\\n _from,\\n _to,\\n _amount,\\n _data\\n );\\n\\n // Send calldata into L2\\n sendCrossDomainMessage(l2TokenBridge, _l2Gas, message);\\n\\n deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount;\\n\\n emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data);\\n }\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @inheritdoc IL1StandardBridge\\n */\\n function finalizeETHWithdrawal(\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external onlyFromCrossDomainAccount(l2TokenBridge) {\\n (bool success, ) = _to.call{ value: _amount }(new bytes(0));\\n require(success, \\\"TransferHelper::safeTransferETH: ETH transfer failed\\\");\\n\\n emit ETHWithdrawalFinalized(_from, _to, _amount, _data);\\n }\\n\\n /**\\n * @inheritdoc IL1ERC20Bridge\\n */\\n function finalizeERC20Withdrawal(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external onlyFromCrossDomainAccount(l2TokenBridge) {\\n deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] - _amount;\\n\\n // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer\\n IERC20(_l1Token).safeTransfer(_to, _amount);\\n\\n emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data);\\n }\\n\\n /*****************************\\n * Temporary - Migrating ETH *\\n *****************************/\\n\\n /**\\n * @dev Adds ETH balance to the account. This is meant to allow for ETH\\n * to be migrated from an old gateway to a new gateway.\\n * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the\\n * old contract\\n */\\n function donateETH() external payable {}\\n}\\n\",\"keccak256\":\"0x595295916d768e901f2b55589871ebd130b202cb2a9de6ba038382fbb058adaa\",\"license\":\"MIT\"},\"contracts/L2/messaging/IL2ERC20Bridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title IL2ERC20Bridge\\n */\\ninterface IL2ERC20Bridge {\\n /**********\\n * Events *\\n **********/\\n\\n event WithdrawalInitiated(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event DepositFinalized(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n event DepositFailed(\\n address indexed _l1Token,\\n address indexed _l2Token,\\n address indexed _from,\\n address _to,\\n uint256 _amount,\\n bytes _data\\n );\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * @dev get the address of the corresponding L1 bridge contract.\\n * @return Address of the corresponding L1 bridge contract.\\n */\\n function l1TokenBridge() external returns (address);\\n\\n /**\\n * @dev initiate a withdraw of some tokens to the caller's account on L1\\n * @param _l2Token Address of L2 token where withdrawal was initiated.\\n * @param _amount Amount of the token to withdraw.\\n * param _l1Gas Unused, but included for potential forward compatibility considerations.\\n * @param _data Optional data to forward to L1. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function withdraw(\\n address _l2Token,\\n uint256 _amount,\\n uint32 _l1Gas,\\n bytes calldata _data\\n ) external;\\n\\n /**\\n * @dev initiate a withdraw of some token to a recipient's account on L1.\\n * @param _l2Token Address of L2 token where withdrawal is initiated.\\n * @param _to L1 adress to credit the withdrawal to.\\n * @param _amount Amount of the token to withdraw.\\n * param _l1Gas Unused, but included for potential forward compatibility considerations.\\n * @param _data Optional data to forward to L1. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function withdrawTo(\\n address _l2Token,\\n address _to,\\n uint256 _amount,\\n uint32 _l1Gas,\\n bytes calldata _data\\n ) external;\\n\\n /*************************\\n * Cross-chain Functions *\\n *************************/\\n\\n /**\\n * @dev Complete a deposit from L1 to L2, and credits funds to the recipient's balance of this\\n * L2 token. This call will fail if it did not originate from a corresponding deposit in\\n * L1StandardTokenBridge.\\n * @param _l1Token Address for the l1 token this is called with\\n * @param _l2Token Address for the l2 token this is called with\\n * @param _from Account to pull the deposit from on L2.\\n * @param _to Address to receive the withdrawal at\\n * @param _amount Amount of the token to withdraw\\n * @param _data Data provider by the sender on L1. This data is provided\\n * solely as a convenience for external contracts. Aside from enforcing a maximum\\n * length, these contracts provide no guarantees about its content.\\n */\\n function finalizeDeposit(\\n address _l1Token,\\n address _l2Token,\\n address _from,\\n address _to,\\n uint256 _amount,\\n bytes calldata _data\\n ) external;\\n}\\n\",\"keccak256\":\"0x4674c3c8733ca0db16c2b81d58227560df36a07ded3b637a0793564d90ac0475\",\"license\":\"MIT\"},\"contracts/libraries/bridge/CrossDomainEnabled.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/* Interface Imports */\\nimport { ICrossDomainMessenger } from \\\"./ICrossDomainMessenger.sol\\\";\\n\\n/**\\n * @title CrossDomainEnabled\\n * @dev Helper contract for contracts performing cross-domain communications\\n *\\n * Compiler used: defined by inheriting contract\\n * Runtime target: defined by inheriting contract\\n */\\ncontract CrossDomainEnabled {\\n /*************\\n * Variables *\\n *************/\\n\\n // Messenger contract used to send and recieve messages from the other domain.\\n address public messenger;\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _messenger Address of the CrossDomainMessenger on the current layer.\\n */\\n constructor(address _messenger) {\\n messenger = _messenger;\\n }\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Enforces that the modified function is only callable by a specific cross-domain account.\\n * @param _sourceDomainAccount The only account on the originating domain which is\\n * authenticated to call this function.\\n */\\n modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) {\\n require(\\n msg.sender == address(getCrossDomainMessenger()),\\n \\\"OVM_XCHAIN: messenger contract unauthenticated\\\"\\n );\\n\\n require(\\n getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount,\\n \\\"OVM_XCHAIN: wrong sender of cross-domain message\\\"\\n );\\n\\n _;\\n }\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Gets the messenger, usually from storage. This function is exposed in case a child contract\\n * needs to override.\\n * @return The address of the cross-domain messenger contract which should be used.\\n */\\n function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) {\\n return ICrossDomainMessenger(messenger);\\n }\\n\\n /**q\\n * Sends a message to an account on another domain\\n * @param _crossDomainTarget The intended recipient on the destination domain\\n * @param _message The data to send to the target (usually calldata to a function with\\n * `onlyFromCrossDomainAccount()`)\\n * @param _gasLimit The gasLimit for the receipt of the message on the target domain.\\n */\\n function sendCrossDomainMessage(\\n address _crossDomainTarget,\\n uint32 _gasLimit,\\n bytes memory _message\\n ) internal {\\n getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit);\\n }\\n}\\n\",\"keccak256\":\"0x196609a9af91807d89f2d781c637a049bdc64c2d29ebed4b758b0a342576c4eb\",\"license\":\"MIT\"},\"contracts/libraries/bridge/ICrossDomainMessenger.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.9.0;\\n\\n/**\\n * @title ICrossDomainMessenger\\n */\\ninterface ICrossDomainMessenger {\\n /**********\\n * Events *\\n **********/\\n\\n event SentMessage(\\n address indexed target,\\n address sender,\\n bytes message,\\n uint256 messageNonce,\\n uint256 gasLimit\\n );\\n event RelayedMessage(bytes32 indexed msgHash);\\n event FailedRelayedMessage(bytes32 indexed msgHash);\\n\\n /*************\\n * Variables *\\n *************/\\n\\n function xDomainMessageSender() external view returns (address);\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sends a cross domain message to the target messenger.\\n * @param _target Target contract address.\\n * @param _message Message to send to the target.\\n * @param _gasLimit Gas limit for the provided message.\\n */\\n function sendMessage(\\n address _target,\\n bytes calldata _message,\\n uint32 _gasLimit\\n ) external;\\n}\\n\",\"keccak256\":\"0x8f29ae23021345a20ccac7b5edb3fc38268aef943b65adc8a32e74b80bf1833a\",\"license\":\"MIT\"},\"contracts/libraries/constants/Lib_PredeployAddresses.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\n/**\\n * @title Lib_PredeployAddresses\\n */\\nlibrary Lib_PredeployAddresses {\\n address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;\\n address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;\\n address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;\\n address payable internal constant OVM_ETH = payable(0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000);\\n address internal constant L2_CROSS_DOMAIN_MESSENGER =\\n 0x4200000000000000000000000000000000000007;\\n address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008;\\n address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009;\\n address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010;\\n address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011;\\n address internal constant L2_STANDARD_TOKEN_FACTORY =\\n 0x4200000000000000000000000000000000000012;\\n address internal constant L1_BLOCK_NUMBER = 0x4200000000000000000000000000000000000013;\\n}\\n\",\"keccak256\":\"0x2bc28307af93e9716151a41a81694b56cbe513ef5eb335fb1d81f35e5db8edfa\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b031916905561199e806100306000396000f3fe6080604052600436106100c05760003560e01c80638b4c40b0116100745780639a2ac6d51161004e5780639a2ac6d514610288578063a9f9e6751461029b578063b1a1a882146102bb57600080fd5b80638b4c40b0146101375780638f601f661461021557806391c49bf81461025b57600080fd5b8063485cc955116100a5578063485cc955146101b557806358a997f6146101d5578063838b2520146101f557600080fd5b80631532ec341461013e5780633cb747bf1461015e57600080fd5b3661013957333b156101195760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f41000000000000000000000000000000000060448201526064015b60405180910390fd5b610137333362030d40604051806020016040528060008152506102ce565b005b600080fd5b34801561014a57600080fd5b50610137610159366004611357565b61041a565b34801561016a57600080fd5b5060005461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c157600080fd5b506101376101d03660046113ca565b610790565b3480156101e157600080fd5b506101376101f036600461141c565b61086f565b34801561020157600080fd5b5061013761021036600461149f565b6108d6565b34801561022157600080fd5b5061024d6102303660046113ca565b600260209081526000928352604080842090915290825290205481565b6040519081526020016101ac565b34801561026757600080fd5b5060015461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b610137610296366004611535565b6108ef565b3480156102a757600080fd5b506101376102b6366004611598565b610937565b6101376102c9366004611611565b610c59565b600063662a633a60e01b600073deaddeaddeaddeaddeaddeaddeaddeaddead000087873487604051602401610308969594939291906116da565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506103ac9073ffffffffffffffffffffffffffffffffffffffff168483610cef565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23348560405161040b929190611735565b60405180910390a35050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661045260005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104f25760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff1661052860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561056d57600080fd5b505afa158015610581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a5919061174e565b73ffffffffffffffffffffffffffffffffffffffff161461062e5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff8716908690604051610665919061176b565b60006040518083038185875af1925050503d80600081146106a2576040519150601f19603f3d011682016040523d82523d6000602084013e6106a7565b606091505b505090508061071e5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c65640000000000000000000000006064820152608401610110565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e63187878760405161077f939291906117d0565b60405180910390a350505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff161561081c5760405162461bcd60e51b815260206004820152602660248201527f436f6e74726163742068617320616c7265616479206265656e20696e6974696160448201527f6c697a65642e00000000000000000000000000000000000000000000000000006064820152608401610110565b6000805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560018054929093169116179055565b333b156108be5760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b6108ce8686333388888888610d77565b505050505050565b6108e68787338888888888610d77565b50505050505050565b61093133858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b50505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661096f60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a0f5760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff16610a4560005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8a57600080fd5b505afa158015610a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac2919061174e565b73ffffffffffffffffffffffffffffffffffffffff1614610b4b5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054610b89908590611822565b73ffffffffffffffffffffffffffffffffffffffff808a166000818152600260209081526040808320948d1683529390529190912091909155610bcd908686610f27565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b388888888604051610c479493929190611839565b60405180910390a45050505050505050565b333b15610ca85760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b610cea33338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b505050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610d4990869085908790600401611879565b600060405180830381600087803b158015610d6357600080fd5b505af11580156108e6573d6000803e3d6000fd5b610d9973ffffffffffffffffffffffffffffffffffffffff8916873087610ffb565b600063662a633a60e01b89898989898888604051602401610dc097969594939291906118be565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600154909150610e649073ffffffffffffffffffffffffffffffffffffffff168583610cef565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c1683529290522054610ea290869061191b565b73ffffffffffffffffffffffffffffffffffffffff808b1660008181526002602090815260408083208e86168085529252918290209490945551918a1692917f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039690610f14908b908b908a908a90611839565b60405180910390a4505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610cea9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611059565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109319085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610f79565b60006110bb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661114b9092919063ffffffff16565b805190915015610cea57808060200190518101906110d99190611933565b610cea5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610110565b606061115a8484600085611164565b90505b9392505050565b6060824710156111dc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610110565b843b61122a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610110565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611253919061176b565b60006040518083038185875af1925050503d8060008114611290576040519150601f19603f3d011682016040523d82523d6000602084013e611295565b606091505b50915091506112a58282866112b0565b979650505050505050565b606083156112bf57508161115d565b8251156112cf5782518084602001fd5b8160405162461bcd60e51b81526004016101109190611955565b73ffffffffffffffffffffffffffffffffffffffff8116811461130b57600080fd5b50565b60008083601f84011261132057600080fd5b50813567ffffffffffffffff81111561133857600080fd5b60208301915083602082850101111561135057600080fd5b9250929050565b60008060008060006080868803121561136f57600080fd5b853561137a816112e9565b9450602086013561138a816112e9565b935060408601359250606086013567ffffffffffffffff8111156113ad57600080fd5b6113b98882890161130e565b969995985093965092949392505050565b600080604083850312156113dd57600080fd5b82356113e8816112e9565b915060208301356113f8816112e9565b809150509250929050565b803563ffffffff8116811461141757600080fd5b919050565b60008060008060008060a0878903121561143557600080fd5b8635611440816112e9565b95506020870135611450816112e9565b94506040870135935061146560608801611403565b9250608087013567ffffffffffffffff81111561148157600080fd5b61148d89828a0161130e565b979a9699509497509295939492505050565b600080600080600080600060c0888a0312156114ba57600080fd5b87356114c5816112e9565b965060208801356114d5816112e9565b955060408801356114e5816112e9565b9450606088013593506114fa60808901611403565b925060a088013567ffffffffffffffff81111561151657600080fd5b6115228a828b0161130e565b989b979a50959850939692959293505050565b6000806000806060858703121561154b57600080fd5b8435611556816112e9565b935061156460208601611403565b9250604085013567ffffffffffffffff81111561158057600080fd5b61158c8782880161130e565b95989497509550505050565b600080600080600080600060c0888a0312156115b357600080fd5b87356115be816112e9565b965060208801356115ce816112e9565b955060408801356115de816112e9565b945060608801356115ee816112e9565b93506080880135925060a088013567ffffffffffffffff81111561151657600080fd5b60008060006040848603121561162657600080fd5b61162f84611403565b9250602084013567ffffffffffffffff81111561164b57600080fd5b6116578682870161130e565b9497909650939450505050565b60005b8381101561167f578181015183820152602001611667565b838111156109315750506000910152565b600081518084526116a8816020860160208601611664565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261172960c0830184611690565b98975050505050505050565b82815260406020820152600061115a6040830184611690565b60006020828403121561176057600080fd5b815161115d816112e9565b6000825161177d818460208701611664565b9190910192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8381526040602082015260006117ea604083018486611787565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611834576118346117f3565b500390565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061186f606083018486611787565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006118a86060830185611690565b905063ffffffff83166040830152949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261190e60c083018486611787565b9998505050505050505050565b6000821982111561192e5761192e6117f3565b500190565b60006020828403121561194557600080fd5b8151801515811461115d57600080fd5b60208152600061115d602083018461169056fea2646970667358221220d862fb20d11a0a1fd01b325278c9f5c2c492f9915c195c3e0f9e8c458fdb424464736f6c63430008090033",
"deployedBytecode": "0x6080604052600436106100c05760003560e01c80638b4c40b0116100745780639a2ac6d51161004e5780639a2ac6d514610288578063a9f9e6751461029b578063b1a1a882146102bb57600080fd5b80638b4c40b0146101375780638f601f661461021557806391c49bf81461025b57600080fd5b8063485cc955116100a5578063485cc955146101b557806358a997f6146101d5578063838b2520146101f557600080fd5b80631532ec341461013e5780633cb747bf1461015e57600080fd5b3661013957333b156101195760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f41000000000000000000000000000000000060448201526064015b60405180910390fd5b610137333362030d40604051806020016040528060008152506102ce565b005b600080fd5b34801561014a57600080fd5b50610137610159366004611357565b61041a565b34801561016a57600080fd5b5060005461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101c157600080fd5b506101376101d03660046113ca565b610790565b3480156101e157600080fd5b506101376101f036600461141c565b61086f565b34801561020157600080fd5b5061013761021036600461149f565b6108d6565b34801561022157600080fd5b5061024d6102303660046113ca565b600260209081526000928352604080842090915290825290205481565b6040519081526020016101ac565b34801561026757600080fd5b5060015461018b9073ffffffffffffffffffffffffffffffffffffffff1681565b610137610296366004611535565b6108ef565b3480156102a757600080fd5b506101376102b6366004611598565b610937565b6101376102c9366004611611565b610c59565b600063662a633a60e01b600073deaddeaddeaddeaddeaddeaddeaddeaddead000087873487604051602401610308969594939291906116da565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506103ac9073ffffffffffffffffffffffffffffffffffffffff168483610cef565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f35d79ab81f2b2017e19afb5c5571778877782d7a8786f5907f93b0f4702f4f23348560405161040b929190611735565b60405180910390a35050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661045260005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104f25760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff1661052860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561056d57600080fd5b505afa158015610581573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a5919061174e565b73ffffffffffffffffffffffffffffffffffffffff161461062e5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff8716908690604051610665919061176b565b60006040518083038185875af1925050503d80600081146106a2576040519150601f19603f3d011682016040523d82523d6000602084013e6106a7565b606091505b505090508061071e5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c65640000000000000000000000006064820152608401610110565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2ac69ee804d9a7a0984249f508dfab7cb2534b465b6ce1580f99a38ba9c5e63187878760405161077f939291906117d0565b60405180910390a350505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff161561081c5760405162461bcd60e51b815260206004820152602660248201527f436f6e74726163742068617320616c7265616479206265656e20696e6974696160448201527f6c697a65642e00000000000000000000000000000000000000000000000000006064820152608401610110565b6000805473ffffffffffffffffffffffffffffffffffffffff9384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560018054929093169116179055565b333b156108be5760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b6108ce8686333388888888610d77565b505050505050565b6108e68787338888888888610d77565b50505050505050565b61093133858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b50505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661096f60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a0f5760405162461bcd60e51b815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e746963617465640000000000000000000000000000000000006064820152608401610110565b8073ffffffffffffffffffffffffffffffffffffffff16610a4560005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8a57600080fd5b505afa158015610a9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac2919061174e565b73ffffffffffffffffffffffffffffffffffffffff1614610b4b5760405162461bcd60e51b815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610110565b73ffffffffffffffffffffffffffffffffffffffff8089166000908152600260209081526040808320938b1683529290522054610b89908590611822565b73ffffffffffffffffffffffffffffffffffffffff808a166000818152600260209081526040808320948d1683529390529190912091909155610bcd908686610f27565b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167f3ceee06c1e37648fcbb6ed52e17b3e1f275a1f8c7b22a84b2b84732431e046b388888888604051610c479493929190611839565b60405180910390a45050505050505050565b333b15610ca85760405162461bcd60e51b815260206004820152600f60248201527f4163636f756e74206e6f7420454f4100000000000000000000000000000000006044820152606401610110565b610cea33338585858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102ce92505050565b505050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610d4990869085908790600401611879565b600060405180830381600087803b158015610d6357600080fd5b505af11580156108e6573d6000803e3d6000fd5b610d9973ffffffffffffffffffffffffffffffffffffffff8916873087610ffb565b600063662a633a60e01b89898989898888604051602401610dc097969594939291906118be565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152600154909150610e649073ffffffffffffffffffffffffffffffffffffffff168583610cef565b73ffffffffffffffffffffffffffffffffffffffff808a166000908152600260209081526040808320938c1683529290522054610ea290869061191b565b73ffffffffffffffffffffffffffffffffffffffff808b1660008181526002602090815260408083208e86168085529252918290209490945551918a1692917f718594027abd4eaed59f95162563e0cc6d0e8d5b86b1c7be8b1b0ac3343d039690610f14908b908b908a908a90611839565b60405180910390a4505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610cea9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611059565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109319085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610f79565b60006110bb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661114b9092919063ffffffff16565b805190915015610cea57808060200190518101906110d99190611933565b610cea5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610110565b606061115a8484600085611164565b90505b9392505050565b6060824710156111dc5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610110565b843b61122a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610110565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611253919061176b565b60006040518083038185875af1925050503d8060008114611290576040519150601f19603f3d011682016040523d82523d6000602084013e611295565b606091505b50915091506112a58282866112b0565b979650505050505050565b606083156112bf57508161115d565b8251156112cf5782518084602001fd5b8160405162461bcd60e51b81526004016101109190611955565b73ffffffffffffffffffffffffffffffffffffffff8116811461130b57600080fd5b50565b60008083601f84011261132057600080fd5b50813567ffffffffffffffff81111561133857600080fd5b60208301915083602082850101111561135057600080fd5b9250929050565b60008060008060006080868803121561136f57600080fd5b853561137a816112e9565b9450602086013561138a816112e9565b935060408601359250606086013567ffffffffffffffff8111156113ad57600080fd5b6113b98882890161130e565b969995985093965092949392505050565b600080604083850312156113dd57600080fd5b82356113e8816112e9565b915060208301356113f8816112e9565b809150509250929050565b803563ffffffff8116811461141757600080fd5b919050565b60008060008060008060a0878903121561143557600080fd5b8635611440816112e9565b95506020870135611450816112e9565b94506040870135935061146560608801611403565b9250608087013567ffffffffffffffff81111561148157600080fd5b61148d89828a0161130e565b979a9699509497509295939492505050565b600080600080600080600060c0888a0312156114ba57600080fd5b87356114c5816112e9565b965060208801356114d5816112e9565b955060408801356114e5816112e9565b9450606088013593506114fa60808901611403565b925060a088013567ffffffffffffffff81111561151657600080fd5b6115228a828b0161130e565b989b979a50959850939692959293505050565b6000806000806060858703121561154b57600080fd5b8435611556816112e9565b935061156460208601611403565b9250604085013567ffffffffffffffff81111561158057600080fd5b61158c8782880161130e565b95989497509550505050565b600080600080600080600060c0888a0312156115b357600080fd5b87356115be816112e9565b965060208801356115ce816112e9565b955060408801356115de816112e9565b945060608801356115ee816112e9565b93506080880135925060a088013567ffffffffffffffff81111561151657600080fd5b60008060006040848603121561162657600080fd5b61162f84611403565b9250602084013567ffffffffffffffff81111561164b57600080fd5b6116578682870161130e565b9497909650939450505050565b60005b8381101561167f578181015183820152602001611667565b838111156109315750506000910152565b600081518084526116a8816020860160208601611664565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff80891683528088166020840152808716604084015280861660608401525083608083015260c060a083015261172960c0830184611690565b98975050505050505050565b82815260406020820152600061115a6040830184611690565b60006020828403121561176057600080fd5b815161115d816112e9565b6000825161177d818460208701611664565b9190910192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b8381526040602082015260006117ea604083018486611787565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015611834576118346117f3565b500390565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061186f606083018486611787565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260006118a86060830185611690565b905063ffffffff83166040830152949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a083015261190e60c083018486611787565b9998505050505050505050565b6000821982111561192e5761192e6117f3565b500190565b60006020828403121561194557600080fd5b8151801515811461115d57600080fd5b60208152600061115d602083018461169056fea2646970667358221220d862fb20d11a0a1fd01b325278c9f5c2c492f9915c195c3e0f9e8c458fdb424464736f6c63430008090033",
"devdoc": {
"details": "The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits and listening to it for newly finalized withdrawals. Runtime target: EVM",
"kind": "dev",
"methods": {
"depositERC20(address,address,uint256,uint32,bytes)": {
"details": "deposit an amount of the ERC20 to the caller's balance on L2.",
"params": {
"_amount": "Amount of the ERC20 to deposit",
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l1Token": "Address of the L1 ERC20 we are depositing",
"_l2Gas": "Gas limit required to complete the deposit on L2.",
"_l2Token": "Address of the L1 respective L2 ERC20"
}
},
"depositERC20To(address,address,address,uint256,uint32,bytes)": {
"details": "deposit an amount of ERC20 to a recipient's balance on L2.",
"params": {
"_amount": "Amount of the ERC20 to deposit.",
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l1Token": "Address of the L1 ERC20 we are depositing",
"_l2Gas": "Gas limit required to complete the deposit on L2.",
"_l2Token": "Address of the L1 respective L2 ERC20",
"_to": "L2 address to credit the withdrawal to."
}
},
"depositETH(uint32,bytes)": {
"details": "Deposit an amount of the ETH to the caller's balance on L2.",
"params": {
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l2Gas": "Gas limit required to complete the deposit on L2."
}
},
"depositETHTo(address,uint32,bytes)": {
"details": "Deposit an amount of ETH to a recipient's balance on L2.",
"params": {
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_l2Gas": "Gas limit required to complete the deposit on L2.",
"_to": "L2 address to credit the withdrawal to."
}
},
"donateETH()": {
"details": "Adds ETH balance to the account. This is meant to allow for ETH to be migrated from an old gateway to a new gateway. NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the old contract"
},
"finalizeERC20Withdrawal(address,address,address,address,uint256,bytes)": {
"details": "Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ERC20 token. This call will fail if the initialized withdrawal from L2 has not been finalized.",
"params": {
"_amount": "Amount of the ERC20 to deposit.",
"_data": "Data provided by the sender on L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_from": "L2 address initiating the transfer.",
"_l1Token": "Address of L1 token to finalizeWithdrawal for.",
"_l2Token": "Address of L2 token where withdrawal was initiated.",
"_to": "L1 address to credit the withdrawal to."
}
},
"finalizeETHWithdrawal(address,address,uint256,bytes)": {
"details": "Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called before the withdrawal is finalized.",
"params": {
"_amount": "Amount of the ERC20 to deposit.",
"_data": "Optional data to forward to L2. This data is provided solely as a convenience for external contracts. Aside from enforcing a maximum length, these contracts provide no guarantees about its content.",
"_from": "L2 address initiating the transfer.",
"_to": "L1 address to credit the withdrawal to."
}
},
"initialize(address,address)": {
"params": {
"_l1messenger": "L1 Messenger address being used for cross-chain communications.",
"_l2TokenBridge": "L2 standard bridge address."
}
}
},
"stateVariables": {
"l2TokenBridge": {
"details": "get the address of the corresponding L2 bridge contract.",
"return": "Address of the corresponding L2 bridge contract.",
"returns": {
"_0": "Address of the corresponding L2 bridge contract."
}
}
},
"title": "L1StandardBridge",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 6180,
"contract": "contracts/L1/messaging/L1StandardBridge.sol:L1StandardBridge",
"label": "messenger",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 2874,
"contract": "contracts/L1/messaging/L1StandardBridge.sol:L1StandardBridge",
"label": "l2TokenBridge",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 2880,
"contract": "contracts/L1/messaging/L1StandardBridge.sol:L1StandardBridge",
"label": "deposits",
"offset": 0,
"slot": "2",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_mapping(t_address,t_uint256))": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => mapping(address => uint256))",
"numberOfBytes": "32",
"value": "t_mapping(t_address,t_uint256)"
},
"t_mapping(t_address,t_uint256)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => uint256)",
"numberOfBytes": "32",
"value": "t_uint256"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"indexed": false,
"internalType": "address",
"name": "_newAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "_oldAddress",
"type": "address"
}
],
"name": "AddressSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "getAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "address",
"name": "_address",
"type": "address"
}
],
"name": "setAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x8803c67a0032b8dea6b0e3a9d2ff1708346a41a8d2945d4e84e5d81862f1cb54",
"receipt": {
"to": null,
"from": "0x9996571372066A1545D3435C6935e3F9593A7eF5",
"contractAddress": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"transactionIndex": 43,
"gasUsed": "425357",
"logsBloom": "0x00800000002000000000000000000000000000000000000000800000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000001000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000040000000000000000000000000000000000000000000",
"blockHash": "0x6eeca8dcaa51370f0048dcc0569ebb0c62ba9841e5414b362aa15915c29428d1",
"transactionHash": "0x8803c67a0032b8dea6b0e3a9d2ff1708346a41a8d2945d4e84e5d81862f1cb54",
"logs": [
{
"transactionIndex": 43,
"blockNumber": 12686687,
"transactionHash": "0x8803c67a0032b8dea6b0e3a9d2ff1708346a41a8d2945d4e84e5d81862f1cb54",
"address": "0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000009996571372066a1545d3435c6935e3f9593a7ef5"
],
"data": "0x",
"logIndex": 195,
"blockHash": "0x6eeca8dcaa51370f0048dcc0569ebb0c62ba9841e5414b362aa15915c29428d1"
}
],
"blockNumber": 12686687,
"cumulativeGasUsed": "6131161",
"status": 1,
"byzantium": true
},
"args": [],
"solcInputHash": "ef3f334bac4d7e77d91b457a0d89ab0a",
"metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_newAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_oldAddress\",\"type\":\"address\"}],\"name\":\"AddressSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_address\",\"type\":\"address\"}],\"name\":\"setAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getAddress(string)\":{\"params\":{\"_name\":\"Name to retrieve an address for.\"},\"returns\":{\"_0\":\"Address associated with the given name.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setAddress(string,address)\":{\"params\":{\"_address\":\"Address to associate with the name.\",\"_name\":\"String name to associate an address with.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Lib_AddressManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAddress(string)\":{\"notice\":\"Retrieves the address associated with a given name.\"},\"setAddress(string,address)\":{\"notice\":\"Changes the address associated with a particular name.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":\"Lib_AddressManager\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x15e2d5bd4c28a88548074c54d220e8086f638a71ed07e6b3ba5a70066fcf458d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(\\n string indexed _name,\\n address _newAddress,\\n address _oldAddress\\n );\\n\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping (bytes32 => address) private addresses;\\n\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(\\n string memory _name,\\n address _address\\n )\\n external\\n onlyOwner\\n {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(\\n _name,\\n _address,\\n oldAddress\\n );\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(\\n string memory _name\\n )\\n external\\n view\\n returns (\\n address\\n )\\n {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(\\n string memory _name\\n )\\n internal\\n pure\\n returns (\\n bytes32\\n )\\n {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0x636defb785a5c6650d101def6790d9104724cc7570e0d875138624d069eed257\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50600061001b61006a565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35061006e565b3390565b6106478061007d6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c5780638da5cb5b146100665780639b2ea4bd1461008a578063bf40fac11461013b578063f2fde38b146101e1575b600080fd5b610064610207565b005b61006e6102c5565b604080516001600160a01b039092168252519081900360200190f35b610064600480360360408110156100a057600080fd5b8101906020810181356401000000008111156100bb57600080fd5b8201836020820111156100cd57600080fd5b803590602001918460018302840111640100000000831117156100ef57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506102d49050565b61006e6004803603602081101561015157600080fd5b81019060208101813564010000000081111561016c57600080fd5b82018360208201111561017e57600080fd5b803590602001918460018302840111640100000000831117156101a057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061042d945050505050565b610064600480360360208110156101f757600080fd5b50356001600160a01b031661045c565b61020f610570565b6001600160a01b03166102206102c5565b6001600160a01b03161461027b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6102dc610570565b6001600160a01b03166102ed6102c5565b6001600160a01b031614610348576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600061035383610574565b60008181526001602090815260409182902080546001600160a01b038781166001600160a01b0319831617909255925187519495509216928692918291908401908083835b602083106103b75780518252601f199092019160209182019101610398565b51815160001960209485036101000a01908116901991909116179052604080519490920184900384206001600160a01b03808b16865288169185019190915281519095507f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c94509283900301919050a250505050565b60006001600061043c84610574565b81526020810191909152604001600020546001600160a01b031692915050565b610464610570565b6001600160a01b03166104756102c5565b6001600160a01b0316146104d0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166105155760405162461bcd60e51b81526004018080602001828103825260268152602001806105ec6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6000816040516020018082805190602001908083835b602083106105a95780518252601f19909201916020918201910161058a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905091905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220b47b03a0c984a0faed73425d34ee172acb8f5010c64751f78c7f645cf8dc2aad64736f6c63430007060033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c5780638da5cb5b146100665780639b2ea4bd1461008a578063bf40fac11461013b578063f2fde38b146101e1575b600080fd5b610064610207565b005b61006e6102c5565b604080516001600160a01b039092168252519081900360200190f35b610064600480360360408110156100a057600080fd5b8101906020810181356401000000008111156100bb57600080fd5b8201836020820111156100cd57600080fd5b803590602001918460018302840111640100000000831117156100ef57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506102d49050565b61006e6004803603602081101561015157600080fd5b81019060208101813564010000000081111561016c57600080fd5b82018360208201111561017e57600080fd5b803590602001918460018302840111640100000000831117156101a057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061042d945050505050565b610064600480360360208110156101f757600080fd5b50356001600160a01b031661045c565b61020f610570565b6001600160a01b03166102206102c5565b6001600160a01b03161461027b576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6102dc610570565b6001600160a01b03166102ed6102c5565b6001600160a01b031614610348576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600061035383610574565b60008181526001602090815260409182902080546001600160a01b038781166001600160a01b0319831617909255925187519495509216928692918291908401908083835b602083106103b75780518252601f199092019160209182019101610398565b51815160001960209485036101000a01908116901991909116179052604080519490920184900384206001600160a01b03808b16865288169185019190915281519095507f9416a153a346f93d95f94b064ae3f148b6460473c6e82b3f9fc2521b873fcd6c94509283900301919050a250505050565b60006001600061043c84610574565b81526020810191909152604001600020546001600160a01b031692915050565b610464610570565b6001600160a01b03166104756102c5565b6001600160a01b0316146104d0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166105155760405162461bcd60e51b81526004018080602001828103825260268152602001806105ec6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6000816040516020018082805190602001908083835b602083106105a95780518252601f19909201916020918201910161058a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905091905056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a2646970667358221220b47b03a0c984a0faed73425d34ee172acb8f5010c64751f78c7f645cf8dc2aad64736f6c63430007060033",
"devdoc": {
"kind": "dev",
"methods": {
"getAddress(string)": {
"params": {
"_name": "Name to retrieve an address for."
},
"returns": {
"_0": "Address associated with the given name."
}
},
"owner()": {
"details": "Returns the address of the current owner."
},
"renounceOwnership()": {
"details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
},
"setAddress(string,address)": {
"params": {
"_address": "Address to associate with the name.",
"_name": "String name to associate an address with."
}
},
"transferOwnership(address)": {
"details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
}
},
"title": "Lib_AddressManager",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getAddress(string)": {
"notice": "Retrieves the address associated with a given name."
},
"setAddress(string,address)": {
"notice": "Changes the address associated with a particular name."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 664,
"contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 15229,
"contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol:Lib_AddressManager",
"label": "addresses",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_bytes32,t_address)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_bytes32": {
"encoding": "inplace",
"label": "bytes32",
"numberOfBytes": "32"
},
"t_mapping(t_bytes32,t_address)": {
"encoding": "mapping",
"key": "t_bytes32",
"label": "mapping(bytes32 => address)",
"numberOfBytes": "32",
"value": "t_address"
}
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_libAddressManager",
"type": "address"
},
{
"internalType": "string",
"name": "_implementationName",
"type": "string"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"stateMutability": "payable",
"type": "fallback"
}
],
"transactionHash": "0x3061bc0332ef45e8809cee450c3c487eba2520084c71ff38da85459aee6b9a1d",
"receipt": {
"to": null,
"from": "0x9996571372066A1545D3435C6935e3F9593A7eF5",
"contractAddress": "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1",
"transactionIndex": 153,
"gasUsed": "225024",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xd4ac3db2a7b6711dabac13ef84b398e86c647e5a24f0ffdd3458b3c66ab6cef1",
"transactionHash": "0x3061bc0332ef45e8809cee450c3c487eba2520084c71ff38da85459aee6b9a1d",
"logs": [],
"blockNumber": 12686757,
"cumulativeGasUsed": "11815865",
"status": 1,
"byzantium": true
},
"args": [
"0xdE1FCfB0851916CA5101820A69b13a4E276bd81F",
"OVM_L1CrossDomainMessenger"
],
"solcInputHash": "ef3f334bac4d7e77d91b457a0d89ab0a",
"metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_libAddressManager\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_implementationName\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_implementationName\":\"implementationName of the contract to proxy to.\",\"_libAddressManager\":\"Address of the Lib_AddressManager.\"}}},\"title\":\"Lib_ResolvedDelegateProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":\"Lib_ResolvedDelegateProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x15e2d5bd4c28a88548074c54d220e8086f638a71ed07e6b3ba5a70066fcf458d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_AddressManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* External Imports */\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title Lib_AddressManager\\n */\\ncontract Lib_AddressManager is Ownable {\\n\\n /**********\\n * Events *\\n **********/\\n\\n event AddressSet(\\n string indexed _name,\\n address _newAddress,\\n address _oldAddress\\n );\\n\\n\\n /*************\\n * Variables *\\n *************/\\n\\n mapping (bytes32 => address) private addresses;\\n\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Changes the address associated with a particular name.\\n * @param _name String name to associate an address with.\\n * @param _address Address to associate with the name.\\n */\\n function setAddress(\\n string memory _name,\\n address _address\\n )\\n external\\n onlyOwner\\n {\\n bytes32 nameHash = _getNameHash(_name);\\n address oldAddress = addresses[nameHash];\\n addresses[nameHash] = _address;\\n\\n emit AddressSet(\\n _name,\\n _address,\\n oldAddress\\n );\\n }\\n\\n /**\\n * Retrieves the address associated with a given name.\\n * @param _name Name to retrieve an address for.\\n * @return Address associated with the given name.\\n */\\n function getAddress(\\n string memory _name\\n )\\n external\\n view\\n returns (\\n address\\n )\\n {\\n return addresses[_getNameHash(_name)];\\n }\\n\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Computes the hash of a name.\\n * @param _name Name to compute a hash for.\\n * @return Hash of the given name.\\n */\\n function _getNameHash(\\n string memory _name\\n )\\n internal\\n pure\\n returns (\\n bytes32\\n )\\n {\\n return keccak256(abi.encodePacked(_name));\\n }\\n}\\n\",\"keccak256\":\"0x636defb785a5c6650d101def6790d9104724cc7570e0d875138624d069eed257\",\"license\":\"MIT\"},\"contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/* Library Imports */\\nimport { Lib_AddressManager } from \\\"./Lib_AddressManager.sol\\\";\\n\\n/**\\n * @title Lib_ResolvedDelegateProxy\\n */\\ncontract Lib_ResolvedDelegateProxy {\\n\\n /*************\\n * Variables *\\n *************/\\n\\n // Using mappings to store fields to avoid overwriting storage slots in the\\n // implementation contract. For example, instead of storing these fields at\\n // storage slot `0` & `1`, they are stored at `keccak256(key + slot)`.\\n // See: https://solidity.readthedocs.io/en/v0.7.0/internals/layout_in_storage.html\\n // NOTE: Do not use this code in your own contract system.\\n // There is a known flaw in this contract, and we will remove it from the repository\\n // in the near future. Due to the very limited way that we are using it, this flaw is\\n // not an issue in our system.\\n mapping (address => string) private implementationName;\\n mapping (address => Lib_AddressManager) private addressManager;\\n\\n\\n /***************\\n * Constructor *\\n ***************/\\n\\n /**\\n * @param _libAddressManager Address of the Lib_AddressManager.\\n * @param _implementationName implementationName of the contract to proxy to.\\n */\\n constructor(\\n address _libAddressManager,\\n string memory _implementationName\\n ) {\\n addressManager[address(this)] = Lib_AddressManager(_libAddressManager);\\n implementationName[address(this)] = _implementationName;\\n }\\n\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback()\\n external\\n payable\\n {\\n address target = addressManager[address(this)].getAddress(\\n (implementationName[address(this)])\\n );\\n\\n require(\\n target != address(0),\\n \\\"Target address must be initialized.\\\"\\n );\\n\\n (bool success, bytes memory returndata) = target.delegatecall(msg.data);\\n\\n if (success == true) {\\n assembly {\\n return(add(returndata, 0x20), mload(returndata))\\n }\\n } else {\\n assembly {\\n revert(add(returndata, 0x20), mload(returndata))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfaecb051b37f1d87d588cafb17a575723cbdf7c3c2079772110f33e747e05027\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b506040516104083803806104088339818101604052604081101561003357600080fd5b81516020830180516040519294929383019291908464010000000082111561005a57600080fd5b90830190602082018581111561006f57600080fd5b825164010000000081118282018810171561008957600080fd5b82525081516020918201929091019080838360005b838110156100b657818101518382015260200161009e565b50505050905090810190601f1680156100e35780820380516001836020036101000a031916815260200191505b5060409081523060009081526001602090815282822080546001600160a01b0319166001600160a01b038a16179055818152919020855161012c95509093509085019150610134565b5050506101d5565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261016a57600085556101b0565b82601f1061018357805160ff19168380011785556101b0565b828001600101855582156101b0579182015b828111156101b0578251825591602001919060010190610195565b506101bc9291506101c0565b5090565b5b808211156101bc57600081556001016101c1565b610224806101e46000396000f3fe60806040818152306000908152600160208181528383205483825293832063bf40fac160e01b909552608490815284546002610100938216159390930260001901169190910460a481905291936001600160a01b039093169263bf40fac192909190819060c490849080156100b55780601f1061008a576101008083540402835291602001916100b5565b820191906000526020600020905b81548152906001019060200180831161009857829003601f168201915b50509250505060206040518083038186803b1580156100d357600080fd5b505afa1580156100e7573d6000803e3d6000fd5b505050506040513d60208110156100fd57600080fd5b505190506001600160a01b0381166101465760405162461bcd60e51b81526004018080602001828103825260238152602001806101cc6023913960400191505060405180910390fd5b600080826001600160a01b03166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101a5576040519150601f19603f3d011682016040523d82523d6000602084013e6101aa565b606091505b509092509050600182151514156101c357805160208201f35b805160208201fdfe5461726765742061646472657373206d75737420626520696e697469616c697a65642ea2646970667358221220d96dd78b72a44c11bfa8efb98d29ee53776a02c67052599da176325fcbf95b6464736f6c63430007060033",
"deployedBytecode": "0x60806040818152306000908152600160208181528383205483825293832063bf40fac160e01b909552608490815284546002610100938216159390930260001901169190910460a481905291936001600160a01b039093169263bf40fac192909190819060c490849080156100b55780601f1061008a576101008083540402835291602001916100b5565b820191906000526020600020905b81548152906001019060200180831161009857829003601f168201915b50509250505060206040518083038186803b1580156100d357600080fd5b505afa1580156100e7573d6000803e3d6000fd5b505050506040513d60208110156100fd57600080fd5b505190506001600160a01b0381166101465760405162461bcd60e51b81526004018080602001828103825260238152602001806101cc6023913960400191505060405180910390fd5b600080826001600160a01b03166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101a5576040519150601f19603f3d011682016040523d82523d6000602084013e6101aa565b606091505b509092509050600182151514156101c357805160208201f35b805160208201fdfe5461726765742061646472657373206d75737420626520696e697469616c697a65642ea2646970667358221220d96dd78b72a44c11bfa8efb98d29ee53776a02c67052599da176325fcbf95b6464736f6c63430007060033",
"devdoc": {
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_implementationName": "implementationName of the contract to proxy to.",
"_libAddressManager": "Address of the Lib_AddressManager."
}
}
},
"title": "Lib_ResolvedDelegateProxy",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 15340,
"contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy",
"label": "implementationName",
"offset": 0,
"slot": "0",
"type": "t_mapping(t_address,t_string_storage)"
},
{
"astId": 15344,
"contract": "contracts/optimistic-ethereum/libraries/resolver/Lib_ResolvedDelegateProxy.sol:Lib_ResolvedDelegateProxy",
"label": "addressManager",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_address,t_contract(Lib_AddressManager)15296)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_contract(Lib_AddressManager)15296": {
"encoding": "inplace",
"label": "contract Lib_AddressManager",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_contract(Lib_AddressManager)15296)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => contract Lib_AddressManager)",
"numberOfBytes": "32",
"value": "t_contract(Lib_AddressManager)15296"
},
"t_mapping(t_address,t_string_storage)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => string)",
"numberOfBytes": "32",
"value": "t_string_storage"
},
"t_string_storage": {
"encoding": "bytes",
"label": "string",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"address": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"stateMutability": "payable",
"type": "fallback"
},
{
"inputs": [],
"name": "getImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getOwner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_code",
"type": "bytes"
}
],
"name": "setCode",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "_key",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_value",
"type": "bytes32"
}
],
"name": "setStorage",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x3fb736def76e27e507bc4e451e5498f1f1beee3e82e6aa67ecef434c638a04ac",
"receipt": {
"to": null,
"from": "0x9996571372066A1545D3435C6935e3F9593A7eF5",
"contractAddress": "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1",
"transactionIndex": 70,
"gasUsed": "471232",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xb6578d9e60cce4713437b5cf0898dd7040c9284e178aadfb7dfbb590f4f083af",
"transactionHash": "0x3fb736def76e27e507bc4e451e5498f1f1beee3e82e6aa67ecef434c638a04ac",
"logs": [],
"blockNumber": 12686786,
"cumulativeGasUsed": "6551653",
"status": 1,
"byzantium": true
},
"args": [
"0x9996571372066A1545D3435C6935e3F9593A7eF5"
],
"solcInputHash": "7531d7762a77038a37e7490a7b4b176f",
"metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"getImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"setCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_value\",\"type\":\"bytes32\"}],\"name\":\"setStorage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_owner\":\"Address of the initial contract owner.\"}},\"getImplementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"getOwner()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"setCode(bytes)\":{\"params\":{\"_code\":\"New contract code to run inside this contract.\"}},\"setOwner(address)\":{\"params\":{\"_owner\":\"New owner of the proxy contract.\"}},\"setStorage(bytes32,bytes32)\":{\"params\":{\"_key\":\"Storage key to modify.\",\"_value\":\"New value for the storage key.\"}}},\"title\":\"L1ChugSplashProxy\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getImplementation()\":{\"notice\":\"Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"getOwner()\":{\"notice\":\"Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \\\"from\\\" address to address(0).\"},\"setCode(bytes)\":{\"notice\":\"Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner.\"},\"setOwner(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"setStorage(bytes32,bytes32)\":{\"notice\":\"Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":\"L1ChugSplashProxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/chugsplash/L1ChugSplashProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\nimport { iL1ChugSplashDeployer } from \\\"./interfaces/iL1ChugSplashDeployer.sol\\\";\\n\\n/**\\n * @title L1ChugSplashProxy\\n * @dev Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added\\n * functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty!\\n *\\n * Note for future developers: do NOT make anything in this contract 'public' unless you know what\\n * you're doing. Anything public can potentially have a function signature that conflicts with a\\n * signature attached to the implementation contract. Public functions SHOULD always have the\\n * 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that\\n * modifier. And there almost certainly is not a good reason to not have that modifier. Beware!\\n */\\ncontract L1ChugSplashProxy {\\n\\n /*************\\n * Constants *\\n *************/\\n\\n // \\\"Magic\\\" prefix. When prepended to some arbitrary bytecode and used to create a contract, the\\n // appended bytecode will be deployed as given.\\n bytes13 constant internal DEPLOY_CODE_PREFIX = 0x600D380380600D6000396000f3;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n bytes32 constant internal IMPLEMENTATION_KEY = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n bytes32 constant internal OWNER_KEY = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n\\n /***************\\n * Constructor *\\n ***************/\\n \\n /**\\n * @param _owner Address of the initial contract owner.\\n */\\n constructor(\\n address _owner\\n ) {\\n _setOwner(_owner);\\n }\\n\\n\\n /**********************\\n * Function Modifiers *\\n **********************/\\n\\n /**\\n * Blocks a function from being called when the parent signals that the system should be paused\\n * via an isUpgrading function.\\n */\\n modifier onlyWhenNotPaused() {\\n address owner = _getOwner();\\n\\n // We do a low-level call because there's no guarantee that the owner actually *is* an\\n // L1ChugSplashDeployer contract and Solidity will throw errors if we do a normal call and\\n // it turns out that it isn't the right type of contract.\\n (bool success, bytes memory returndata) = owner.staticcall(\\n abi.encodeWithSelector(\\n iL1ChugSplashDeployer.isUpgrading.selector\\n )\\n );\\n\\n // If the call was unsuccessful then we assume that there's no \\\"isUpgrading\\\" method and we\\n // can just continue as normal. We also expect that the return value is exactly 32 bytes\\n // long. If this isn't the case then we can safely ignore the result.\\n if (success && returndata.length == 32) {\\n // Although the expected value is a *boolean*, it's safer to decode as a uint256 in the\\n // case that the isUpgrading function returned something other than 0 or 1. But we only\\n // really care about the case where this value is 0 (= false).\\n uint256 ret = abi.decode(returndata, (uint256));\\n require(\\n ret == 0,\\n \\\"L1ChugSplashProxy: system is currently being upgraded\\\"\\n );\\n }\\n\\n _;\\n }\\n\\n /**\\n * Makes a proxy call instead of triggering the given function when the caller is either the\\n * owner or the zero address. Caller can only ever be the zero address if this function is\\n * being called off-chain via eth_call, which is totally fine and can be convenient for\\n * client-side tooling. Avoids situations where the proxy and implementation share a sighash\\n * and the proxy function ends up being called instead of the implementation one.\\n *\\n * Note: msg.sender == address(0) can ONLY be triggered off-chain via eth_call. If there's a\\n * way for someone to send a transaction with msg.sender == address(0) in any real context then\\n * we have much bigger problems. Primary reason to include this additional allowed sender is\\n * because the owner address can be changed dynamically and we do not want clients to have to\\n * keep track of the current owner in order to make an eth_call that doesn't trigger the\\n * proxied contract.\\n */\\n modifier proxyCallIfNotOwner() {\\n if (msg.sender == _getOwner() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n\\n /*********************\\n * Fallback Function *\\n *********************/\\n\\n fallback()\\n external\\n payable\\n {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n\\n /********************\\n * Public Functions *\\n ********************/\\n\\n /**\\n * Sets the code that should be running behind this proxy. Note that this scheme is a bit\\n * different from the standard proxy scheme where one would typically deploy the code\\n * separately and then set the implementation address. We're doing it this way because it gives\\n * us a lot more freedom on the client side. Can only be triggered by the contract owner.\\n * @param _code New contract code to run inside this contract.\\n */\\n function setCode(\\n bytes memory _code\\n )\\n proxyCallIfNotOwner\\n public\\n {\\n // Get the code hash of the current implementation.\\n address implementation = _getImplementation();\\n\\n // If the code hash matches the new implementation then we return early.\\n if (keccak256(_code) == _getAccountCodeHash(implementation)) {\\n return;\\n }\\n\\n // Create the deploycode by appending the magic prefix.\\n bytes memory deploycode = abi.encodePacked(\\n DEPLOY_CODE_PREFIX,\\n _code\\n );\\n\\n // Deploy the code and set the new implementation address.\\n address newImplementation;\\n assembly {\\n newImplementation := create(0x0, add(deploycode, 0x20), mload(deploycode))\\n }\\n\\n // Check that the code was actually deployed correctly. I'm not sure if you can ever\\n // actually fail this check. Should only happen if the contract creation from above runs\\n // out of gas but this parent execution thread does NOT run out of gas. Seems like we\\n // should be doing this check anyway though.\\n require(\\n _getAccountCodeHash(newImplementation) == keccak256(_code),\\n \\\"L1ChugSplashProxy: code was not correctly deployed.\\\"\\n );\\n\\n _setImplementation(newImplementation);\\n }\\n\\n /**\\n * Modifies some storage slot within the proxy contract. Gives us a lot of power to perform\\n * upgrades in a more transparent way. Only callable by the owner.\\n * @param _key Storage key to modify.\\n * @param _value New value for the storage key.\\n */\\n function setStorage(\\n bytes32 _key,\\n bytes32 _value\\n )\\n proxyCallIfNotOwner\\n public\\n {\\n assembly {\\n sstore(_key, _value)\\n }\\n }\\n\\n /**\\n * Changes the owner of the proxy contract. Only callable by the owner.\\n * @param _owner New owner of the proxy contract.\\n */\\n function setOwner(\\n address _owner\\n )\\n proxyCallIfNotOwner\\n public\\n {\\n _setOwner(_owner);\\n }\\n\\n /**\\n * Queries the owner of the proxy contract. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Owner address.\\n */\\n function getOwner()\\n proxyCallIfNotOwner\\n public\\n returns (\\n address\\n )\\n {\\n return _getOwner();\\n }\\n\\n /**\\n * Queries the implementation address. Can only be called by the owner OR by making an\\n * eth_call and setting the \\\"from\\\" address to address(0).\\n * @return Implementation address.\\n */\\n function getImplementation()\\n proxyCallIfNotOwner\\n public\\n returns (\\n address\\n )\\n {\\n return _getImplementation();\\n }\\n\\n\\n /**********************\\n * Internal Functions *\\n **********************/\\n\\n /**\\n * Sets the implementation address.\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(\\n address _implementation\\n )\\n internal\\n {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n }\\n\\n /**\\n * Queries the implementation address.\\n * @return Implementation address.\\n */\\n function _getImplementation()\\n internal\\n view\\n returns (\\n address\\n )\\n {\\n address implementation;\\n assembly {\\n implementation := sload(IMPLEMENTATION_KEY)\\n }\\n return implementation;\\n }\\n\\n /**\\n * Changes the owner of the proxy contract.\\n * @param _owner New owner of the proxy contract.\\n */\\n function _setOwner(\\n address _owner\\n )\\n internal\\n {\\n assembly {\\n sstore(OWNER_KEY, _owner)\\n }\\n }\\n\\n /**\\n * Queries the owner of the proxy contract.\\n * @return Owner address.\\n */\\n function _getOwner()\\n internal\\n view \\n returns (\\n address\\n )\\n {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n\\n /**\\n * Gets the code hash for a given account.\\n * @param _account Address of the account to get a code hash for.\\n * @return Code hash for the account.\\n */\\n function _getAccountCodeHash(\\n address _account\\n )\\n internal\\n view\\n returns (\\n bytes32\\n )\\n {\\n bytes32 codeHash;\\n assembly {\\n codeHash := extcodehash(_account)\\n }\\n return codeHash;\\n }\\n\\n /**\\n * Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall()\\n onlyWhenNotPaused\\n internal\\n {\\n address implementation = _getImplementation();\\n\\n require(\\n implementation != address(0),\\n \\\"L1ChugSplashProxy: implementation is not set yet\\\"\\n );\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), implementation, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n \\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0x654af4f1d1aab76467c49fcce992eaf3522040ed806d656d98735c50ac235eeb\",\"license\":\"MIT\"},\"contracts/chugsplash/interfaces/iL1ChugSplashDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >0.5.0 <0.8.0;\\n\\n/**\\n * @title iL1ChugSplashDeployer\\n */\\ninterface iL1ChugSplashDeployer {\\n function isUpgrading()\\n external\\n view\\n returns (\\n bool\\n );\\n}\\n\",\"keccak256\":\"0xdab3ecb1ce03376523cd2f2ce5f991389c388829c56907987da01d99d3fc44c7\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b506040516107983803806107988339818101604052602081101561003357600080fd5b505161003e81610044565b50610068565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b610721806100776000396000f3fe60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610087578063893d20e81461013a5780639b0b0fda1461016b578063aaf10f421461019b575b6100526101b0565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661036c565b34801561009357600080fd5b50610052600480360360208110156100aa57600080fd5b8101906020810181356401000000008111156100c557600080fd5b8201836020820111156100d757600080fd5b803590602001918460018302840111640100000000831117156100f957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103af945050505050565b34801561014657600080fd5b5061014f610505565b604080516001600160a01b039092168252519081900360200190f35b34801561017757600080fd5b506100526004803603604081101561018e57600080fd5b508035906020013561054b565b3480156101a757600080fd5b5061014f610589565b60006101ba6105bd565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b1781529151815193945060009384936001600160a01b0387169392918291908083835b602083106102215780518252601f199092019160209182019101610202565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610281576040519150601f19603f3d011682016040523d82523d6000602084013e610286565b606091505b5091509150818015610299575080516020145b156102f85760008180602001905160208110156102b557600080fd5b5051905080156102f65760405162461bcd60e51b81526004018080602001828103825260358152602001806106b76035913960400191505060405180910390fd5b505b60006103026105e2565b90506001600160a01b0381166103495760405162461bcd60e51b81526004018080602001828103825260308152602001806106546030913960400191505060405180910390fd5b3660008037600080366000845af43d6000803e80610366573d6000fd5b503d6000f35b6103746105bd565b6001600160a01b0316336001600160a01b03161480610391575033155b156103a45761039f81610607565b6103ac565b6103ac6101b0565b50565b6103b76105bd565b6001600160a01b0316336001600160a01b031614806103d4575033155b156103a45760006103e36105e2565b90506103ee8161062b565b825160208401201415610401575061039f565b60006c600d380380600d6000396000f360981b83604051602001808372ffffffffffffffffffffffffffffffffffffff19168152600d0182805190602001908083835b602083106104635780518252601f199092019160209182019101610444565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905060008151602083016000f0905083805190602001206104b88261062b565b146104f45760405162461bcd60e51b81526004018080602001828103825260338152602001806106846033913960400191505060405180910390fd5b6104fd8161062f565b5050506103ac565b600061050f6105bd565b6001600160a01b0316336001600160a01b0316148061052c575033155b15610540576105396105bd565b9050610548565b6105486101b0565b90565b6105536105bd565b6001600160a01b0316336001600160a01b03161480610570575033155b1561057d57808255610585565b6105856101b0565b5050565b60006105936105bd565b6001600160a01b0316336001600160a01b031614806105b0575033155b15610540576105396105e2565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3f90565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe4c314368756753706c61736850726f78793a20696d706c656d656e746174696f6e206973206e6f7420736574207965744c314368756753706c61736850726f78793a20636f646520776173206e6f7420636f72726563746c79206465706c6f7965642e4c314368756753706c61736850726f78793a2073797374656d2069732063757272656e746c79206265696e67207570677261646564a26469706673582212202e20c1d0062b5a698d49624edce72a713b117e88f4cd70877869b53519c1d1f964736f6c63430007060033",
"deployedBytecode": "0x60806040526004361061004a5760003560e01c806313af4035146100545780636c5d4ad014610087578063893d20e81461013a5780639b0b0fda1461016b578063aaf10f421461019b575b6100526101b0565b005b34801561006057600080fd5b506100526004803603602081101561007757600080fd5b50356001600160a01b031661036c565b34801561009357600080fd5b50610052600480360360208110156100aa57600080fd5b8101906020810181356401000000008111156100c557600080fd5b8201836020820111156100d757600080fd5b803590602001918460018302840111640100000000831117156100f957600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506103af945050505050565b34801561014657600080fd5b5061014f610505565b604080516001600160a01b039092168252519081900360200190f35b34801561017757600080fd5b506100526004803603604081101561018e57600080fd5b508035906020013561054b565b3480156101a757600080fd5b5061014f610589565b60006101ba6105bd565b60408051600481526024810182526020810180516001600160e01b0316635bca393160e11b1781529151815193945060009384936001600160a01b0387169392918291908083835b602083106102215780518252601f199092019160209182019101610202565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610281576040519150601f19603f3d011682016040523d82523d6000602084013e610286565b606091505b5091509150818015610299575080516020145b156102f85760008180602001905160208110156102b557600080fd5b5051905080156102f65760405162461bcd60e51b81526004018080602001828103825260358152602001806106b76035913960400191505060405180910390fd5b505b60006103026105e2565b90506001600160a01b0381166103495760405162461bcd60e51b81526004018080602001828103825260308152602001806106546030913960400191505060405180910390fd5b3660008037600080366000845af43d6000803e80610366573d6000fd5b503d6000f35b6103746105bd565b6001600160a01b0316336001600160a01b03161480610391575033155b156103a45761039f81610607565b6103ac565b6103ac6101b0565b50565b6103b76105bd565b6001600160a01b0316336001600160a01b031614806103d4575033155b156103a45760006103e36105e2565b90506103ee8161062b565b825160208401201415610401575061039f565b60006c600d380380600d6000396000f360981b83604051602001808372ffffffffffffffffffffffffffffffffffffff19168152600d0182805190602001908083835b602083106104635780518252601f199092019160209182019101610444565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052905060008151602083016000f0905083805190602001206104b88261062b565b146104f45760405162461bcd60e51b81526004018080602001828103825260338152602001806106846033913960400191505060405180910390fd5b6104fd8161062f565b5050506103ac565b600061050f6105bd565b6001600160a01b0316336001600160a01b0316148061052c575033155b15610540576105396105bd565b9050610548565b6105486101b0565b90565b6105536105bd565b6001600160a01b0316336001600160a01b03161480610570575033155b1561057d57808255610585565b6105856101b0565b5050565b60006105936105bd565b6001600160a01b0316336001600160a01b031614806105b0575033155b15610540576105396105e2565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355565b3f90565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5556fe4c314368756753706c61736850726f78793a20696d706c656d656e746174696f6e206973206e6f7420736574207965744c314368756753706c61736850726f78793a20636f646520776173206e6f7420636f72726563746c79206465706c6f7965642e4c314368756753706c61736850726f78793a2073797374656d2069732063757272656e746c79206265696e67207570677261646564a26469706673582212202e20c1d0062b5a698d49624edce72a713b117e88f4cd70877869b53519c1d1f964736f6c63430007060033",
"devdoc": {
"details": "Basic ChugSplash proxy contract for L1. Very close to being a normal proxy but has added functions `setCode` and `setStorage` for changing the code or storage of the contract. Nifty! Note for future developers: do NOT make anything in this contract 'public' unless you know what you're doing. Anything public can potentially have a function signature that conflicts with a signature attached to the implementation contract. Public functions SHOULD always have the 'proxyCallIfNotOwner' modifier unless there's some *really* good reason not to have that modifier. And there almost certainly is not a good reason to not have that modifier. Beware!",
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_owner": "Address of the initial contract owner."
}
},
"getImplementation()": {
"returns": {
"_0": "Implementation address."
}
},
"getOwner()": {
"returns": {
"_0": "Owner address."
}
},
"setCode(bytes)": {
"params": {
"_code": "New contract code to run inside this contract."
}
},
"setOwner(address)": {
"params": {
"_owner": "New owner of the proxy contract."
}
},
"setStorage(bytes32,bytes32)": {
"params": {
"_key": "Storage key to modify.",
"_value": "New value for the storage key."
}
}
},
"title": "L1ChugSplashProxy",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getImplementation()": {
"notice": "Queries the implementation address. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)."
},
"getOwner()": {
"notice": "Queries the owner of the proxy contract. Can only be called by the owner OR by making an eth_call and setting the \"from\" address to address(0)."
},
"setCode(bytes)": {
"notice": "Sets the code that should be running behind this proxy. Note that this scheme is a bit different from the standard proxy scheme where one would typically deploy the code separately and then set the implementation address. We're doing it this way because it gives us a lot more freedom on the client side. Can only be triggered by the contract owner."
},
"setOwner(address)": {
"notice": "Changes the owner of the proxy contract. Only callable by the owner."
},
"setStorage(bytes32,bytes32)": {
"notice": "Modifies some storage slot within the proxy contract. Gives us a lot of power to perform upgrades in a more transparent way. Only callable by the owner."
}
},
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC",
"abi": [
{
"inputs": [
{
"internalType": "uint256",
"name": "_minDepositAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_maxDepositAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_maxBalance",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "balance",
"type": "uint256"
}
],
"name": "BalanceWithdrawn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "depositId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "emitter",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "EtherReceived",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "previousBalance",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newBalance",
"type": "uint256"
}
],
"name": "MaxBalanceSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "previousAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newAmount",
"type": "uint256"
}
],
"name": "MaxDepositAmountSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "previousAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newAmount",
"type": "uint256"
}
],
"name": "MinDepositAmountSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [],
"name": "maxBalance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxDepositAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "minDepositAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_maxDepositAmount",
"type": "uint256"
}
],
"name": "setMaxAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_maxBalance",
"type": "uint256"
}
],
"name": "setMaxBalance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_minDepositAmount",
"type": "uint256"
}
],
"name": "setMinAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalDeposits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdrawBalance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0xb63a08a31db0fb45bf48836d0941dd30b094870905f838ee3c3ff237374edeaf",
"receipt": {
"to": null,
"from": "0xe07E50264CD86EC96a22C930f3581EFb46bA3A34",
"contractAddress": "0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC",
"transactionIndex": 284,
"gasUsed": "690034",
"logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800200000000000000200000000004000400000000000000000000000000000000040000000000000000000000000000000000000040000000000000000000000000000000000020000000000000000000000000000000008000200000001000000400000000020000000000000000020000002000000000000000000000000008000000000000000000000000000020000",
"blockHash": "0xec5b8ac652db0c4eabeb18672080e7810982020558a38de0169b44a9efeffd9b",
"transactionHash": "0xb63a08a31db0fb45bf48836d0941dd30b094870905f838ee3c3ff237374edeaf",
"logs": [
{
"transactionIndex": 284,
"blockNumber": 14595007,
"transactionHash": "0xb63a08a31db0fb45bf48836d0941dd30b094870905f838ee3c3ff237374edeaf",
"address": "0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x000000000000000000000000e07e50264cd86ec96a22c930f3581efb46ba3a34"
],
"data": "0x",
"logIndex": 306,
"blockHash": "0xec5b8ac652db0c4eabeb18672080e7810982020558a38de0169b44a9efeffd9b"
},
{
"transactionIndex": 284,
"blockNumber": 14595007,
"transactionHash": "0xb63a08a31db0fb45bf48836d0941dd30b094870905f838ee3c3ff237374edeaf",
"address": "0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC",
"topics": [
"0x65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005af3107a4000",
"logIndex": 307,
"blockHash": "0xec5b8ac652db0c4eabeb18672080e7810982020558a38de0169b44a9efeffd9b"
},
{
"transactionIndex": 284,
"blockNumber": 14595007,
"transactionHash": "0xb63a08a31db0fb45bf48836d0941dd30b094870905f838ee3c3ff237374edeaf",
"address": "0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC",
"topics": [
"0xb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797"
],
"data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000",
"logIndex": 308,
"blockHash": "0xec5b8ac652db0c4eabeb18672080e7810982020558a38de0169b44a9efeffd9b"
},
{
"transactionIndex": 284,
"blockNumber": 14595007,
"transactionHash": "0xb63a08a31db0fb45bf48836d0941dd30b094870905f838ee3c3ff237374edeaf",
"address": "0x52ec2F3d7C5977A8E558C8D9C6000B615098E8fC",
"topics": [
"0x185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003635c9adc5dea00000",
"logIndex": 309,
"blockHash": "0xec5b8ac652db0c4eabeb18672080e7810982020558a38de0169b44a9efeffd9b"
}
],
"blockNumber": 14595007,
"cumulativeGasUsed": "18549106",
"status": 1,
"byzantium": true
},
"args": [
"100000000000000",
"1000000000000000000",
"1000000000000000000000"
],
"solcInputHash": "ad04ab9565e42a9370aa7f055041028d",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxDepositAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxBalance\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"BalanceWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"emitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EtherReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"MaxBalanceSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newAmount\",\"type\":\"uint256\"}],\"name\":\"MaxDepositAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newAmount\",\"type\":\"uint256\"}],\"name\":\"MinDepositAmountSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"maxBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minDepositAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxDepositAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxBalance\",\"type\":\"uint256\"}],\"name\":\"setMaxBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_minDepositAmount\",\"type\":\"uint256\"}],\"name\":\"setMinAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalDeposits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawBalance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"BalanceWithdrawn(address,uint256)\":{\"params\":{\"balance\":\"The current contract balance paid to the owner.\",\"owner\":\"The current owner and recipient of the funds.\"}},\"EtherReceived(uint256,address,uint256)\":{\"params\":{\"amount\":\"The amount deposited by the payer.\",\"depositId\":\"A unique sequencer number identifying the deposit.\",\"emitter\":\"The sending address of the payer.\"}},\"MaxBalanceSet(uint256,uint256)\":{\"params\":{\"newBalance\":\"The new maximum contract balance.\",\"previousBalance\":\"The previous maximum contract balance.\"}},\"MaxDepositAmountSet(uint256,uint256)\":{\"params\":{\"newAmount\":\"The new maximum deposit amount.\",\"previousAmount\":\"The previous maximum deposit amount.\"}},\"MinDepositAmountSet(uint256,uint256)\":{\"params\":{\"newAmount\":\"The new minimum deposit amount.\",\"previousAmount\":\"The previous minimum deposit amount.\"}}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_maxBalance\":\"The initial maximum contract balance.\",\"_maxDepositAmount\":\"The initial maximum deposit amount.\",\"_minDepositAmount\":\"The initial minimum deposit amount.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setMaxAmount(uint256)\":{\"params\":{\"_maxDepositAmount\":\"The new maximum deposit amount.\"}},\"setMaxBalance(uint256)\":{\"params\":{\"_maxBalance\":\"The new maximum contract balance.\"}},\"setMinAmount(uint256)\":{\"params\":{\"_minDepositAmount\":\"The new minimum deposit amount.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"TeleportrDeposit Shout out to 0xclem for providing the inspiration for this contract: https://github.com/0xclem/teleportr/blob/main/contracts/BridgeDeposit.sol\",\"version\":1},\"userdoc\":{\"events\":{\"BalanceWithdrawn(address,uint256)\":{\"notice\":\"Emitted any time the balance is withdrawn by the owner.\"},\"EtherReceived(uint256,address,uint256)\":{\"notice\":\"Emitted any time a successful deposit is received.\"},\"MaxBalanceSet(uint256,uint256)\":{\"notice\":\"Emitted any time the contract maximum balance is set.\"},\"MaxDepositAmountSet(uint256,uint256)\":{\"notice\":\"Emitted any time the maximum deposit amount is set.\"},\"MinDepositAmountSet(uint256,uint256)\":{\"notice\":\"Emitted any time the minimum deposit amount is set.\"}},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Initializes a new TeleportrDeposit contract.\"},\"maxBalance()\":{\"notice\":\"The maximum balance the contract can hold after a receive.\"},\"maxDepositAmount()\":{\"notice\":\"The maximum amount that be deposited in a receive.\"},\"minDepositAmount()\":{\"notice\":\"The minimum amount that be deposited in a receive.\"},\"setMaxAmount(uint256)\":{\"notice\":\"Sets the maximum amount that can be deposited in a receive.\"},\"setMaxBalance(uint256)\":{\"notice\":\"Sets the maximum balance the contract can hold after a receive.\"},\"setMinAmount(uint256)\":{\"notice\":\"Sets the minimum amount that can be deposited in a receive.\"},\"totalDeposits()\":{\"notice\":\"The total number of successful deposits received.\"},\"withdrawBalance()\":{\"notice\":\"Sends the contract's current balance to the owner.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/L1/teleportr/TeleportrDeposit.sol\":\"TeleportrDeposit\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/L1/teleportr/TeleportrDeposit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.9;\\n\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/**\\n * @title TeleportrDeposit\\n *\\n * Shout out to 0xclem for providing the inspiration for this contract:\\n * https://github.com/0xclem/teleportr/blob/main/contracts/BridgeDeposit.sol\\n */\\ncontract TeleportrDeposit is Ownable {\\n /// The minimum amount that be deposited in a receive.\\n uint256 public minDepositAmount;\\n /// The maximum amount that be deposited in a receive.\\n uint256 public maxDepositAmount;\\n /// The maximum balance the contract can hold after a receive.\\n uint256 public maxBalance;\\n /// The total number of successful deposits received.\\n uint256 public totalDeposits;\\n\\n /**\\n * @notice Emitted any time the minimum deposit amount is set.\\n * @param previousAmount The previous minimum deposit amount.\\n * @param newAmount The new minimum deposit amount.\\n */\\n event MinDepositAmountSet(uint256 previousAmount, uint256 newAmount);\\n\\n /**\\n * @notice Emitted any time the maximum deposit amount is set.\\n * @param previousAmount The previous maximum deposit amount.\\n * @param newAmount The new maximum deposit amount.\\n */\\n event MaxDepositAmountSet(uint256 previousAmount, uint256 newAmount);\\n\\n /**\\n * @notice Emitted any time the contract maximum balance is set.\\n * @param previousBalance The previous maximum contract balance.\\n * @param newBalance The new maximum contract balance.\\n */\\n event MaxBalanceSet(uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @notice Emitted any time the balance is withdrawn by the owner.\\n * @param owner The current owner and recipient of the funds.\\n * @param balance The current contract balance paid to the owner.\\n */\\n event BalanceWithdrawn(address indexed owner, uint256 balance);\\n\\n /**\\n * @notice Emitted any time a successful deposit is received.\\n * @param depositId A unique sequencer number identifying the deposit.\\n * @param emitter The sending address of the payer.\\n * @param amount The amount deposited by the payer.\\n */\\n event EtherReceived(uint256 indexed depositId, address indexed emitter, uint256 indexed amount);\\n\\n /**\\n * @notice Initializes a new TeleportrDeposit contract.\\n * @param _minDepositAmount The initial minimum deposit amount.\\n * @param _maxDepositAmount The initial maximum deposit amount.\\n * @param _maxBalance The initial maximum contract balance.\\n */\\n constructor(\\n uint256 _minDepositAmount,\\n uint256 _maxDepositAmount,\\n uint256 _maxBalance\\n ) {\\n minDepositAmount = _minDepositAmount;\\n maxDepositAmount = _maxDepositAmount;\\n maxBalance = _maxBalance;\\n totalDeposits = 0;\\n emit MinDepositAmountSet(0, _minDepositAmount);\\n emit MaxDepositAmountSet(0, _maxDepositAmount);\\n emit MaxBalanceSet(0, _maxBalance);\\n }\\n\\n /**\\n * @notice Accepts deposits that will be disbursed to the sender's address on L2.\\n * The method reverts if the amount is less than the current\\n * minDepositAmount, the amount is greater than the current\\n * maxDepositAmount, or the amount causes the contract to exceed its maximum\\n * allowed balance.\\n */\\n receive() external payable {\\n require(msg.value >= minDepositAmount, \\\"Deposit amount is too small\\\");\\n require(msg.value <= maxDepositAmount, \\\"Deposit amount is too big\\\");\\n require(address(this).balance <= maxBalance, \\\"Contract max balance exceeded\\\");\\n\\n emit EtherReceived(totalDeposits, msg.sender, msg.value);\\n unchecked {\\n totalDeposits += 1;\\n }\\n }\\n\\n /**\\n * @notice Sends the contract's current balance to the owner.\\n */\\n function withdrawBalance() external onlyOwner {\\n address _owner = owner();\\n uint256 _balance = address(this).balance;\\n emit BalanceWithdrawn(_owner, _balance);\\n payable(_owner).transfer(_balance);\\n }\\n\\n /**\\n * @notice Sets the minimum amount that can be deposited in a receive.\\n * @param _minDepositAmount The new minimum deposit amount.\\n */\\n function setMinAmount(uint256 _minDepositAmount) external onlyOwner {\\n emit MinDepositAmountSet(minDepositAmount, _minDepositAmount);\\n minDepositAmount = _minDepositAmount;\\n }\\n\\n /**\\n * @notice Sets the maximum amount that can be deposited in a receive.\\n * @param _maxDepositAmount The new maximum deposit amount.\\n */\\n function setMaxAmount(uint256 _maxDepositAmount) external onlyOwner {\\n emit MaxDepositAmountSet(maxDepositAmount, _maxDepositAmount);\\n maxDepositAmount = _maxDepositAmount;\\n }\\n\\n /**\\n * @notice Sets the maximum balance the contract can hold after a receive.\\n * @param _maxBalance The new maximum contract balance.\\n */\\n function setMaxBalance(uint256 _maxBalance) external onlyOwner {\\n emit MaxBalanceSet(maxBalance, _maxBalance);\\n maxBalance = _maxBalance;\\n }\\n}\\n\",\"keccak256\":\"0x86af035f651f8d2d9b3acd8048d63ec95037c1411de9bd086c82afc6d9790a9d\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50604051610b4a380380610b4a83398101604081905261002f91610153565b61003833610103565b6001839055600282905560038190556000600481905560408051918252602082018590527f65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f910160405180910390a16040805160008152602081018490527fb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797910160405180910390a16040805160008152602081018390527f185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b910160405180910390a1505050610181565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060006060848603121561016857600080fd5b8351925060208401519150604084015190509250925092565b6109ba806101906000396000f3fe6080604052600436106100c05760003560e01c80637d882097116100745780638ed832711161004e5780638ed83271146103445780639d51d9b71461035a578063f2fde38b1461037a57600080fd5b80637d882097146102d9578063897b0637146102ef5780638da5cb5b1461030f57600080fd5b8063645006ca116100a5578063645006ca14610285578063715018a6146102ae57806373ad468a146102c357600080fd5b80634fe47f701461024e5780635fd8c7101461027057600080fd5b3661024957600154341015610136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4465706f73697420616d6f756e7420697320746f6f20736d616c6c000000000060448201526064015b60405180910390fd5b6002543411156101a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4465706f73697420616d6f756e7420697320746f6f2062696700000000000000604482015260640161012d565b60035447111561020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f436f6e7472616374206d61782062616c616e6365206578636565646564000000604482015260640161012d565b600454604051349133917f2d27851832fcac28a0d4af1344f01fed7ffcfd15171c14c564a0c42aa57ae5c090600090a4600480546001019055005b600080fd5b34801561025a57600080fd5b5061026e61026936600461092e565b61039a565b005b34801561027c57600080fd5b5061026e61045c565b34801561029157600080fd5b5061029b60015481565b6040519081526020015b60405180910390f35b3480156102ba57600080fd5b5061026e610578565b3480156102cf57600080fd5b5061029b60035481565b3480156102e557600080fd5b5061029b60045481565b3480156102fb57600080fd5b5061026e61030a36600461092e565b610605565b34801561031b57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102a5565b34801561035057600080fd5b5061029b60025481565b34801561036657600080fd5b5061026e61037536600461092e565b6106c7565b34801561038657600080fd5b5061026e610395366004610947565b610789565b60005473ffffffffffffffffffffffffffffffffffffffff16331461041b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b60025460408051918252602082018390527fb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797910160405180910390a1600255565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b6000546040805147808252915173ffffffffffffffffffffffffffffffffffffffff9093169283917fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f1919081900360200190a260405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610573573d6000803e3d6000fd5b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b61060360006108b9565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b60015460408051918252602082018390527f65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f910160405180910390a1600155565b60005473ffffffffffffffffffffffffffffffffffffffff163314610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b60035460408051918252602082018390527f185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b910160405180910390a1600355565b60005473ffffffffffffffffffffffffffffffffffffffff16331461080a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b73ffffffffffffffffffffffffffffffffffffffff81166108ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161012d565b6108b6816108b9565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561094057600080fd5b5035919050565b60006020828403121561095957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461097d57600080fd5b939250505056fea2646970667358221220b610d8106720e33f96db31f8c5c4f9cecb50144a2cf1e4049ac0216cd47d0eff64736f6c63430008090033",
"deployedBytecode": "0x6080604052600436106100c05760003560e01c80637d882097116100745780638ed832711161004e5780638ed83271146103445780639d51d9b71461035a578063f2fde38b1461037a57600080fd5b80637d882097146102d9578063897b0637146102ef5780638da5cb5b1461030f57600080fd5b8063645006ca116100a5578063645006ca14610285578063715018a6146102ae57806373ad468a146102c357600080fd5b80634fe47f701461024e5780635fd8c7101461027057600080fd5b3661024957600154341015610136576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4465706f73697420616d6f756e7420697320746f6f20736d616c6c000000000060448201526064015b60405180910390fd5b6002543411156101a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4465706f73697420616d6f756e7420697320746f6f2062696700000000000000604482015260640161012d565b60035447111561020e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f436f6e7472616374206d61782062616c616e6365206578636565646564000000604482015260640161012d565b600454604051349133917f2d27851832fcac28a0d4af1344f01fed7ffcfd15171c14c564a0c42aa57ae5c090600090a4600480546001019055005b600080fd5b34801561025a57600080fd5b5061026e61026936600461092e565b61039a565b005b34801561027c57600080fd5b5061026e61045c565b34801561029157600080fd5b5061029b60015481565b6040519081526020015b60405180910390f35b3480156102ba57600080fd5b5061026e610578565b3480156102cf57600080fd5b5061029b60035481565b3480156102e557600080fd5b5061029b60045481565b3480156102fb57600080fd5b5061026e61030a36600461092e565b610605565b34801561031b57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102a5565b34801561035057600080fd5b5061029b60025481565b34801561036657600080fd5b5061026e61037536600461092e565b6106c7565b34801561038657600080fd5b5061026e610395366004610947565b610789565b60005473ffffffffffffffffffffffffffffffffffffffff16331461041b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b60025460408051918252602082018390527fb1e6cc560df1786578fd4d1fe6e046f089a0c3be401e999b51a5112437911797910160405180910390a1600255565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b6000546040805147808252915173ffffffffffffffffffffffffffffffffffffffff9093169283917fddc398b321237a8d40ac914388309c2f52a08c134e4dc4ce61e32f57cb7d80f1919081900360200190a260405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610573573d6000803e3d6000fd5b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b61060360006108b9565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610686576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b60015460408051918252602082018390527f65779d3ca560e9bdec52d08ed75431a84df87cb7796f0e51965f6efc0f556c0f910160405180910390a1600155565b60005473ffffffffffffffffffffffffffffffffffffffff163314610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b60035460408051918252602082018390527f185c6391e7218e85de8a9346fc72024a0f88e1f04c186e6351230b93976ad50b910160405180910390a1600355565b60005473ffffffffffffffffffffffffffffffffffffffff16331461080a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161012d565b73ffffffffffffffffffffffffffffffffffffffff81166108ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161012d565b6108b6816108b9565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561094057600080fd5b5035919050565b60006020828403121561095957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461097d57600080fd5b939250505056fea2646970667358221220b610d8106720e33f96db31f8c5c4f9cecb50144a2cf1e4049ac0216cd47d0eff64736f6c63430008090033",
"devdoc": {
"events": {
"BalanceWithdrawn(address,uint256)": {
"params": {
"balance": "The current contract balance paid to the owner.",
"owner": "The current owner and recipient of the funds."
}
},
"EtherReceived(uint256,address,uint256)": {
"params": {
"amount": "The amount deposited by the payer.",
"depositId": "A unique sequencer number identifying the deposit.",
"emitter": "The sending address of the payer."
}
},
"MaxBalanceSet(uint256,uint256)": {
"params": {
"newBalance": "The new maximum contract balance.",
"previousBalance": "The previous maximum contract balance."
}
},
"MaxDepositAmountSet(uint256,uint256)": {
"params": {
"newAmount": "The new maximum deposit amount.",
"previousAmount": "The previous maximum deposit amount."
}
},
"MinDepositAmountSet(uint256,uint256)": {
"params": {
"newAmount": "The new minimum deposit amount.",
"previousAmount": "The previous minimum deposit amount."
}
}
},
"kind": "dev",
"methods": {
"constructor": {
"params": {
"_maxBalance": "The initial maximum contract balance.",
"_maxDepositAmount": "The initial maximum deposit amount.",
"_minDepositAmount": "The initial minimum deposit amount."
}
},
"owner()": {
"details": "Returns the address of the current owner."
},
"renounceOwnership()": {
"details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
},
"setMaxAmount(uint256)": {
"params": {
"_maxDepositAmount": "The new maximum deposit amount."
}
},
"setMaxBalance(uint256)": {
"params": {
"_maxBalance": "The new maximum contract balance."
}
},
"setMinAmount(uint256)": {
"params": {
"_minDepositAmount": "The new minimum deposit amount."
}
},
"transferOwnership(address)": {
"details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
}
},
"title": "TeleportrDeposit Shout out to 0xclem for providing the inspiration for this contract: https://github.com/0xclem/teleportr/blob/main/contracts/BridgeDeposit.sol",
"version": 1
},
"userdoc": {
"events": {
"BalanceWithdrawn(address,uint256)": {
"notice": "Emitted any time the balance is withdrawn by the owner."
},
"EtherReceived(uint256,address,uint256)": {
"notice": "Emitted any time a successful deposit is received."
},
"MaxBalanceSet(uint256,uint256)": {
"notice": "Emitted any time the contract maximum balance is set."
},
"MaxDepositAmountSet(uint256,uint256)": {
"notice": "Emitted any time the maximum deposit amount is set."
},
"MinDepositAmountSet(uint256,uint256)": {
"notice": "Emitted any time the minimum deposit amount is set."
}
},
"kind": "user",
"methods": {
"constructor": {
"notice": "Initializes a new TeleportrDeposit contract."
},
"maxBalance()": {
"notice": "The maximum balance the contract can hold after a receive."
},
"maxDepositAmount()": {
"notice": "The maximum amount that be deposited in a receive."
},
"minDepositAmount()": {
"notice": "The minimum amount that be deposited in a receive."
},
"setMaxAmount(uint256)": {
"notice": "Sets the maximum amount that can be deposited in a receive."
},
"setMaxBalance(uint256)": {
"notice": "Sets the maximum balance the contract can hold after a receive."
},
"setMinAmount(uint256)": {
"notice": "Sets the minimum amount that can be deposited in a receive."
},
"totalDeposits()": {
"notice": "The total number of successful deposits received."
},
"withdrawBalance()": {
"notice": "Sends the contract's current balance to the owner."
}
},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 393,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 5028,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "minDepositAmount",
"offset": 0,
"slot": "1",
"type": "t_uint256"
},
{
"astId": 5031,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "maxDepositAmount",
"offset": 0,
"slot": "2",
"type": "t_uint256"
},
{
"astId": 5034,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "maxBalance",
"offset": 0,
"slot": "3",
"type": "t_uint256"
},
{
"astId": 5037,
"contract": "contracts/L1/teleportr/TeleportrDeposit.sol:TeleportrDeposit",
"label": "totalDeposits",
"offset": 0,
"slot": "4",
"type": "t_uint256"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_uint256": {
"encoding": "inplace",
"label": "uint256",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
...@@ -107,7 +107,7 @@ const main = async () => { ...@@ -107,7 +107,7 @@ const main = async () => {
// Check the rest. // Check the rest.
for (const { check, error } of checks) { for (const { check, error } of checks) {
if (!check(element.name.split('_'))) { if (!check(element.name.split('_'))) {
errors.push(`${filepath} function ${element.name}: ${error}`) errors.push(`${filepath}#${element.name}: ${error}`)
success = false 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)
checks:
- name: eth-gas-reporter/codechecks
settings:
speculativeBranchSelection: false
branches:
- develop
- master
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0x9C6373dE60c2D3297b18A8f964618ac46E011B58',
l2ProxyOwnerAddress: '',
optimistName: '',
optimistSymbol: '',
optimistBaseUriAttestorAddress: '',
optimistInviterInviteGranter: '',
optimistInviterName: '',
optimistAllowlistAllowlistAttestor: '',
optimistAllowlistCoinbaseQuestAttestor: '',
}
export default config
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0x9C6373dE60c2D3297b18A8f964618ac46E011B58',
l2ProxyOwnerAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistName: 'Optimist',
optimistSymbol: 'OPTIMIST',
optimistBaseUriAttestorAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistInviterInviteGranter: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistInviterName: 'OptimistInviter',
optimistAllowlistAllowlistAttestor:
'0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistAllowlistCoinbaseQuestAttestor:
'0x661B7Acca8ebd93AFd349a088e9a9A00053DB1BF',
}
export default config
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
l2ProxyOwnerAddress: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
optimistName: 'OP Citizenship',
optimistSymbol: 'OPNFT',
optimistBaseUriAttestorAddress: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
optimistInviterInviteGranter: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
optimistInviterName: 'OptimistInviter',
optimistAllowlistAllowlistAttestor:
'0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
optimistAllowlistCoinbaseQuestAttestor:
'0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
}
export default config
import config from './hardhat'
// uses the same config as hardhat.ts
export default config
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0x9C6373dE60c2D3297b18A8f964618ac46E011B58',
l2ProxyOwnerAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistName: 'Optimist',
optimistSymbol: 'OPTIMIST',
optimistBaseUriAttestorAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistInviterInviteGranter: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistInviterName: 'OptimistInviter',
optimistAllowlistAllowlistAttestor:
'0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistAllowlistCoinbaseQuestAttestor:
'0x661B7Acca8ebd93AFd349a088e9a9A00053DB1BF',
}
export default config
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0x9C6373dE60c2D3297b18A8f964618ac46E011B58',
// EcoPod test account
l2ProxyOwnerAddress: '0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819',
optimistName: 'Optimist',
optimistSymbol: 'OPTIMIST',
optimistBaseUriAttestorAddress: '0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819',
optimistInviterInviteGranter: '0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819',
optimistInviterName: 'OptimistInviter',
optimistAllowlistAllowlistAttestor:
'0x8F0EBDaA1cF7106bE861753B0f9F5c0250fE0819',
optimistAllowlistCoinbaseQuestAttestor:
'0x9A75024c09b48B78205dfCf9D9FC5E026CD9A416',
}
export default config
import { DeployConfig } from '../../src'
const config: DeployConfig = {
ddd: '0x9C6373dE60c2D3297b18A8f964618ac46E011B58',
l2ProxyOwnerAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistName: 'Optimist',
optimistSymbol: 'OPTIMIST',
optimistBaseUriAttestorAddress: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistInviterInviteGranter: '0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistInviterName: 'OptimistInviter',
optimistAllowlistAllowlistAttestor:
'0x60c5C9c98bcBd0b0F2fD89B24c16e533BaA8CdA3',
optimistAllowlistCoinbaseQuestAttestor:
'0x661B7Acca8ebd93AFd349a088e9a9A00053DB1BF',
}
export default config
import { ethers } from 'ethers'
import { DrippieConfig } from '../../src'
const config: DrippieConfig = {
TeleportrWithdrawalV2: {
interval: 60 * 60 * 24,
dripcheck: 'CheckBalanceHigh',
checkparams: {
target: '0x52ec2f3d7c5977a8e558c8d9c6000b615098e8fc',
threshold: ethers.utils.parseEther('1'),
},
actions: [
{
target: '0x78A25524D90E3D0596558fb43789bD800a5c3007',
data: {
fn: 'withdrawFromTeleportr',
args: [],
},
},
],
},
GelatoBalance: {
interval: 60 * 60 * 24,
dripcheck: 'CheckGelatoLow',
checkparams: {
treasury: '0x2807B4aE232b624023f87d0e237A3B1bf200Fd99',
recipient: '0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
threshold: ethers.utils.parseEther('0.1'),
},
actions: [
{
target: '0x2807B4aE232b624023f87d0e237A3B1bf200Fd99',
value: ethers.utils.parseEther('1'),
data: {
fn: 'depositFunds',
args: [
// receiver
'0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
// token
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// amount
ethers.utils.parseEther('1'),
],
},
},
],
},
}
export default config
import { ethers } from 'ethers'
import { DrippieConfig, Time } from '../../src'
const config: DrippieConfig = {
BatcherBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0x7431310e026b69bfc676c0013e12a1a11411eec9',
threshold: ethers.utils.parseEther('50'),
},
actions: [
{
target: '0x7431310e026b69bfc676c0013e12a1a11411eec9',
value: ethers.utils.parseEther('100'),
},
],
},
ProposerBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0x02b1786a85ec3f71fbbba46507780db7cf9014f6',
threshold: ethers.utils.parseEther('50'),
},
actions: [
{
target: '0x02b1786a85ec3f71fbbba46507780db7cf9014f6',
value: ethers.utils.parseEther('100'),
},
],
},
GelatoBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckGelatoLow',
checkparams: {
treasury: '0xf381dfd7a139caab83c26140e5595c0b85ddadcd',
recipient: '0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
threshold: ethers.utils.parseEther('0.1'),
},
actions: [
{
target: '0xf381dfd7a139caab83c26140e5595c0b85ddadcd',
value: ethers.utils.parseEther('1'),
data: {
fn: 'depositFunds',
args: [
// receiver
'0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
// token
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// amount
ethers.utils.parseEther('1'),
],
},
},
],
},
}
export default config
import { ethers } from 'ethers'
import { DrippieConfig, Time } from '../../src'
const config: DrippieConfig = {
TeleportrWithdrawal: {
interval: 10 * Time.MINUTE,
dripcheck: 'CheckBalanceHigh',
checkparams: {
target: '0x4821975ca220601c153d02353300d6ad34adc362',
threshold: ethers.utils.parseEther('1'),
},
actions: [
{
target: '0x78A25524D90E3D0596558fb43789bD800a5c3007',
data: {
fn: 'withdrawFromTeleportr',
args: [],
},
},
],
},
GelatoBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckGelatoLow',
checkparams: {
treasury: '0x340759c8346A1E6Ed92035FB8B6ec57cE1D82c2c',
recipient: '0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
threshold: ethers.utils.parseEther('0.1'),
},
actions: [
{
target: '0x340759c8346A1E6Ed92035FB8B6ec57cE1D82c2c',
value: ethers.utils.parseEther('1'),
data: {
fn: 'depositFunds',
args: [
// receiver
'0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
// token
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// amount
ethers.utils.parseEther('1'),
],
},
},
],
},
}
export default config
import { ethers } from 'ethers'
import { DrippieConfig, Time } from '../../src'
const config: DrippieConfig = {
BatcherBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0x6887246668a3b87f54deb3b94ba47a6f63f32985',
threshold: ethers.utils.parseEther('75'),
},
actions: [
{
target: '0x6887246668a3b87f54deb3b94ba47a6f63f32985',
value: ethers.utils.parseEther('125'),
},
],
},
ProposerBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0x473300df21d047806a082244b417f96b32f13a33',
threshold: ethers.utils.parseEther('50'),
},
actions: [
{
target: '0x473300df21d047806a082244b417f96b32f13a33',
value: ethers.utils.parseEther('100'),
},
],
},
GelatoBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckGelatoLow',
checkparams: {
treasury: '0x2807B4aE232b624023f87d0e237A3B1bf200Fd99',
recipient: '0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
threshold: ethers.utils.parseEther('0.1'),
},
actions: [
{
target: '0x2807B4aE232b624023f87d0e237A3B1bf200Fd99',
value: ethers.utils.parseEther('1'),
data: {
fn: 'depositFunds',
args: [
// receiver
'0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
// token
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// amount
ethers.utils.parseEther('1'),
],
},
},
],
},
}
export default config
import { ethers } from 'ethers'
import { DrippieConfig, Time } from '../../src'
const config: DrippieConfig = {
GelatoBalance: {
interval: 1 * Time.DAY,
dripcheck: 'CheckGelatoLow',
checkparams: {
treasury: '0x527a819db1eb0e34426297b03bae11F2f8B3A19E',
recipient: '0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
threshold: ethers.utils.parseEther('0.1'),
},
actions: [
{
target: '0x527a819db1eb0e34426297b03bae11F2f8B3A19E',
value: ethers.utils.parseEther('1'),
data: {
fn: 'depositFunds',
args: [
// receiver
'0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5',
// token
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
// amount
ethers.utils.parseEther('1'),
],
},
},
],
},
TonyOptimismKovanFaucet: {
interval: 1 * Time.WEEK,
dripcheck: 'CheckBalanceLow',
checkparams: {
target: '0xa8019d6F7bC3008a0a708A422f223Ccb21b61eAD',
threshold: ethers.utils.parseEther('20'),
},
actions: [
{
target: '0xa8019d6F7bC3008a0a708A422f223Ccb21b61eAD',
value: ethers.utils.parseEther('100'),
},
],
},
}
export default config
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { Multicall3 } from "multicall/src/Multicall3.sol";
/**
* Just exists so we can compile this contract.
*/
contract MulticallContractCompiler {
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
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;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { ProxyAdmin } from "@eth-optimism/contracts-bedrock/contracts/universal/ProxyAdmin.sol";
import { Proxy } from "@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol";
/**
* Just exists so we can compile external contracts.
*/
contract ExternalContractCompiler {
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FailingReceiver {
receive() external payable {
require(false, "FailingReceiver");
}
}
//SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {
AdminFaucetAuthModule
} from "../../universal/faucet/authmodules/AdminFaucetAuthModule.sol";
import {
ECDSAUpgradeable
} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
/**
* 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));
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Reverter {
function doRevert() public pure {
revert("Reverter reverted");
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
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];
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
// 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);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { ERC20 } from "@rari-capital/solmate/src/tokens/ERC20.sol";
contract TestERC20 is ERC20 {
constructor() ERC20("TEST", "TST", 18) {}
function mint(address to, uint256 value) public {
_mint(to, value);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { ERC721 } from "@rari-capital/solmate/src/tokens/ERC721.sol";
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) {}
}
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic(
'PeripheryProxyAdmin',
{
contract: 'ProxyAdmin',
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['PeripheryProxyAdmin']
),
from: deployer,
args: [hre.deployConfig.ddd],
log: true,
}
)
await deploy()
}
deployFn.tags = ['PeripheryProxyAdmin']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic('AssetReceiver', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['RetroReceiver']),
from: deployer,
args: [hre.deployConfig.ddd],
log: true,
})
await deploy()
}
deployFn.tags = ['RetroReceiver']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic('Drippie', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['Drippie']),
from: deployer,
args: [hre.deployConfig.ddd],
log: true,
})
await deploy()
}
deployFn.tags = ['Drippie', 'DrippieEnvironment']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic('CheckBalanceHigh', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['CheckBalanceHigh']),
from: deployer,
log: true,
})
await deploy()
}
deployFn.tags = ['CheckBalanceHigh', 'DrippieEnvironment']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic('CheckBalanceLow', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['CheckBalanceLow']),
from: deployer,
log: true,
})
await deploy()
}
deployFn.tags = ['CheckBalanceLow', 'DrippieEnvironment']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic('CheckGelatoLow', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['CheckGelatoLow']),
from: deployer,
log: true,
})
await deploy()
}
deployFn.tags = ['CheckGelatoLow', 'DrippieEnvironment']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deploy } = await hre.deployments.deterministic('CheckTrue', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['CheckTrue']),
from: deployer,
log: true,
})
await deploy()
}
deployFn.tags = ['CheckTrue', 'DrippieEnvironment']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { deployer } = await hre.getNamedAccounts()
console.log(`Deploying AttestationStation with ${deployer}`)
const { deploy } = await hre.deployments.deterministic('AttestationStation', {
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['AttestationStation']
),
from: deployer,
args: [],
log: true,
})
await deploy()
const Deployment__AttestationStation = await hre.deployments.get(
'AttestationStation'
)
const addr = Deployment__AttestationStation.address
console.log(`AttestationStation deployed to ${addr}`)
}
deployFn.tags = ['AttestationStation', 'OptimistEnvironment']
export default deployFn
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { assertContractVariable } from '@eth-optimism/contracts-bedrock/src/deploy-utils'
import { ethers, utils } from 'ethers'
import type { DeployConfig } from '../../src'
const { getAddress } = utils
/**
* Deploys the AttestationStationProxy
*/
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
const { deployer } = await hre.getNamedAccounts()
const ddd = hre.deployConfig.ddd
if (getAddress(deployer) !== getAddress(ddd)) {
throw new Error('Must deploy with the ddd')
}
console.log(`Deploying AttestationStationProxy with ${deployer}`)
const Deployment__AttestationStation = await hre.deployments.get(
'AttestationStation'
)
const { deploy } = await hre.deployments.deterministic(
'AttestationStationProxy',
{
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['AttestationStationProxy']
),
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
}
)
await deploy()
const Deployment__AttestationStationProxy = await hre.deployments.get(
'AttestationStationProxy'
)
const addr = Deployment__AttestationStationProxy.address
console.log(`AttestationStationProxy deployed to ${addr}`)
console.log(
`Using AttestationStation implementation at ${Deployment__AttestationStation.address}`
)
const Proxy = await hre.ethers.getContractAt('Proxy', addr)
const AttestationStation = await hre.ethers.getContractAt(
'AttestationStation',
addr
)
const implementation = await Proxy.connect(
ethers.constants.AddressZero
).callStatic.implementation()
console.log(`implementation is set to ${implementation}`)
if (
getAddress(implementation) !==
getAddress(Deployment__AttestationStation.address)
) {
console.log('implementation not set to AttestationStation contract')
console.log(
`Setting implementation to ${Deployment__AttestationStation.address}`
)
const tx = await Proxy.upgradeTo(Deployment__AttestationStation.address)
const receipt = await tx.wait()
console.log(`implementation set in tx ${receipt.transactionHash}`)
} else {
console.log('implementation already set to AttestationStation contract')
}
const l2ProxyOwnerAddress = deployConfig.l2ProxyOwnerAddress
const admin = await Proxy.connect(
ethers.constants.AddressZero
).callStatic.admin()
console.log(`admin is set to ${admin}`)
if (getAddress(admin) !== getAddress(l2ProxyOwnerAddress)) {
console.log('admin not set correctly')
console.log(`Setting admin to ${l2ProxyOwnerAddress}`)
const tx = await Proxy.changeAdmin(l2ProxyOwnerAddress)
const receipt = await tx.wait()
console.log(`admin set in ${receipt.transactionHash}`)
} else {
console.log('admin already set to L2 Proxy Owner Address')
}
console.log('Contract deployment complete')
await assertContractVariable(Proxy, 'admin', l2ProxyOwnerAddress)
await assertContractVariable(AttestationStation, 'version', '1.1.0')
}
deployFn.tags = ['AttestationStationProxy', 'OptimistEnvironment']
deployFn.dependencies = ['AttestationStation']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
import type { DeployConfig } from '../../src'
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
const { deployer } = await hre.getNamedAccounts()
console.log(`Deploying OptimistAllowlist implementation with ${deployer}`)
const Deployment__AttestationStation = await hre.deployments.get(
'AttestationStationProxy'
)
const Deployment__OptimistInviter = await hre.deployments.get(
'OptimistInviterProxy'
)
const attestationStationAddress = Deployment__AttestationStation.address
const optimistInviterAddress = Deployment__OptimistInviter.address
console.log(`Using ${attestationStationAddress} as the ATTESTATION_STATION`)
console.log(
`Using ${deployConfig.optimistAllowlistAllowlistAttestor} as ALLOWLIST_ATTESTOR`
)
console.log(
`Using ${deployConfig.optimistAllowlistCoinbaseQuestAttestor} as COINBASE_QUEST_ATTESTOR`
)
console.log(`Using ${optimistInviterAddress} as OPTIMIST_INVITER`)
const { deploy } = await hre.deployments.deterministic('OptimistAllowlist', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['OptimistAllowlist']),
from: deployer,
args: [
attestationStationAddress,
deployConfig.optimistAllowlistAllowlistAttestor,
deployConfig.optimistAllowlistCoinbaseQuestAttestor,
optimistInviterAddress,
],
log: true,
})
await deploy()
}
deployFn.tags = ['OptimistAllowlistImpl', 'OptimistEnvironment']
deployFn.dependencies = ['AttestationStationProxy', 'OptimistInviterProxy']
export default deployFn
/* Imports: External */
import assert from 'assert'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { assertContractVariable } from '@eth-optimism/contracts-bedrock/src/deploy-utils'
import { ethers, utils } from 'ethers'
import type { DeployConfig } from '../../src'
import { setupProxyContract } from '../../src/helpers/setupProxyContract'
const { getAddress } = utils
// Required conditions before deploying - Specified in `deployFn.dependencies`
// - AttestationStationProxy is deployed and points to the correct implementation
// - OptimistInviterProxy is deployed and points to the correct implementation
// - OptimistAllowlistImpl is deployed
//
// Steps
// 1. Deploy OptimistAllowlistProxy
// 2. Point the newly deployed proxy to the implementation, if it hasn't been done already
// 3. Update the admin of the proxy to the l2ProxyOwnerAddress, if it hasn't been done already
// 4. Basic sanity checks for contract variables
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
// Deployer should be set in hardhat.config.ts
const { deployer } = await hre.getNamedAccounts()
// We want the ability to deploy to a deterministic address, so we need the init bytecode to be
// consistent across deployments. The ddd will quickly transfer the ownership of the Proxy to a
// multisig after deployment.
//
// We need a consistent ddd, since the Proxy takes a `_admin` constructor argument, which
// affects the init bytecode and hence deployed address.
const ddd = deployConfig.ddd
if (getAddress(deployer) !== getAddress(ddd)) {
// Not a hard requirement. We can deploy with any account and just set the `_admin` to the
// ddd, but requiring that the deployer is the same as the ddd minimizes number of hot wallets
// we need to keep track of during deployment.
throw new Error('Must deploy with the ddd')
}
// Get the up to date deployment of the OptimistAllowlist contract
const Deployment__OptimistAllowlistImpl = await hre.deployments.get(
'OptimistAllowlist'
)
console.log(`Deploying OptimistAllowlistProxy with ${deployer}`)
// Deploys the Proxy.sol contract with the `_admin` constructor param set to the ddd (=== deployer).
const { deploy } = await hre.deployments.deterministic(
'OptimistAllowlistProxy',
{
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['OptimistAllowlistProxy']
),
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
}
)
// Deploy the Proxy contract
await deploy()
const Deployment__OptimistAllowlistProxy = await hre.deployments.get(
'OptimistAllowlistProxy'
)
console.log(
`OptimistAllowlistProxy deployed to ${Deployment__OptimistAllowlistProxy.address}`
)
// Deployed Proxy.sol contract
const Proxy = await hre.ethers.getContractAt(
'Proxy',
Deployment__OptimistAllowlistProxy.address
)
// Deployed Proxy.sol contract with the OptimistAllowlist interface
const OptimistAllowlist = await hre.ethers.getContractAt(
'OptimistAllowlist',
Deployment__OptimistAllowlistProxy.address
)
// ethers.Signer for the ddd. Should be the current owner of the Proxy.
const dddSigner = await hre.ethers.provider.getSigner(deployer)
// intended admin of the Proxy
const l2ProxyOwnerAddress = deployConfig.l2ProxyOwnerAddress
// setup the Proxy contract with correct implementation and admin
await setupProxyContract(Proxy, dddSigner, {
targetImplAddress: Deployment__OptimistAllowlistImpl.address,
targetProxyOwnerAddress: l2ProxyOwnerAddress,
})
const Deployment__AttestationStationProxy = await hre.deployments.get(
'AttestationStationProxy'
)
const Deployment__OptimistInviter = await hre.deployments.get(
'OptimistInviterProxy'
)
await assert(
getAddress(
await Proxy.connect(ethers.constants.AddressZero).callStatic.admin()
) === getAddress(l2ProxyOwnerAddress)
)
await assertContractVariable(OptimistAllowlist, 'version', '1.0.0')
await assertContractVariable(
OptimistAllowlist,
'ATTESTATION_STATION',
Deployment__AttestationStationProxy.address
)
await assertContractVariable(
OptimistAllowlist,
'ALLOWLIST_ATTESTOR',
deployConfig.optimistAllowlistAllowlistAttestor
)
await assertContractVariable(
OptimistAllowlist,
'COINBASE_QUEST_ATTESTOR',
deployConfig.optimistAllowlistCoinbaseQuestAttestor
)
await assertContractVariable(
OptimistAllowlist,
'OPTIMIST_INVITER',
Deployment__OptimistInviter.address
)
}
deployFn.tags = ['OptimistAllowlistProxy', 'OptimistEnvironment']
deployFn.dependencies = [
'AttestationStationProxy',
'OptimistInviterProxy',
'OptimistAllowlistImpl',
]
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
import type { DeployConfig } from '../../src'
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
const { deployer } = await hre.getNamedAccounts()
console.log(`Deploying Optimist implementation with ${deployer}`)
const Deployment__AttestationStationProxy = await hre.deployments.get(
'AttestationStationProxy'
)
const attestationStationAddress = Deployment__AttestationStationProxy.address
console.log(`Using ${attestationStationAddress} as the ATTESTATION_STATION`)
console.log(
`Using ${deployConfig.optimistBaseUriAttestorAddress} as BASE_URI_ATTESTOR`
)
const Deployment__OptimistAllowlistProxy = await hre.deployments.get(
'OptimistAllowlistProxy'
)
const optimistAllowlistAddress = Deployment__OptimistAllowlistProxy.address
const { deploy } = await hre.deployments.deterministic('Optimist', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['Optimist']),
from: deployer,
args: [
deployConfig.optimistName,
deployConfig.optimistSymbol,
deployConfig.optimistBaseUriAttestorAddress,
attestationStationAddress,
optimistAllowlistAddress,
],
log: true,
})
await deploy()
}
deployFn.tags = ['OptimistImpl', 'OptimistEnvironment']
deployFn.dependencies = ['AttestationStationProxy', 'OptimistAllowlistProxy']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@nomiclabs/hardhat-ethers'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'
import type { DeployConfig } from '../../src'
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
const { deployer } = await hre.getNamedAccounts()
console.log(`Deploying OptimistInviter implementation with ${deployer}`)
const Deployment__AttestationStation = await hre.deployments.get(
'AttestationStationProxy'
)
const attestationStationAddress = Deployment__AttestationStation.address
console.log(`Using ${attestationStationAddress} as the ATTESTATION_STATION`)
console.log(
`Using ${deployConfig.optimistInviterInviteGranter} as INVITE_GRANTER`
)
const { deploy } = await hre.deployments.deterministic('OptimistInviter', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['OptimistInviter']),
from: deployer,
args: [
deployConfig.optimistInviterInviteGranter,
attestationStationAddress,
],
log: true,
})
await deploy()
}
deployFn.tags = ['OptimistInviterImpl', 'OptimistEnvironment']
deployFn.dependencies = ['AttestationStationProxy']
export default deployFn
/* Imports: External */
import assert from 'assert'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { assertContractVariable } from '@eth-optimism/contracts-bedrock/src/deploy-utils'
import { ethers, utils } from 'ethers'
import type { DeployConfig } from '../../src'
import { setupProxyContract } from '../../src/helpers/setupProxyContract'
const { getAddress } = utils
// Required conditions before deploying - Specified in `deployFn.dependencies`
// - AttestationStationProxy is deployed and points to the correct implementation
// - OptimistInviterImpl is deployed
//
// Steps
// 1. Deploy OptimistInviterProxy
// 2. Point the newly deployed proxy to the implementation, if it hasn't been done already
// 3. Update the admin of the proxy to the l2ProxyOwnerAddress, if it hasn't been done already
// 4. Basic sanity checks for contract variables
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
// Deployer should be set in hardhat.config.ts
const { deployer } = await hre.getNamedAccounts()
// We want the ability to deploy to a deterministic address, so we need the init bytecode to be
// consistent across deployments. The ddd will quickly transfer the ownership of the Proxy to a
// multisig after deployment.
//
// We need a consistent ddd, since the Proxy takes a `_admin` constructor argument, which
// affects the init bytecode and hence deployed address.
const ddd = deployConfig.ddd
if (getAddress(deployer) !== getAddress(ddd)) {
// Not a hard requirement. We can deploy with any account and just set the `_admin` to the
// ddd, but requiring that the deployer is the same as the ddd minimizes number of hot wallets
// we need to keep track of during deployment.
throw new Error('Must deploy with the ddd')
}
// Get the up to date deployment of the OptimistInviter contract
const Deployment__OptimistInviterImpl = await hre.deployments.get(
'OptimistInviter'
)
console.log(`Deploying OptimistInviterProxy with ${deployer}`)
// Deploys the Proxy.sol contract with the `_admin` constructor param set to the ddd (=== deployer).
const { deploy } = await hre.deployments.deterministic(
'OptimistInviterProxy',
{
salt: hre.ethers.utils.solidityKeccak256(
['string'],
['OptimistInviterProxy']
),
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
}
)
// Deploy the Proxy contract
await deploy()
const Deployment__OptimistInviterProxy = await hre.deployments.get(
'OptimistInviterProxy'
)
console.log(
`OptimistInviterProxy deployed to ${Deployment__OptimistInviterProxy.address}`
)
// Deployed Proxy.sol contract
const Proxy = await hre.ethers.getContractAt(
'Proxy',
Deployment__OptimistInviterProxy.address
)
// Deployed Proxy.sol contract with the OptimistInviter interface
const OptimistInviter = await hre.ethers.getContractAt(
'OptimistInviter',
Deployment__OptimistInviterProxy.address
)
const name = deployConfig.optimistInviterName
// Create the calldata for the call to `initialize()`
const initializeCalldata = OptimistInviter.interface.encodeFunctionData(
'initialize',
[name]
)
// ethers.Signer for the ddd. Should be the current owner of the Proxy.
const dddSigner = await hre.ethers.provider.getSigner(deployer)
// intended admin of the Proxy
const l2ProxyOwnerAddress = deployConfig.l2ProxyOwnerAddress
// setup the Proxy contract with correct implementation and admin
await setupProxyContract(Proxy, dddSigner, {
targetImplAddress: Deployment__OptimistInviterImpl.address,
targetProxyOwnerAddress: l2ProxyOwnerAddress,
postUpgradeCallCalldata: initializeCalldata,
})
const Deployment__AttestationStation = await hre.deployments.get(
'AttestationStationProxy'
)
await assert(
getAddress(
await Proxy.connect(ethers.constants.AddressZero).callStatic.admin()
) === getAddress(l2ProxyOwnerAddress)
)
await assertContractVariable(OptimistInviter, 'version', '1.0.0')
await assertContractVariable(
OptimistInviter,
'INVITE_GRANTER',
deployConfig.optimistInviterInviteGranter
)
await assertContractVariable(
OptimistInviter,
'ATTESTATION_STATION',
Deployment__AttestationStation.address
)
await assertContractVariable(OptimistInviter, 'EIP712_VERSION', '1.0.0')
}
deployFn.tags = ['OptimistInviterProxy', 'OptimistEnvironment']
deployFn.dependencies = ['AttestationStationProxy', 'OptimistInviterImpl']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { assertContractVariable } from '@eth-optimism/contracts-bedrock/src/deploy-utils'
import { utils } from 'ethers'
import { setupProxyContract } from '../../src/helpers/setupProxyContract'
import type { DeployConfig } from '../../src'
const { getAddress } = utils
const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployConfig = hre.deployConfig as DeployConfig
const { deployer } = await hre.getNamedAccounts()
const ddd = deployConfig.ddd
if (getAddress(deployer) !== getAddress(ddd)) {
throw new Error('Must deploy with the ddd')
}
const Deployment__OptimistImpl = await hre.deployments.get('Optimist')
console.log(`Deploying OptimistProxy with ${deployer}`)
const { deploy } = await hre.deployments.deterministic('OptimistProxy', {
salt: hre.ethers.utils.solidityKeccak256(['string'], ['OptimistProxy']),
contract: 'Proxy',
from: deployer,
args: [deployer],
log: true,
})
await deploy()
const Deployment__OptimistProxy = await hre.deployments.get('OptimistProxy')
console.log(`OptimistProxy deployed to ${Deployment__OptimistProxy.address}`)
const Proxy = await hre.ethers.getContractAt(
'Proxy',
Deployment__OptimistProxy.address
)
const Optimist = await hre.ethers.getContractAt(
'Optimist',
Deployment__OptimistProxy.address
)
// ethers.Signer for the ddd. Should be the current owner of the Proxy.
const dddSigner = await hre.ethers.provider.getSigner(deployer)
// intended admin of the Proxy
const l2ProxyOwnerAddress = deployConfig.l2ProxyOwnerAddress
// Create the calldata for the call to `initialize()`
const name = deployConfig.optimistName
const symbol = deployConfig.optimistSymbol
const initializeCalldata = Optimist.interface.encodeFunctionData(
'initialize',
[name, symbol]
)
// setup the Proxy contract with correct implementation and admin, and initialize atomically
await setupProxyContract(Proxy, dddSigner, {
targetImplAddress: Deployment__OptimistImpl.address,
targetProxyOwnerAddress: l2ProxyOwnerAddress,
postUpgradeCallCalldata: initializeCalldata,
})
const Deployment__AttestationStationProxy = await hre.deployments.get(
'AttestationStationProxy'
)
const Deployment__OptimistAllowlistProxy = await hre.deployments.get(
'OptimistAllowlistProxy'
)
await assertContractVariable(Proxy, 'admin', l2ProxyOwnerAddress)
await assertContractVariable(Optimist, 'name', deployConfig.optimistName)
await assertContractVariable(Optimist, 'version', '2.0.0')
await assertContractVariable(Optimist, 'symbol', deployConfig.optimistSymbol)
await assertContractVariable(
Optimist,
'BASE_URI_ATTESTOR',
deployConfig.optimistBaseUriAttestorAddress
)
await assertContractVariable(
Optimist,
'OPTIMIST_ALLOWLIST',
Deployment__OptimistAllowlistProxy.address
)
await assertContractVariable(
Optimist,
'ATTESTATION_STATION',
Deployment__AttestationStationProxy.address
)
}
deployFn.tags = ['OptimistProxy', 'OptimistEnvironment']
deployFn.dependencies = ['AttestationStationProxy', 'OptimistImpl']
export default deployFn
{
"language": "Solidity",
"sources": {
"contracts/testing/helpers/TestERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n constructor() ERC20(\"TEST\", \"TST\", 18) {}\n\n function mint(address to, uint256 value) public {\n _mint(to, value);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * @notice Emitted when ETH is received by this address.\n *\n * @param from Address that sent ETH to this contract.\n * @param amount Amount of ETH received.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * @notice Emitted when ETH is withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param amount ETH amount withdrawn.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param amount ERC20 amount withdrawn.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param id Token ID being withdrawn.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * @notice Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * @notice Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * @notice Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n (bool success, ) = _to.call{ value: _amount }(\"\");\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * @notice Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * @notice Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * @notice Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _value ETH value to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(address _target, bytes memory _data)\n external\n payable\n onlyOwner\n returns (bool, bytes memory)\n {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck)\n * and an execution interval. Drips cannot be executed faster than the execution interval.\n * Drips can trigger arbitrary contract calls where the calling contract is this contract\n * address. Drips can also send ETH value, which makes them ideal for keeping addresses\n * sufficiently funded with ETH. Drippie is designed to be connected with smart contract\n * automation services so that drips can be executed automatically. However, Drippie is\n * specifically designed to be separated from these services so that trust assumptions are\n * better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * @notice Enum representing different status options for a given drip.\n *\n * @custom:value NONE Drip does not exist.\n * @custom:value PAUSED Drip is paused and cannot be executed until reactivated.\n * @custom:value ACTIVE Drip is active and can be executed.\n * @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.\n */\n enum DripStatus {\n NONE,\n PAUSED,\n ACTIVE,\n ARCHIVED\n }\n\n /**\n * @notice Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * @notice Represents the configuration for a given drip.\n */\n struct DripConfig {\n bool reentrant;\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * @notice Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n uint256 count;\n }\n\n /**\n * @notice Emitted when a new drip is created.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param config Config for the created drip.\n */\n event DripCreated(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n DripConfig config\n );\n\n /**\n * @notice Emitted when a drip status is updated.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param status New drip status.\n */\n event DripStatusUpdated(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n DripStatus status\n );\n\n /**\n * @notice Emitted when a drip is executed.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param executor Address that executed the drip.\n * @param timestamp Time when the drip was executed.\n */\n event DripExecuted(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n address executor,\n uint256 timestamp\n );\n\n /**\n * @notice Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * @notice Creates a new drip with the given name and configuration. Once created, drips cannot\n * be modified in any way (this is a security measure). If you want to update a drip,\n * simply pause (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string calldata _name, DripConfig calldata _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // Validate the drip interval, only allowing an interval of zero if the drip has explicitly\n // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable\n // within the same block (of course, restricted by gas limits).\n if (_config.reentrant) {\n require(\n _config.interval == 0,\n \"Drippie: if allowing reentrant drip, must set interval to zero\"\n );\n } else {\n require(\n _config.interval > 0,\n \"Drippie: interval must be greater than zero if drip is not reentrant\"\n );\n }\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.reentrant = _config.reentrant;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _name, _config);\n }\n\n /**\n * @notice Sets the status for a given drip. The behavior of this function depends on the\n * status that the user is trying to set. A drip can always move between ACTIVE and\n * PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back\n * to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string calldata _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Load the drip status once to avoid unnecessary SLOADs.\n DripStatus curr = drips[_name].status;\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n curr != DripStatus.NONE,\n \"Drippie: drip with that name does not exist and cannot be updated\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n curr != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived and cannot be updated\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n curr != _status,\n \"Drippie: cannot set drip status to the same status as its current status\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n curr == DripStatus.PAUSED,\n \"Drippie: drip must first be paused before being archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, _name, _status);\n }\n\n /**\n * @notice Checks if a given drip is executable.\n *\n * @param _name Drip to check.\n *\n * @return True if the drip is executable, reverts otherwise.\n */\n function executable(string calldata _name) public view returns (bool) {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Alright, we're good to execute.\n return true;\n }\n\n /**\n * @notice Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative\n * signal that the drip should be executable according to the drip parameters, drip\n * check, and drip interval. Note that drip parameters are read entirely from the state\n * and are not supplied as user input, so there should not be any way for a\n * non-authorized user to influence the behavior of the drip. Note that the drip check\n * is executed only **once** at the beginning of the call to the drip function and will\n * not be executed again between the drip actions within this call.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string calldata _name) external {\n DripState storage state = drips[_name];\n\n // Make sure the drip can be executed. Since executable reverts if the drip is not ready to\n // be executed, we don't need to do an assertion that the returned value is true.\n executable(_name);\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Update the number of times this drip has been executed. Although this increases the cost\n // of using Drippie, it slightly simplifies the client-side by not having to worry about\n // counting drips via events. Useful for monitoring the rate of drip execution.\n state.count++;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, _name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n /**\n * @notice Checks whether a drip should be executable.\n *\n * @param _params Encoded parameters for the drip check.\n *\n * @return Whether the drip should be executed.\n */\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n struct Params {\n address target;\n uint256 threshold;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n struct Params {\n address target;\n uint256 threshold;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
},
"contracts/testing/helpers/TestERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"TEST\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n function tokenURI(uint256) public pure virtual override returns (string memory) {}\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0xd5F62980C9d1bAa2A983bF16F8874A92F0050C48",
"abi": [
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct CheckBalanceHigh.Params",
"name": "params",
"type": "tuple"
}
],
"name": "_EventToExposeStructInABI__Params",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"args": [],
"numDeployments": 1,
"solcInputHash": "b09909e91a3ff9823ceba49a3a845230",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceHigh.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckBalanceHigh\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck for checking if an account's balance is above a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":\"CheckBalanceHigh\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x73db6ada63ed1f0eba24efd36099139e66908aa45c79c0d1defe2a59a9e9eb9d\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceHigh\\n * @notice DripCheck for checking if an account's balance is above a given threshold.\\n */\\ncontract CheckBalanceHigh is IDripCheck {\\n event _EventToExposeStructInABI__Params(Params params);\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target balance is above threshold.\\n return params.target.balance > params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x517f69b75b62b7b74d3d4fceb45ecacb9cf1d68b62a8517e2985a6e0da0a7575\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220c3948eadf9cbb80bb928bc392291d583593cefbaff6536ec1485a7602e7f6b7f64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631119392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea2646970667358221220c3948eadf9cbb80bb928bc392291d583593cefbaff6536ec1485a7602e7f6b7f64736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {},
"title": "CheckBalanceHigh",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"notice": "DripCheck for checking if an account's balance is above a given threshold.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"address": "0x00B1D6438A4E7E3733Bd9fCe4A068b07A0E47620",
"abi": [
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
}
],
"indexed": false,
"internalType": "struct CheckBalanceLow.Params",
"name": "params",
"type": "tuple"
}
],
"name": "_EventToExposeStructInABI__Params",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x65f0d04160b33d020aed8bfc4207f169d230549d8cff494f600b104fe0e689a1",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5",
"contractAddress": null,
"transactionIndex": 81,
"gasUsed": "176640",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xb1ddf0d044777738b0a1e53a28129e5d58076dbaa9b190843b76354706d8880b",
"transactionHash": "0x65f0d04160b33d020aed8bfc4207f169d230549d8cff494f600b104fe0e689a1",
"logs": [],
"blockNumber": 14981100,
"cumulativeGasUsed": "5262258",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "b09909e91a3ff9823ceba49a3a845230",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct CheckBalanceLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckBalanceLow\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck for checking if an account's balance is below a given threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":\"CheckBalanceLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x73db6ada63ed1f0eba24efd36099139e66908aa45c79c0d1defe2a59a9e9eb9d\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckBalanceLow\\n * @notice DripCheck for checking if an account's balance is below a given threshold.\\n */\\ncontract CheckBalanceLow is IDripCheck {\\n event _EventToExposeStructInABI__Params(Params params);\\n struct Params {\\n address target;\\n uint256 threshold;\\n }\\n\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check target ETH balance is below threshold.\\n return params.target.balance < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0xd6d8e6abcc1428666132e9d8140243fff23c564b6474927e18f30fe078801842\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50610239806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea264697066735822122075d8f6816a6709f5b54613834c7be6979cb3af4abf6a1d38244135be431d562b64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e3660046100c3565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610192565b6020810151905173ffffffffffffffffffffffffffffffffffffffff1631109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156100d557600080fd5b813567ffffffffffffffff808211156100ed57600080fd5b818401915084601f83011261010157600080fd5b81358181111561011357610113610094565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561015957610159610094565b8160405282815287602084870101111561017257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000604082840312156101a457600080fd5b6040516040810181811067ffffffffffffffff821117156101c7576101c7610094565b604052825173ffffffffffffffffffffffffffffffffffffffff811681146101ee57600080fd5b8152602092830151928101929092525091905056fea264697066735822122075d8f6816a6709f5b54613834c7be6979cb3af4abf6a1d38244135be431d562b64736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {},
"title": "CheckBalanceLow",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"notice": "DripCheck for checking if an account's balance is below a given threshold.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"address": "0x81d70959f29872A9e597a54658A93962F7D9B597",
"abi": [
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "treasury",
"type": "address"
},
{
"internalType": "uint256",
"name": "threshold",
"type": "uint256"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"indexed": false,
"internalType": "struct CheckGelatoLow.Params",
"name": "params",
"type": "tuple"
}
],
"name": "_EventToExposeStructInABI__Params",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_params",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x4f3db725a79a177062c8ddbbedb005a96ecb8eab6e71c4172c1b37fa1c708688",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5",
"contractAddress": null,
"transactionIndex": 53,
"gasUsed": "225248",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xae292ed733027c5232a5775cd788ce31394cf4e7a068b7f2edbf8bd142e40d8f",
"transactionHash": "0x4f3db725a79a177062c8ddbbedb005a96ecb8eab6e71c4172c1b37fa1c708688",
"logs": [],
"blockNumber": 14981104,
"cumulativeGasUsed": "5063510",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "b09909e91a3ff9823ceba49a3a845230",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"treasury\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct CheckGelatoLow.Params\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"_EventToExposeStructInABI__Params\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_params\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckGelatoLow\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck for checking if an account's Gelato ETH balance is below some threshold.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":\"CheckGelatoLow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x73db6ada63ed1f0eba24efd36099139e66908aa45c79c0d1defe2a59a9e9eb9d\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\ninterface IGelatoTreasury {\\n function userTokenBalance(address _user, address _token) external view returns (uint256);\\n}\\n\\n/**\\n * @title CheckGelatoLow\\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\\n */\\ncontract CheckGelatoLow is IDripCheck {\\n event _EventToExposeStructInABI__Params(Params params);\\n struct Params {\\n address treasury;\\n uint256 threshold;\\n address recipient;\\n }\\n\\n function check(bytes memory _params) external view returns (bool) {\\n Params memory params = abi.decode(_params, (Params));\\n\\n // Check GelatoTreasury ETH balance is below threshold.\\n return\\n IGelatoTreasury(params.treasury).userTokenBalance(\\n params.recipient,\\n // Gelato represents ETH as 0xeeeee....eeeee\\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\\n ) < params.threshold;\\n }\\n}\\n\",\"keccak256\":\"0x8d936bc5e037a1b05225f2cd208ef6899b0d29cd3b91c73e5c16762eb242e5ef\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5061031b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e36600461016f565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610267565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c89060440160206040518083038186803b15801561010057600080fd5b505afa158015610114573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013891906102cc565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561018157600080fd5b813567ffffffffffffffff8082111561019957600080fd5b818401915084601f8301126101ad57600080fd5b8135818111156101bf576101bf610140565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561020557610205610140565b8160405282815287602084870101111561021e57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461026257600080fd5b919050565b60006060828403121561027957600080fd5b6040516060810181811067ffffffffffffffff8211171561029c5761029c610140565b6040526102a88361023e565b8152602083015160208201526102c06040840161023e565b60408201529392505050565b6000602082840312156102de57600080fd5b505191905056fea2646970667358221220e4e865f160af7ad5bd6e586c93c567a5f9a5ee5a652397683119d14d6f5e658464736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004361003e36600461016f565b610057565b604051901515815260200160405180910390f35b6000808280602001905181019061006e9190610267565b6020810151815160408084015190517fb47064c800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff918216600482015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6024820152939450919291169063b47064c89060440160206040518083038186803b15801561010057600080fd5b505afa158015610114573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061013891906102cc565b109392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561018157600080fd5b813567ffffffffffffffff8082111561019957600080fd5b818401915084601f8301126101ad57600080fd5b8135818111156101bf576101bf610140565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561020557610205610140565b8160405282815287602084870101111561021e57600080fd5b826020860160208301376000928101602001929092525095945050505050565b805173ffffffffffffffffffffffffffffffffffffffff8116811461026257600080fd5b919050565b60006060828403121561027957600080fd5b6040516060810181811067ffffffffffffffff8211171561029c5761029c610140565b6040526102a88361023e565b8152602083015160208201526102c06040840161023e565b60408201529392505050565b6000602082840312156102de57600080fd5b505191905056fea2646970667358221220e4e865f160af7ad5bd6e586c93c567a5f9a5ee5a652397683119d14d6f5e658464736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {},
"title": "CheckGelatoLow",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"notice": "DripCheck for checking if an account's Gelato ETH balance is below some threshold.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"address": "0x7e2B28af043c347C18fc37f62B5D001df6BFa26c",
"abi": [
{
"inputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "check",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "pure",
"type": "function"
}
],
"transactionHash": "0x02af8af4f6eda0944e437af66082a71b3a0c9c52f3ab2ac4e4929538f94d9411",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5",
"contractAddress": null,
"transactionIndex": 6,
"gasUsed": "139230",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xbf599dc7b5468b1291bd41db9290db892c3e883c7f24cfa123f0ce4fa19d8bf3",
"transactionHash": "0x02af8af4f6eda0944e437af66082a71b3a0c9c52f3ab2ac4e4929538f94d9411",
"logs": [],
"blockNumber": 14981108,
"cumulativeGasUsed": "630300",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "b09909e91a3ff9823ceba49a3a845230",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"check\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"CheckTrue\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"DripCheck that always returns true.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":\"CheckTrue\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"contracts/universal/drippie/IDripCheck.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\ninterface IDripCheck {\\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\\n // possible to easily encode parameters on the client side. Solidity does not support generics\\n // so it's not possible to do this with explicit typing.\\n\\n function check(bytes memory _params) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x73db6ada63ed1f0eba24efd36099139e66908aa45c79c0d1defe2a59a9e9eb9d\",\"license\":\"MIT\"},\"contracts/universal/drippie/dripchecks/CheckTrue.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { IDripCheck } from \\\"../IDripCheck.sol\\\";\\n\\n/**\\n * @title CheckTrue\\n * @notice DripCheck that always returns true.\\n */\\ncontract CheckTrue is IDripCheck {\\n function check(bytes memory) external pure returns (bool) {\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x2ed60821a4302130b567da45f15dce5a7c41e5d5b016c32ec09c92d4fb5ba6e6\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5061018c806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212207179cc803626c6d5a28bb5725d572d164ec9b64d4f37f10f220761ee045840fc64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c64b3bb514610030575b600080fd5b61004461003e366004610087565b50600190565b604051901515815260200160405180910390f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561009957600080fd5b813567ffffffffffffffff808211156100b157600080fd5b818401915084601f8301126100c557600080fd5b8135818111156100d7576100d7610058565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561011d5761011d610058565b8160405282815287602084870101111561013657600080fd5b82602086016020830137600092810160200192909252509594505050505056fea26469706673582212207179cc803626c6d5a28bb5725d572d164ec9b64d4f37f10f220761ee045840fc64736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {},
"title": "CheckTrue",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"notice": "DripCheck that always returns true.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"address": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_admin",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "previousAdmin",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "newAdmin",
"type": "address"
}
],
"name": "AdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Upgraded",
"type": "event"
},
{
"stateMutability": "payable",
"type": "fallback"
},
{
"inputs": [],
"name": "admin",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_admin",
"type": "address"
}
],
"name": "changeAdmin",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "implementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_implementation",
"type": "address"
}
],
"name": "upgradeTo",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_implementation",
"type": "address"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "upgradeToAndCall",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0x7583d011cf1593fb1ffc79b097b0a365192c87dfdccbf860e1ad3f1425a305ef",
"receipt": {
"to": null,
"from": "0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E",
"contractAddress": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D",
"transactionIndex": 140,
"gasUsed": "532674",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000800000000000000000000000000",
"blockHash": "0xa5c98ae09c1db0857551a9eaca6d88e1bff5f8103814795c0ed1e7863e16a6d5",
"transactionHash": "0x7583d011cf1593fb1ffc79b097b0a365192c87dfdccbf860e1ad3f1425a305ef",
"logs": [
{
"transactionIndex": 140,
"blockNumber": 15677422,
"transactionHash": "0x7583d011cf1593fb1ffc79b097b0a365192c87dfdccbf860e1ad3f1425a305ef",
"address": "0x5a7749f83b81B301cAb5f48EB8516B986DAef23D",
"topics": [
"0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f"
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053a6eecc2dd4795fcc68940ddc6b4d53bd88bd9e",
"logIndex": 251,
"blockHash": "0xa5c98ae09c1db0857551a9eaca6d88e1bff5f8103814795c0ed1e7863e16a6d5"
}
],
"blockNumber": 15677422,
"cumulativeGasUsed": "12586381",
"status": 1,
"byzantium": true
},
"args": [
"0x53A6eecC2dD4795Fcc68940ddc6B4d53Bd88Bd9E"
],
"numDeployments": 1,
"solcInputHash": "ab9b77493f35e63b7a63fb2fa8d618b4",
"metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"params\":{\"newAdmin\":\"The new owner of the contract\",\"previousAdmin\":\"The previous owner of the contract\"}},\"Upgraded(address)\":{\"params\":{\"implementation\":\"The address of the implementation contract\"}}},\"kind\":\"dev\",\"methods\":{\"admin()\":{\"returns\":{\"_0\":\"Owner address.\"}},\"changeAdmin(address)\":{\"params\":{\"_admin\":\"New owner of the proxy contract.\"}},\"constructor\":{\"params\":{\"_admin\":\"Address of the initial contract admin. Admin as the ability to access the transparent proxy interface.\"}},\"implementation()\":{\"returns\":{\"_0\":\"Implementation address.\"}},\"upgradeTo(address)\":{\"params\":{\"_implementation\":\"Address of the implementation contract.\"}},\"upgradeToAndCall(address,bytes)\":{\"params\":{\"_data\":\"Calldata to delegatecall the new implementation with.\",\"_implementation\":\"Address of the implementation contract.\"}}},\"title\":\"Proxy\",\"version\":1},\"userdoc\":{\"events\":{\"AdminChanged(address,address)\":{\"notice\":\"An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification.\"},\"Upgraded(address)\":{\"notice\":\"An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification.\"}},\"kind\":\"user\",\"methods\":{\"admin()\":{\"notice\":\"Gets the owner of the proxy contract.\"},\"changeAdmin(address)\":{\"notice\":\"Changes the owner of the proxy contract. Only callable by the owner.\"},\"constructor\":{\"notice\":\"Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible.\"},\"implementation()\":{\"notice\":\"Queries the implementation address.\"},\"upgradeTo(address)\":{\"notice\":\"Set the implementation contract address. The code at the given address will execute when this contract is called.\"},\"upgradeToAndCall(address,bytes)\":{\"notice\":\"Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades.\"}},\"notice\":\"Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":\"Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@eth-optimism/contracts-bedrock/contracts/universal/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.15;\\n\\n/**\\n * @title Proxy\\n * @notice Proxy is a transparent proxy that passes through the call if the caller is the owner or\\n * if the caller is address(0), meaning that the call originated from an off-chain\\n * simulation.\\n */\\ncontract Proxy {\\n /**\\n * @notice The storage slot that holds the address of the implementation.\\n * bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\\n */\\n bytes32 internal constant IMPLEMENTATION_KEY =\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @notice The storage slot that holds the address of the owner.\\n * bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)\\n */\\n bytes32 internal constant OWNER_KEY =\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @notice An event that is emitted each time the implementation is changed. This event is part\\n * of the EIP-1967 specification.\\n *\\n * @param implementation The address of the implementation contract\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @notice An event that is emitted each time the owner is upgraded. This event is part of the\\n * EIP-1967 specification.\\n *\\n * @param previousAdmin The previous owner of the contract\\n * @param newAdmin The new owner of the contract\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @notice A modifier that reverts if not called by the owner or by address(0) to allow\\n * eth_call to interact with this proxy without needing to use low-level storage\\n * inspection. We assume that nobody is able to trigger calls from address(0) during\\n * normal EVM execution.\\n */\\n modifier proxyCallIfNotAdmin() {\\n if (msg.sender == _getAdmin() || msg.sender == address(0)) {\\n _;\\n } else {\\n // This WILL halt the call frame on completion.\\n _doProxyCall();\\n }\\n }\\n\\n /**\\n * @notice Sets the initial admin during contract deployment. Admin address is stored at the\\n * EIP-1967 admin storage slot so that accidental storage collision with the\\n * implementation is not possible.\\n *\\n * @param _admin Address of the initial contract admin. Admin as the ability to access the\\n * transparent proxy interface.\\n */\\n constructor(address _admin) {\\n _changeAdmin(_admin);\\n }\\n\\n // slither-disable-next-line locked-ether\\n receive() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n // slither-disable-next-line locked-ether\\n fallback() external payable {\\n // Proxy call by default.\\n _doProxyCall();\\n }\\n\\n /**\\n * @notice Set the implementation contract address. The code at the given address will execute\\n * when this contract is called.\\n *\\n * @param _implementation Address of the implementation contract.\\n */\\n function upgradeTo(address _implementation) external proxyCallIfNotAdmin {\\n _setImplementation(_implementation);\\n }\\n\\n /**\\n * @notice Set the implementation and call a function in a single transaction. Useful to ensure\\n * atomic execution of initialization-based upgrades.\\n *\\n * @param _implementation Address of the implementation contract.\\n * @param _data Calldata to delegatecall the new implementation with.\\n */\\n function upgradeToAndCall(address _implementation, bytes calldata _data)\\n external\\n payable\\n proxyCallIfNotAdmin\\n returns (bytes memory)\\n {\\n _setImplementation(_implementation);\\n (bool success, bytes memory returndata) = _implementation.delegatecall(_data);\\n require(success, \\\"Proxy: delegatecall to new implementation contract failed\\\");\\n return returndata;\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract. Only callable by the owner.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function changeAdmin(address _admin) external proxyCallIfNotAdmin {\\n _changeAdmin(_admin);\\n }\\n\\n /**\\n * @notice Gets the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function admin() external proxyCallIfNotAdmin returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function implementation() external proxyCallIfNotAdmin returns (address) {\\n return _getImplementation();\\n }\\n\\n /**\\n * @notice Sets the implementation address.\\n *\\n * @param _implementation New implementation address.\\n */\\n function _setImplementation(address _implementation) internal {\\n assembly {\\n sstore(IMPLEMENTATION_KEY, _implementation)\\n }\\n emit Upgraded(_implementation);\\n }\\n\\n /**\\n * @notice Changes the owner of the proxy contract.\\n *\\n * @param _admin New owner of the proxy contract.\\n */\\n function _changeAdmin(address _admin) internal {\\n address previous = _getAdmin();\\n assembly {\\n sstore(OWNER_KEY, _admin)\\n }\\n emit AdminChanged(previous, _admin);\\n }\\n\\n /**\\n * @notice Performs the proxy call via a delegatecall.\\n */\\n function _doProxyCall() internal {\\n address impl = _getImplementation();\\n require(impl != address(0), \\\"Proxy: implementation not initialized\\\");\\n\\n assembly {\\n // Copy calldata into memory at 0x0....calldatasize.\\n calldatacopy(0x0, 0x0, calldatasize())\\n\\n // Perform the delegatecall, make sure to pass all available gas.\\n let success := delegatecall(gas(), impl, 0x0, calldatasize(), 0x0, 0x0)\\n\\n // Copy returndata into memory at 0x0....returndatasize. Note that this *will*\\n // overwrite the calldata that we just copied into memory but that doesn't really\\n // matter because we'll be returning in a second anyway.\\n returndatacopy(0x0, 0x0, returndatasize())\\n\\n // Success == 0 means a revert. We'll revert too and pass the data up.\\n if iszero(success) {\\n revert(0x0, returndatasize())\\n }\\n\\n // Otherwise we'll just return and pass the data up.\\n return(0x0, returndatasize())\\n }\\n }\\n\\n /**\\n * @notice Queries the implementation address.\\n *\\n * @return Implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n address impl;\\n assembly {\\n impl := sload(IMPLEMENTATION_KEY)\\n }\\n return impl;\\n }\\n\\n /**\\n * @notice Queries the owner of the proxy contract.\\n *\\n * @return Owner address.\\n */\\n function _getAdmin() internal view returns (address) {\\n address owner;\\n assembly {\\n owner := sload(OWNER_KEY)\\n }\\n return owner;\\n }\\n}\\n\",\"keccak256\":\"0xfa08635f1866139673ac4fe7b07330f752f93800075b895d8fcb8484f4a3f753\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5060405161094138038061094183398101604081905261002f916100b2565b6100388161003e565b506100e2565b60006100566000805160206109218339815191525490565b600080516020610921833981519152839055604080516001600160a01b038084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b6000602082840312156100c457600080fd5b81516001600160a01b03811681146100db57600080fd5b9392505050565b610830806100f16000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103",
"deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100be5780638f283970146100f8578063f851a440146101185761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61012d565b005b61006b61012d565b34801561008157600080fd5b5061006b6100903660046106d9565b610224565b6100a86100a33660046106f4565b610296565b6040516100b59190610777565b60405180910390f35b3480156100ca57600080fd5b506100d3610419565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100b5565b34801561010457600080fd5b5061006b6101133660046106d9565b6104b0565b34801561012457600080fd5b506100d3610517565b60006101577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905073ffffffffffffffffffffffffffffffffffffffff8116610201576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160448201527f6c697a656400000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8061021e573d6000fd5b503d6000f35b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061027d575033155b1561028e5761028b816105a3565b50565b61028b61012d565b60606102c07fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102f7575033155b1561040a57610305846105a3565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161032f9291906107ea565b600060405180830381855af49150503d806000811461036a576040519150601f19603f3d011682016040523d82523d6000602084013e61036f565b606091505b509150915081610401576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560448201527f6d656e746174696f6e20636f6e7472616374206661696c65640000000000000060648201526084016101f8565b91506104129050565b61041261012d565b9392505050565b60006104437fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061047a575033155b156104a557507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6104ad61012d565b90565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610509575033155b1561028e5761028b8161060b565b60006105417fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610578575033155b156104a557507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81905560405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60006106357fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038390556040805173ffffffffffffffffffffffffffffffffffffffff8084168252851660208201529192507f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f910160405180910390a15050565b803573ffffffffffffffffffffffffffffffffffffffff811681146106d457600080fd5b919050565b6000602082840312156106eb57600080fd5b610412826106b0565b60008060006040848603121561070957600080fd5b610712846106b0565b9250602084013567ffffffffffffffff8082111561072f57600080fd5b818601915086601f83011261074357600080fd5b81358181111561075257600080fd5b87602082850101111561076457600080fd5b6020830194508093505050509250925092565b600060208083528351808285015260005b818110156107a457858101830151858201604001528201610788565b818111156107b6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b818382376000910190815291905056fea2646970667358221220120210f19dd8be0e46312b3b9a2148bbb98ec24cce2aa05af1c3d1fe69f55b2b64736f6c634300080f0033",
"devdoc": {
"events": {
"AdminChanged(address,address)": {
"params": {
"newAdmin": "The new owner of the contract",
"previousAdmin": "The previous owner of the contract"
}
},
"Upgraded(address)": {
"params": {
"implementation": "The address of the implementation contract"
}
}
},
"kind": "dev",
"methods": {
"admin()": {
"returns": {
"_0": "Owner address."
}
},
"changeAdmin(address)": {
"params": {
"_admin": "New owner of the proxy contract."
}
},
"constructor": {
"params": {
"_admin": "Address of the initial contract admin. Admin as the ability to access the transparent proxy interface."
}
},
"implementation()": {
"returns": {
"_0": "Implementation address."
}
},
"upgradeTo(address)": {
"params": {
"_implementation": "Address of the implementation contract."
}
},
"upgradeToAndCall(address,bytes)": {
"params": {
"_data": "Calldata to delegatecall the new implementation with.",
"_implementation": "Address of the implementation contract."
}
}
},
"title": "Proxy",
"version": 1
},
"userdoc": {
"events": {
"AdminChanged(address,address)": {
"notice": "An event that is emitted each time the owner is upgraded. This event is part of the EIP-1967 specification."
},
"Upgraded(address)": {
"notice": "An event that is emitted each time the implementation is changed. This event is part of the EIP-1967 specification."
}
},
"kind": "user",
"methods": {
"admin()": {
"notice": "Gets the owner of the proxy contract."
},
"changeAdmin(address)": {
"notice": "Changes the owner of the proxy contract. Only callable by the owner."
},
"constructor": {
"notice": "Sets the initial admin during contract deployment. Admin address is stored at the EIP-1967 admin storage slot so that accidental storage collision with the implementation is not possible."
},
"implementation()": {
"notice": "Queries the implementation address."
},
"upgradeTo(address)": {
"notice": "Set the implementation contract address. The code at the given address will execute when this contract is called."
},
"upgradeToAndCall(address,bytes)": {
"notice": "Set the implementation and call a function in a single transaction. Useful to ensure atomic execution of initialization-based upgrades."
}
},
"notice": "Proxy is a transparent proxy that passes through the call if the caller is the owner or if the caller is address(0), meaning that the call originated from an off-chain simulation.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * Emitted when ETH is received by this address.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * Emitted when ETH is withdrawn from this address.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * Emitted when ERC20 tokens are withdrawn from this address.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * Emitted when ERC721 tokens are withdrawn from this address.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n _to.transfer(_amount);\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @param _value ETH value to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _gas,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ gas: _gas, value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(\n address _target,\n bytes memory _data,\n uint256 _gas\n ) external payable onlyOwner returns (bool, bytes memory) {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall{ gas: _gas }(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck) and an\n * execution interval. Drips cannot be executed faster than the execution interval. Drips can\n * trigger arbitrary contract calls where the calling contract is this contract address. Drips can\n * also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.\n * Drippie is designed to be connected with smart contract automation services so that drips can be\n * executed automatically. However, Drippie is specifically designed to be separated from these\n * services so that trust assumptions are better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * Enum representing different status options for a given drip.\n */\n enum DripStatus {\n NONE,\n ACTIVE,\n PAUSED,\n ARCHIVED\n }\n\n /**\n * Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * Represents the configuration for a given drip.\n */\n struct DripConfig {\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n }\n\n /**\n * Emitted when a new drip is created.\n */\n event DripCreated(string indexed name, DripConfig config);\n\n /**\n * Emitted when a drip status is updated.\n */\n event DripStatusUpdated(string indexed name, DripStatus status);\n\n /**\n * Emitted when a drip is executed.\n */\n event DripExecuted(string indexed name, address indexed executor, uint256 timestamp);\n\n /**\n * Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * Creates a new drip with the given name and configuration. Once created, drips cannot be\n * modified in any way (this is a security measure). If you want to update a drip, simply pause\n * (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _config);\n }\n\n /**\n * Sets the status for a given drip. The behavior of this function depends on the status that\n * the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can\n * never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string memory _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n drips[_name].status != DripStatus.NONE,\n \"Drippie: drip with that name does not exist\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n drips[_name].status != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n drips[_name].status != _status,\n \"Drippie: cannot set drip status to same status as before\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n drips[_name].status == DripStatus.PAUSED,\n \"Drippie: drip must be paused to be archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, drips[_name].status);\n }\n\n /**\n * Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative signal that\n * the drip should be executable according to the drip parameters, drip check, and drip\n * interval. Note that drip parameters are read entirely from the state and are not supplied as\n * user input, so there should not be any way for a non-authorized user to influence the\n * behavior of the drip.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string memory _name) external {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * Emitted when ETH is received by this address.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * Emitted when ETH is withdrawn from this address.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * Emitted when ERC20 tokens are withdrawn from this address.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * Emitted when ERC721 tokens are withdrawn from this address.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n _to.transfer(_amount);\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @param _value ETH value to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _gas,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ gas: _gas, value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(\n address _target,\n bytes memory _data,\n uint256 _gas\n ) external payable onlyOwner returns (bool, bytes memory) {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall{ gas: _gas }(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck) and an\n * execution interval. Drips cannot be executed faster than the execution interval. Drips can\n * trigger arbitrary contract calls where the calling contract is this contract address. Drips can\n * also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.\n * Drippie is designed to be connected with smart contract automation services so that drips can be\n * executed automatically. However, Drippie is specifically designed to be separated from these\n * services so that trust assumptions are better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * Enum representing different status options for a given drip.\n */\n enum DripStatus {\n NONE,\n ACTIVE,\n PAUSED,\n ARCHIVED\n }\n\n /**\n * Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * Represents the configuration for a given drip.\n */\n struct DripConfig {\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n }\n\n /**\n * Emitted when a new drip is created.\n */\n event DripCreated(string indexed name, DripConfig config);\n\n /**\n * Emitted when a drip status is updated.\n */\n event DripStatusUpdated(string indexed name, DripStatus status);\n\n /**\n * Emitted when a drip is executed.\n */\n event DripExecuted(string indexed name, address indexed executor, uint256 timestamp);\n\n /**\n * Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * Creates a new drip with the given name and configuration. Once created, drips cannot be\n * modified in any way (this is a security measure). If you want to update a drip, simply pause\n * (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _config);\n }\n\n /**\n * Sets the status for a given drip. The behavior of this function depends on the status that\n * the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can\n * never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string memory _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n drips[_name].status != DripStatus.NONE,\n \"Drippie: drip with that name does not exist\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n drips[_name].status != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n drips[_name].status != _status,\n \"Drippie: cannot set drip status to same status as before\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n drips[_name].status == DripStatus.PAUSED,\n \"Drippie: drip must be paused to be archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, drips[_name].status);\n }\n\n /**\n * Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative signal that\n * the drip should be executable according to the drip parameters, drip check, and drip\n * interval. Note that drip parameters are read entirely from the state and are not supplied as\n * user input, so there should not be any way for a non-authorized user to influence the\n * behavior of the drip.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string memory _name) external {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{
"address": "0x15DdA60616Ffca20371ED1659dBB78E888f65556",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnerUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ReceivedETH",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "WithdrewERC20",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "WithdrewERC721",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "WithdrewETH",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "_target",
"type": "address"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "_gas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
}
],
"name": "CALL",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_target",
"type": "address"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "_gas",
"type": "uint256"
}
],
"name": "DELEGATECALL",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ERC20",
"name": "_asset",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "withdrawERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ERC20",
"name": "_asset",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
}
],
"name": "withdrawERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ERC721",
"name": "_asset",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_id",
"type": "uint256"
}
],
"name": "withdrawERC721",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "withdrawETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_to",
"type": "address"
}
],
"name": "withdrawETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0xb71ff0a1159385a03ad097a57d1cb37b62c5d6bc82be2e642a8d25d4ff4e1814",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x9C6373dE60c2D3297b18A8f964618ac46E011B58",
"contractAddress": null,
"transactionIndex": 31,
"gasUsed": "887432",
"logsBloom": "0x00100000000000000001000000000000000000000000000000000000000000000000100000000000000000100000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000020000000000000000000000000000000000000000000000",
"blockHash": "0x2b65d7c70a739ca85d8fd598096aa680cd2eb267e73036afd4cb974edebda524",
"transactionHash": "0xb71ff0a1159385a03ad097a57d1cb37b62c5d6bc82be2e642a8d25d4ff4e1814",
"logs": [
{
"transactionIndex": 31,
"blockNumber": 14904330,
"transactionHash": "0xb71ff0a1159385a03ad097a57d1cb37b62c5d6bc82be2e642a8d25d4ff4e1814",
"address": "0x15DdA60616Ffca20371ED1659dBB78E888f65556",
"topics": [
"0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58"
],
"data": "0x",
"logIndex": 57,
"blockHash": "0x2b65d7c70a739ca85d8fd598096aa680cd2eb267e73036afd4cb974edebda524"
}
],
"blockNumber": 14904330,
"cumulativeGasUsed": "3130678",
"status": 1,
"byzantium": true
},
"args": [
"0x9C6373dE60c2D3297b18A8f964618ac46E011B58"
],
"numDeployments": 2,
"solcInputHash": "66d28de48de020e62747d42ffe3118e7",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial contract owner.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"AssetReceiver\",\"version\":1},\"userdoc\":{\"events\":{\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC721 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes,uint256)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"}},\"notice\":\"AssetReceiver is a minimal contract for receiving funds assets in the form of either ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/AssetReceiver.sol\":\"AssetReceiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x0240f7703cff32a61ee3e9fbb339e09a944260432a9ef37debf3692b1a6c8049\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xb59c7c25eca386f39da4819a9f70f89b73b7583d5f5127a83ffe5339800b1183\",\"license\":\"AGPL-3.0-only\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * Emitted when ETH is received by this address.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * Emitted when ETH is withdrawn from this address.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * Emitted when ERC20 tokens are withdrawn from this address.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * Emitted when ERC721 tokens are withdrawn from this address.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n _to.transfer(_amount);\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x1f82aff6f4e5a4bebebbfb4a2e0e4378ef9bc5bee8b81f88b27fc0ce73546d5f\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @param _value ETH value to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ gas: _gas, value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall{ gas: _gas }(_data);\\n }\\n}\\n\",\"keccak256\":\"0xfe0d9c05a423d36775047e3285f76b874f8b887444d412a0d680c302c3b06a50\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b50604051610f6e380380610f6e83398101604081905261002f91610081565b600080546001600160a01b0319166001600160a01b038316908117825560405183928392917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a35050506100b1565b60006020828403121561009357600080fd5b81516001600160a01b03811681146100aa57600080fd5b9392505050565b610eae806100c06000396000f3fe60806040526004361061009a5760003560e01c80635cef8b4a116100695780638da5cb5b1161004e5780638da5cb5b146101a75780639456fbcc146101f95780639e73dbea1461021957600080fd5b80635cef8b4a1461015d578063690d83201461018757600080fd5b806313af4035146100db5780634025feb2146100fd57806344004cc11461011d5780634782f7791461013d57600080fd5b366100d65760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b3480156100e757600080fd5b506100fb6100f6366004610b3a565b61022c565b005b34801561010957600080fd5b506100fb610118366004610b5e565b610322565b34801561012957600080fd5b506100fb610138366004610b5e565b6104b4565b34801561014957600080fd5b506100fb610158366004610b9f565b610654565b61017061016b366004610ca5565b61076a565b60405161017e929190610d2e565b60405180910390f35b34801561019357600080fd5b506100fb6101a2366004610b3a565b610863565b3480156101b357600080fd5b506000546101d49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161017e565b34801561020557600080fd5b506100fb610214366004610d88565b6108f1565b610170610227366004610dc1565b610a1b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516104a791815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156105a557600080fd5b505af11580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190610e21565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516104a791815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610718573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8473ffffffffffffffffffffffffffffffffffffffff1683856040516108159190610e43565b6000604051808303818686f4925050503d8060008114610851576040519150601f19603f3d011682016040523d82523d6000602084013e610856565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6108ee8147610654565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610a17908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101389190610e5f565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610ac79190610e43565b600060405180830381858888f193505050503d8060008114610b05576040519150601f19603f3d011682016040523d82523d6000602084013e610b0a565b606091505b509150915094509492505050565b73ffffffffffffffffffffffffffffffffffffffff811681146108ee57600080fd5b600060208284031215610b4c57600080fd5b8135610b5781610b18565b9392505050565b600080600060608486031215610b7357600080fd5b8335610b7e81610b18565b92506020840135610b8e81610b18565b929592945050506040919091013590565b60008060408385031215610bb257600080fd5b8235610bbd81610b18565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610c0b57600080fd5b813567ffffffffffffffff80821115610c2657610c26610bcb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c6c57610c6c610bcb565b81604052838152866020858801011115610c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610cba57600080fd5b8335610cc581610b18565b9250602084013567ffffffffffffffff811115610ce157600080fd5b610ced86828701610bfa565b925050604084013590509250925092565b60005b83811015610d19578181015183820152602001610d01565b83811115610d28576000848401525b50505050565b82151581526040602082015260008251806040840152610d55816060850160208701610cfe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60008060408385031215610d9b57600080fd5b8235610da681610b18565b91506020830135610db681610b18565b809150509250929050565b60008060008060808587031215610dd757600080fd5b8435610de281610b18565b9350602085013567ffffffffffffffff811115610dfe57600080fd5b610e0a87828801610bfa565b949794965050505060408301359260600135919050565b600060208284031215610e3357600080fd5b81518015158114610b5757600080fd5b60008251610e55818460208701610cfe565b9190910192915050565b600060208284031215610e7157600080fd5b505191905056fea2646970667358221220a79fda18860baa011a378f2e4963a1c9eb8fa5184c5fd3130308ce3c35ba96da64736f6c63430008090033",
"deployedBytecode": "0x60806040526004361061009a5760003560e01c80635cef8b4a116100695780638da5cb5b1161004e5780638da5cb5b146101a75780639456fbcc146101f95780639e73dbea1461021957600080fd5b80635cef8b4a1461015d578063690d83201461018757600080fd5b806313af4035146100db5780634025feb2146100fd57806344004cc11461011d5780634782f7791461013d57600080fd5b366100d65760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b3480156100e757600080fd5b506100fb6100f6366004610b3a565b61022c565b005b34801561010957600080fd5b506100fb610118366004610b5e565b610322565b34801561012957600080fd5b506100fb610138366004610b5e565b6104b4565b34801561014957600080fd5b506100fb610158366004610b9f565b610654565b61017061016b366004610ca5565b61076a565b60405161017e929190610d2e565b60405180910390f35b34801561019357600080fd5b506100fb6101a2366004610b3a565b610863565b3480156101b357600080fd5b506000546101d49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161017e565b34801561020557600080fd5b506100fb610214366004610d88565b6108f1565b610170610227366004610dc1565b610a1b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516104a791815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b1580156105a557600080fd5b505af11580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190610e21565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516104a791815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610718573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff1633146107ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8473ffffffffffffffffffffffffffffffffffffffff1683856040516108159190610e43565b6000604051808303818686f4925050503d8060008114610851576040519150601f19603f3d011682016040523d82523d6000602084013e610856565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6108ee8147610654565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610972576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610a17908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b1580156109df57600080fd5b505afa1580156109f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101389190610e5f565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016102a9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610ac79190610e43565b600060405180830381858888f193505050503d8060008114610b05576040519150601f19603f3d011682016040523d82523d6000602084013e610b0a565b606091505b509150915094509492505050565b73ffffffffffffffffffffffffffffffffffffffff811681146108ee57600080fd5b600060208284031215610b4c57600080fd5b8135610b5781610b18565b9392505050565b600080600060608486031215610b7357600080fd5b8335610b7e81610b18565b92506020840135610b8e81610b18565b929592945050506040919091013590565b60008060408385031215610bb257600080fd5b8235610bbd81610b18565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610c0b57600080fd5b813567ffffffffffffffff80821115610c2657610c26610bcb565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610c6c57610c6c610bcb565b81604052838152866020858801011115610c8557600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610cba57600080fd5b8335610cc581610b18565b9250602084013567ffffffffffffffff811115610ce157600080fd5b610ced86828701610bfa565b925050604084013590509250925092565b60005b83811015610d19578181015183820152602001610d01565b83811115610d28576000848401525b50505050565b82151581526040602082015260008251806040840152610d55816060850160208701610cfe565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60008060408385031215610d9b57600080fd5b8235610da681610b18565b91506020830135610db681610b18565b809150509250929050565b60008060008060808587031215610dd757600080fd5b8435610de281610b18565b9350602085013567ffffffffffffffff811115610dfe57600080fd5b610e0a87828801610bfa565b949794965050505060408301359260600135919050565b600060208284031215610e3357600080fd5b81518015158114610b5757600080fd5b60008251610e55818460208701610cfe565b9190910192915050565b600060208284031215610e7157600080fd5b505191905056fea2646970667358221220a79fda18860baa011a378f2e4963a1c9eb8fa5184c5fd3130308ce3c35ba96da64736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {
"CALL(address,bytes,uint256,uint256)": {
"params": {
"_data": "Data to send with the call.",
"_gas": "Amount of gas to send with the call.",
"_target": "Address to call.",
"_value": "ETH value to send with the call."
},
"returns": {
"_0": "Boolean success value.",
"_1": "Bytes data returned by the call."
}
},
"DELEGATECALL(address,bytes,uint256)": {
"params": {
"_data": "Data to send with the call.",
"_gas": "Amount of gas to send with the call.",
"_target": "Address to call."
},
"returns": {
"_0": "Boolean success value.",
"_1": "Bytes data returned by the call."
}
},
"constructor": {
"params": {
"_owner": "Initial contract owner."
}
},
"withdrawERC20(address,address)": {
"params": {
"_asset": "ERC20 token to withdraw.",
"_to": "Address to receive the ERC20 balance."
}
},
"withdrawERC20(address,address,uint256)": {
"params": {
"_amount": "Amount of ERC20 to withdraw.",
"_asset": "ERC20 token to withdraw.",
"_to": "Address to receive the ERC20 balance."
}
},
"withdrawERC721(address,address,uint256)": {
"params": {
"_asset": "ERC721 token to withdraw.",
"_id": "Token ID of the ERC721 token to withdraw.",
"_to": "Address to receive the ERC721 token."
}
},
"withdrawETH(address)": {
"params": {
"_to": "Address to receive the ETH balance."
}
},
"withdrawETH(address,uint256)": {
"params": {
"_amount": "Amount of ETH to withdraw.",
"_to": "Address to receive the ETH balance."
}
}
},
"title": "AssetReceiver",
"version": 1
},
"userdoc": {
"events": {
"ReceivedETH(address,uint256)": {
"notice": "Emitted when ETH is received by this address."
},
"WithdrewERC20(address,address,address,uint256)": {
"notice": "Emitted when ERC20 tokens are withdrawn from this address."
},
"WithdrewERC721(address,address,address,uint256)": {
"notice": "Emitted when ERC721 tokens are withdrawn from this address."
},
"WithdrewETH(address,address,uint256)": {
"notice": "Emitted when ETH is withdrawn from this address."
}
},
"kind": "user",
"methods": {
"CALL(address,bytes,uint256,uint256)": {
"notice": "Sends a CALL to a target address."
},
"DELEGATECALL(address,bytes,uint256)": {
"notice": "Sends a DELEGATECALL to a target address."
},
"withdrawERC20(address,address)": {
"notice": "Withdraws full ERC20 balance to the recipient."
},
"withdrawERC20(address,address,uint256)": {
"notice": "Withdraws partial ERC20 balance to the recipient."
},
"withdrawERC721(address,address,uint256)": {
"notice": "Withdraws ERC721 token to the recipient."
},
"withdrawETH(address)": {
"notice": "Withdraws full ETH balance to the recipient."
},
"withdrawETH(address,uint256)": {
"notice": "Withdraws partial ETH balance to the recipient."
}
},
"notice": "AssetReceiver is a minimal contract for receiving funds assets in the form of either ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.",
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 10,
"contract": "contracts/universal/AssetReceiver.sol:AssetReceiver",
"label": "owner",
"offset": 0,
"slot": "0",
"type": "t_address"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
}
}
}
}
\ No newline at end of file
{
"address": "0x78A25524D90E3D0596558fb43789bD800a5c3007",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnerUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ReceivedETH",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "WithdrewERC20",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "WithdrewERC721",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "withdrawer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "WithdrewETH",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "_target",
"type": "address"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "_gas",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
}
],
"name": "CALL",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_target",
"type": "address"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "_gas",
"type": "uint256"
}
],
"name": "DELEGATECALL",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "data",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "recipient",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "setData",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_recipient",
"type": "address"
}
],
"name": "setRecipient",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_teleportr",
"type": "address"
}
],
"name": "setTeleportr",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "teleportr",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ERC20",
"name": "_asset",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "withdrawERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ERC20",
"name": "_asset",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
}
],
"name": "withdrawERC20",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ERC721",
"name": "_asset",
"type": "address"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_id",
"type": "uint256"
}
],
"name": "withdrawERC721",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "withdrawETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_to",
"type": "address"
}
],
"name": "withdrawETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdrawFromTeleportr",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
],
"transactionHash": "0xe7914c509af8b99ef3421601b487ccdf2c7ef5955ffbd58bbb7d786452df3638",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0xc37f6a6c4AB335E20d10F034B90386E2fb70bbF5",
"contractAddress": null,
"transactionIndex": 249,
"gasUsed": "1233027",
"logsBloom": "0x00000000000000000001000000000000000000000000000000000000000000000000100000000000000000000000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000080000000020000000000000000000800000000000080000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000004000000020000000000000000000000000000000000000000000000",
"blockHash": "0xbdb85532b8a9423604350b1254f5b465838c92bffaecd1768cf94b95e58ffa80",
"transactionHash": "0xe7914c509af8b99ef3421601b487ccdf2c7ef5955ffbd58bbb7d786452df3638",
"logs": [
{
"transactionIndex": 249,
"blockNumber": 14981055,
"transactionHash": "0xe7914c509af8b99ef3421601b487ccdf2c7ef5955ffbd58bbb7d786452df3638",
"address": "0x78A25524D90E3D0596558fb43789bD800a5c3007",
"topics": [
"0x8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000009c6373de60c2d3297b18a8f964618ac46e011b58"
],
"data": "0x",
"logIndex": 574,
"blockHash": "0xbdb85532b8a9423604350b1254f5b465838c92bffaecd1768cf94b95e58ffa80"
}
],
"blockNumber": 14981055,
"cumulativeGasUsed": "26253070",
"status": 1,
"byzantium": true
},
"args": [
"0x9C6373dE60c2D3297b18A8f964618ac46E011B58"
],
"numDeployments": 1,
"solcInputHash": "b09909e91a3ff9823ceba49a3a845230",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ReceivedETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"WithdrewERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"withdrawer\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrewETH\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"CALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gas\",\"type\":\"uint256\"}],\"name\":\"DELEGATECALL\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"data\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"setData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"setOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"}],\"name\":\"setRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_teleportr\",\"type\":\"address\"}],\"name\":\"setTeleportr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"teleportr\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC20\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ERC721\",\"name\":\"_asset\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_to\",\"type\":\"address\"}],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawFromTeleportr\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\",\"_value\":\"ETH value to send with the call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"DELEGATECALL(address,bytes,uint256)\":{\"params\":{\"_data\":\"Data to send with the call.\",\"_gas\":\"Amount of gas to send with the call.\",\"_target\":\"Address to call.\"},\"returns\":{\"_0\":\"Boolean success value.\",\"_1\":\"Bytes data returned by the call.\"}},\"constructor\":{\"params\":{\"_owner\":\"Initial owner of the contract.\"}},\"setData(bytes)\":{\"params\":{\"_data\":\"New data to be sent to the recipient address.\"}},\"setRecipient(address)\":{\"params\":{\"_recipient\":\"New recipient address.\"}},\"setTeleportr(address)\":{\"params\":{\"_teleportr\":\"New Teleportr contract address.\"}},\"withdrawERC20(address,address)\":{\"params\":{\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC20(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount of ERC20 to withdraw.\",\"_asset\":\"ERC20 token to withdraw.\",\"_to\":\"Address to receive the ERC20 balance.\"}},\"withdrawERC721(address,address,uint256)\":{\"params\":{\"_asset\":\"ERC721 token to withdraw.\",\"_id\":\"Token ID of the ERC721 token to withdraw.\",\"_to\":\"Address to receive the ERC721 token.\"}},\"withdrawETH(address)\":{\"params\":{\"_to\":\"Address to receive the ETH balance.\"}},\"withdrawETH(address,uint256)\":{\"params\":{\"_amount\":\"Amount of ETH to withdraw.\",\"_to\":\"Address to receive the ETH balance.\"}}},\"title\":\"TeleportrWithdrawer\",\"version\":1},\"userdoc\":{\"events\":{\"ReceivedETH(address,uint256)\":{\"notice\":\"Emitted when ETH is received by this address.\"},\"WithdrewERC20(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC20 tokens are withdrawn from this address.\"},\"WithdrewERC721(address,address,address,uint256)\":{\"notice\":\"Emitted when ERC721 tokens are withdrawn from this address.\"},\"WithdrewETH(address,address,uint256)\":{\"notice\":\"Emitted when ETH is withdrawn from this address.\"}},\"kind\":\"user\",\"methods\":{\"CALL(address,bytes,uint256,uint256)\":{\"notice\":\"Sends a CALL to a target address.\"},\"DELEGATECALL(address,bytes,uint256)\":{\"notice\":\"Sends a DELEGATECALL to a target address.\"},\"data()\":{\"notice\":\"Data to be sent to the recipient address.\"},\"recipient()\":{\"notice\":\"Address that will receive Teleportr withdrawals.\"},\"setData(bytes)\":{\"notice\":\"Allows the owner to update the data to be sent to the recipient address.\"},\"setRecipient(address)\":{\"notice\":\"Allows the owner to update the recipient address.\"},\"setTeleportr(address)\":{\"notice\":\"Allows the owner to update the Teleportr contract address.\"},\"teleportr()\":{\"notice\":\"Address of the Teleportr contract.\"},\"withdrawERC20(address,address)\":{\"notice\":\"Withdraws full ERC20 balance to the recipient.\"},\"withdrawERC20(address,address,uint256)\":{\"notice\":\"Withdraws partial ERC20 balance to the recipient.\"},\"withdrawERC721(address,address,uint256)\":{\"notice\":\"Withdraws ERC721 token to the recipient.\"},\"withdrawETH(address)\":{\"notice\":\"Withdraws full ETH balance to the recipient.\"},\"withdrawETH(address,uint256)\":{\"notice\":\"Withdraws partial ETH balance to the recipient.\"},\"withdrawFromTeleportr()\":{\"notice\":\"Withdraws the full balance of the Teleportr contract to the recipient address. Anyone is allowed to trigger this function since the recipient address cannot be controlled by the msg.sender.\"}},\"notice\":\"The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the TeleportrContract and sending them to some recipient address.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/universal/TeleportrWithdrawer.sol\":\"TeleportrWithdrawer\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/auth/Owned.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Simple single owner authorization mixin.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\\nabstract contract Owned {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event OwnerUpdated(address indexed user, address indexed newOwner);\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n address public owner;\\n\\n modifier onlyOwner() virtual {\\n require(msg.sender == owner, \\\"UNAUTHORIZED\\\");\\n\\n _;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(address _owner) {\\n owner = _owner;\\n\\n emit OwnerUpdated(address(0), _owner);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n OWNERSHIP LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function setOwner(address newOwner) public virtual onlyOwner {\\n owner = newOwner;\\n\\n emit OwnerUpdated(msg.sender, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7e91c80b0dd1a14a19cb9e661b99924043adab6d9d893bbfcf3a6a3dc23a6743\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n address recoveredAddress = ecrecover(\\n keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(\\n abi.encode(\\n keccak256(\\n \\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\"\\n ),\\n owner,\\n spender,\\n value,\\n nonces[owner]++,\\n deadline\\n )\\n )\\n )\\n ),\\n v,\\n r,\\n s\\n );\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x0240f7703cff32a61ee3e9fbb339e09a944260432a9ef37debf3692b1a6c8049\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/tokens/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721 {\\n /*//////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\\n\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /*//////////////////////////////////////////////////////////////\\n METADATA STORAGE/LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n function tokenURI(uint256 id) public view virtual returns (string memory);\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 BALANCE/OWNER STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) internal _ownerOf;\\n\\n mapping(address => uint256) internal _balanceOf;\\n\\n function ownerOf(uint256 id) public view virtual returns (address owner) {\\n require((owner = _ownerOf[id]) != address(0), \\\"NOT_MINTED\\\");\\n }\\n\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n require(owner != address(0), \\\"ZERO_ADDRESS\\\");\\n\\n return _balanceOf[owner];\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 APPROVAL STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n mapping(uint256 => address) public getApproved;\\n\\n mapping(address => mapping(address => bool)) public isApprovedForAll;\\n\\n /*//////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(string memory _name, string memory _symbol) {\\n name = _name;\\n symbol = _symbol;\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC721 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 id) public virtual {\\n address owner = _ownerOf[id];\\n\\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \\\"NOT_AUTHORIZED\\\");\\n\\n getApproved[id] = spender;\\n\\n emit Approval(owner, spender, id);\\n }\\n\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n isApprovedForAll[msg.sender][operator] = approved;\\n\\n emit ApprovalForAll(msg.sender, operator, approved);\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n require(from == _ownerOf[id], \\\"WRONG_FROM\\\");\\n\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(\\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\\n \\\"NOT_AUTHORIZED\\\"\\n );\\n\\n // Underflow of the sender's balance is impossible because we check for\\n // ownership above and the recipient's balance can't realistically overflow.\\n unchecked {\\n _balanceOf[from]--;\\n\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n delete getApproved[id];\\n\\n emit Transfer(from, to, id);\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n bytes calldata data\\n ) public virtual {\\n transferFrom(from, to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n ERC165 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return\\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 id) internal virtual {\\n require(to != address(0), \\\"INVALID_RECIPIENT\\\");\\n\\n require(_ownerOf[id] == address(0), \\\"ALREADY_MINTED\\\");\\n\\n // Counter overflow is incredibly unrealistic.\\n unchecked {\\n _balanceOf[to]++;\\n }\\n\\n _ownerOf[id] = to;\\n\\n emit Transfer(address(0), to, id);\\n }\\n\\n function _burn(uint256 id) internal virtual {\\n address owner = _ownerOf[id];\\n\\n require(owner != address(0), \\\"NOT_MINTED\\\");\\n\\n // Ownership check above ensures no underflow.\\n unchecked {\\n _balanceOf[owner]--;\\n }\\n\\n delete _ownerOf[id];\\n\\n delete getApproved[id];\\n\\n emit Transfer(owner, address(0), id);\\n }\\n\\n /*//////////////////////////////////////////////////////////////\\n INTERNAL SAFE MINT LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _safeMint(address to, uint256 id) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \\\"\\\") ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n\\n function _safeMint(\\n address to,\\n uint256 id,\\n bytes memory data\\n ) internal virtual {\\n _mint(to, id);\\n\\n require(\\n to.code.length == 0 ||\\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\\n ERC721TokenReceiver.onERC721Received.selector,\\n \\\"UNSAFE_RECIPIENT\\\"\\n );\\n }\\n}\\n\\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\\nabstract contract ERC721TokenReceiver {\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external virtual returns (bytes4) {\\n return ERC721TokenReceiver.onERC721Received.selector;\\n }\\n}\\n\",\"keccak256\":\"0xb59c7c25eca386f39da4819a9f70f89b73b7583d5f5127a83ffe5339800b1183\",\"license\":\"AGPL-3.0-only\"},\"contracts/universal/AssetReceiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { ERC20 } from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport { ERC721 } from \\\"@rari-capital/solmate/src/tokens/ERC721.sol\\\";\\nimport { Transactor } from \\\"./Transactor.sol\\\";\\n\\n/**\\n * @title AssetReceiver\\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\\n */\\ncontract AssetReceiver is Transactor {\\n /**\\n * Emitted when ETH is received by this address.\\n */\\n event ReceivedETH(address indexed from, uint256 amount);\\n\\n /**\\n * Emitted when ETH is withdrawn from this address.\\n */\\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\\n\\n /**\\n * Emitted when ERC20 tokens are withdrawn from this address.\\n */\\n event WithdrewERC20(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 amount\\n );\\n\\n /**\\n * Emitted when ERC721 tokens are withdrawn from this address.\\n */\\n event WithdrewERC721(\\n address indexed withdrawer,\\n address indexed recipient,\\n address indexed asset,\\n uint256 id\\n );\\n\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Transactor(_owner) {}\\n\\n /**\\n * Make sure we can receive ETH.\\n */\\n receive() external payable {\\n emit ReceivedETH(msg.sender, msg.value);\\n }\\n\\n /**\\n * Withdraws full ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n */\\n function withdrawETH(address payable _to) external onlyOwner {\\n withdrawETH(_to, address(this).balance);\\n }\\n\\n /**\\n * Withdraws partial ETH balance to the recipient.\\n *\\n * @param _to Address to receive the ETH balance.\\n * @param _amount Amount of ETH to withdraw.\\n */\\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\\n // slither-disable-next-line reentrancy-unlimited-gas\\n _to.transfer(_amount);\\n emit WithdrewETH(msg.sender, _to, _amount);\\n }\\n\\n /**\\n * Withdraws full ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n */\\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\\n }\\n\\n /**\\n * Withdraws partial ERC20 balance to the recipient.\\n *\\n * @param _asset ERC20 token to withdraw.\\n * @param _to Address to receive the ERC20 balance.\\n * @param _amount Amount of ERC20 to withdraw.\\n */\\n function withdrawERC20(\\n ERC20 _asset,\\n address _to,\\n uint256 _amount\\n ) public onlyOwner {\\n // slither-disable-next-line unchecked-transfer\\n _asset.transfer(_to, _amount);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\\n }\\n\\n /**\\n * Withdraws ERC721 token to the recipient.\\n *\\n * @param _asset ERC721 token to withdraw.\\n * @param _to Address to receive the ERC721 token.\\n * @param _id Token ID of the ERC721 token to withdraw.\\n */\\n function withdrawERC721(\\n ERC721 _asset,\\n address _to,\\n uint256 _id\\n ) external onlyOwner {\\n _asset.transferFrom(address(this), _to, _id);\\n // slither-disable-next-line reentrancy-events\\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\\n }\\n}\\n\",\"keccak256\":\"0x1f82aff6f4e5a4bebebbfb4a2e0e4378ef9bc5bee8b81f88b27fc0ce73546d5f\",\"license\":\"MIT\"},\"contracts/universal/TeleportrWithdrawer.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { AssetReceiver } from \\\"./AssetReceiver.sol\\\";\\n\\n/**\\n * @notice Stub interface for Teleportr.\\n */\\ninterface Teleportr {\\n function withdrawBalance() external;\\n}\\n\\n/**\\n * @title TeleportrWithdrawer\\n * @notice The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the\\n * TeleportrContract and sending them to some recipient address.\\n */\\ncontract TeleportrWithdrawer is AssetReceiver {\\n /**\\n * @notice Address of the Teleportr contract.\\n */\\n address public teleportr;\\n\\n /**\\n * @notice Address that will receive Teleportr withdrawals.\\n */\\n address public recipient;\\n\\n /**\\n * @notice Data to be sent to the recipient address.\\n */\\n bytes public data;\\n\\n /**\\n * @param _owner Initial owner of the contract.\\n */\\n constructor(address _owner) AssetReceiver(_owner) {}\\n\\n /**\\n * @notice Allows the owner to update the recipient address.\\n *\\n * @param _recipient New recipient address.\\n */\\n function setRecipient(address _recipient) external onlyOwner {\\n recipient = _recipient;\\n }\\n\\n /**\\n * @notice Allows the owner to update the Teleportr contract address.\\n *\\n * @param _teleportr New Teleportr contract address.\\n */\\n function setTeleportr(address _teleportr) external onlyOwner {\\n teleportr = _teleportr;\\n }\\n\\n /**\\n * @notice Allows the owner to update the data to be sent to the recipient address.\\n *\\n * @param _data New data to be sent to the recipient address.\\n */\\n function setData(bytes memory _data) external onlyOwner {\\n data = _data;\\n }\\n\\n /**\\n * @notice Withdraws the full balance of the Teleportr contract to the recipient address.\\n * Anyone is allowed to trigger this function since the recipient address cannot be\\n * controlled by the msg.sender.\\n */\\n function withdrawFromTeleportr() external {\\n Teleportr(teleportr).withdrawBalance();\\n (bool success, ) = recipient.call{ value: address(this).balance }(data);\\n require(success, \\\"TeleportrWithdrawer: send failed\\\");\\n }\\n}\\n\",\"keccak256\":\"0x26414ae14c7aee927c18075ee60757383e0202c2a2691f23b86c200c0ac24713\",\"license\":\"MIT\"},\"contracts/universal/Transactor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.9;\\n\\nimport { Owned } from \\\"@rari-capital/solmate/src/auth/Owned.sol\\\";\\n\\n/**\\n * @title Transactor\\n * @notice Transactor is a minimal contract that can send transactions.\\n */\\ncontract Transactor is Owned {\\n /**\\n * @param _owner Initial contract owner.\\n */\\n constructor(address _owner) Owned(_owner) {}\\n\\n /**\\n * Sends a CALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @param _value ETH value to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function CALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas,\\n uint256 _value\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n return _target.call{ gas: _gas, value: _value }(_data);\\n }\\n\\n /**\\n * Sends a DELEGATECALL to a target address.\\n *\\n * @param _target Address to call.\\n * @param _data Data to send with the call.\\n * @param _gas Amount of gas to send with the call.\\n * @return Boolean success value.\\n * @return Bytes data returned by the call.\\n */\\n function DELEGATECALL(\\n address _target,\\n bytes memory _data,\\n uint256 _gas\\n ) external payable onlyOwner returns (bool, bytes memory) {\\n // slither-disable-next-line controlled-delegatecall\\n return _target.delegatecall{ gas: _gas }(_data);\\n }\\n}\\n\",\"keccak256\":\"0xfe0d9c05a423d36775047e3285f76b874f8b887444d412a0d680c302c3b06a50\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b506040516115ac3803806115ac83398101604081905261002f91610086565b600080546001600160a01b0319166001600160a01b03831690811782556040518392839283929091907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a3505050506100b6565b60006020828403121561009857600080fd5b81516001600160a01b03811681146100af57600080fd5b9392505050565b6114e7806100c56000396000f3fe6080604052600436106100f75760003560e01c8063617d55421161008a5780638da5cb5b116100595780638da5cb5b146102f65780639456fbcc146103235780639e73dbea14610343578063ab62f0e11461035657600080fd5b8063617d55421461026757806366d003ac14610287578063690d8320146102b457806373d4a13a146102d457600080fd5b80634025feb2116100c65780634025feb2146101e657806344004cc1146102065780634782f779146102265780635cef8b4a1461024657600080fd5b806306fa29b21461013857806313af40351461018f5780633afe48c2146101b15780633bbed4a0146101c657600080fd5b366101335760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561014457600080fd5b506001546101659073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561019b57600080fd5b506101af6101aa366004610ff1565b610376565b005b3480156101bd57600080fd5b506101af610452565b3480156101d257600080fd5b506101af6101e1366004610ff1565b61059a565b3480156101f257600080fd5b506101af610201366004611015565b610648565b34801561021257600080fd5b506101af610221366004611015565b6107c0565b34801561023257600080fd5b506101af610241366004611056565b610946565b61025961025436600461115c565b610a42565b60405161018692919061122f565b34801561027357600080fd5b506101af610282366004610ff1565b610b21565b34801561029357600080fd5b506002546101659073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102c057600080fd5b506101af6102cf366004610ff1565b610bcf565b3480156102e057600080fd5b506102e9610c40565b6040516101869190611252565b34801561030257600080fd5b506000546101659073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032f57600080fd5b506101af61033e366004611265565b610cce565b61025961035136600461129e565b610dde565b34801561036257600080fd5b506101af6103713660046112fe565b610ec1565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103e25760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fd8c7106040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104bc57600080fd5b505af11580156104d0573d6000803e3d6000fd5b50506002546040516000935073ffffffffffffffffffffffffffffffffffffffff9091169150479061050490600390611387565b60006040518083038185875af1925050503d8060008114610541576040519150601f19603f3d011682016040523d82523d6000602084013e610546565b606091505b50509050806105975760405162461bcd60e51b815260206004820181905260248201527f54656c65706f727472576974686472617765723a2073656e64206661696c656460448201526064016103d9565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106015760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106af5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561072557600080fd5b505af1158015610739573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516107b391815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108275760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b15801561089757600080fd5b505af11580156108ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cf919061145a565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516107b391815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109ad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156109f0573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610ad3919061147c565b6000604051808303818686f4925050503d8060008114610b0f576040519150601f19603f3d011682016040523d82523d6000602084013e610b14565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b885760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c365760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6105978147610946565b60038054610c4d90611333565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7990611333565b8015610cc65780601f10610c9b57610100808354040283529160200191610cc6565b820191906000526020600020905b815481529060010190602001808311610ca957829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d355760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610dda908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b158015610da257600080fd5b505afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102219190611498565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610e495760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610e70919061147c565b600060405180830381858888f193505050503d8060008114610eae576040519150601f19603f3d011682016040523d82523d6000602084013e610eb3565b606091505b509150915094509492505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f285760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8051610dda906003906020840190828054610f4290611333565b90600052602060002090601f016020900481019282610f645760008555610faa565b82601f10610f7d57805160ff1916838001178555610faa565b82800160010185558215610faa579182015b82811115610faa578251825591602001919060010190610f8f565b50610fb6929150610fba565b5090565b5b80821115610fb65760008155600101610fbb565b73ffffffffffffffffffffffffffffffffffffffff8116811461059757600080fd5b60006020828403121561100357600080fd5b813561100e81610fcf565b9392505050565b60008060006060848603121561102a57600080fd5b833561103581610fcf565b9250602084013561104581610fcf565b929592945050506040919091013590565b6000806040838503121561106957600080fd5b823561107481610fcf565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126110c257600080fd5b813567ffffffffffffffff808211156110dd576110dd611082565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561112357611123611082565b8160405283815286602085880101111561113c57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561117157600080fd5b833561117c81610fcf565b9250602084013567ffffffffffffffff81111561119857600080fd5b6111a4868287016110b1565b925050604084013590509250925092565b60005b838110156111d05781810151838201526020016111b8565b838111156111df576000848401525b50505050565b600081518084526111fd8160208601602086016111b5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b821515815260406020820152600061124a60408301846111e5565b949350505050565b60208152600061100e60208301846111e5565b6000806040838503121561127857600080fd5b823561128381610fcf565b9150602083013561129381610fcf565b809150509250929050565b600080600080608085870312156112b457600080fd5b84356112bf81610fcf565b9350602085013567ffffffffffffffff8111156112db57600080fd5b6112e7878288016110b1565b949794965050505060408301359260600135919050565b60006020828403121561131057600080fd5b813567ffffffffffffffff81111561132757600080fd5b61124a848285016110b1565b600181811c9082168061134757607f821691505b60208210811415611381577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806113a357607f831692505b60208084108214156113dc577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b8180156113f0576001811461141f5761144c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952848901965061144c565b60008a81526020902060005b868110156114445781548b82015290850190830161142b565b505084890196505b509498975050505050505050565b60006020828403121561146c57600080fd5b8151801515811461100e57600080fd5b6000825161148e8184602087016111b5565b9190910192915050565b6000602082840312156114aa57600080fd5b505191905056fea26469706673582212203903a2f3f310c1942ac6f552df9012c64af2d384894531650c63a359397535f364736f6c63430008090033",
"deployedBytecode": "0x6080604052600436106100f75760003560e01c8063617d55421161008a5780638da5cb5b116100595780638da5cb5b146102f65780639456fbcc146103235780639e73dbea14610343578063ab62f0e11461035657600080fd5b8063617d55421461026757806366d003ac14610287578063690d8320146102b457806373d4a13a146102d457600080fd5b80634025feb2116100c65780634025feb2146101e657806344004cc1146102065780634782f779146102265780635cef8b4a1461024657600080fd5b806306fa29b21461013857806313af40351461018f5780633afe48c2146101b15780633bbed4a0146101c657600080fd5b366101335760405134815233907f4103257eaac983ca79a70d28f90dfc4fa16b619bb0c17ee7cab0d4034c2796249060200160405180910390a2005b600080fd5b34801561014457600080fd5b506001546101659073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561019b57600080fd5b506101af6101aa366004610ff1565b610376565b005b3480156101bd57600080fd5b506101af610452565b3480156101d257600080fd5b506101af6101e1366004610ff1565b61059a565b3480156101f257600080fd5b506101af610201366004611015565b610648565b34801561021257600080fd5b506101af610221366004611015565b6107c0565b34801561023257600080fd5b506101af610241366004611056565b610946565b61025961025436600461115c565b610a42565b60405161018692919061122f565b34801561027357600080fd5b506101af610282366004610ff1565b610b21565b34801561029357600080fd5b506002546101659073ffffffffffffffffffffffffffffffffffffffff1681565b3480156102c057600080fd5b506101af6102cf366004610ff1565b610bcf565b3480156102e057600080fd5b506102e9610c40565b6040516101869190611252565b34801561030257600080fd5b506000546101659073ffffffffffffffffffffffffffffffffffffffff1681565b34801561032f57600080fd5b506101af61033e366004611265565b610cce565b61025961035136600461129e565b610dde565b34801561036257600080fd5b506101af6103713660046112fe565b610ec1565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103e25760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d769190a350565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635fd8c7106040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156104bc57600080fd5b505af11580156104d0573d6000803e3d6000fd5b50506002546040516000935073ffffffffffffffffffffffffffffffffffffffff9091169150479061050490600390611387565b60006040518083038185875af1925050503d8060008114610541576040519150601f19603f3d011682016040523d82523d6000602084013e610546565b606091505b50509050806105975760405162461bcd60e51b815260206004820181905260248201527f54656c65706f727472576974686472617765723a2073656e64206661696c656460448201526064016103d9565b50565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106015760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1633146106af5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390528416906323b872dd90606401600060405180830381600087803b15801561072557600080fd5b505af1158015610739573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f30b478a5e196e55886228aa87ba74a7dfeba655e0a4d7ba275eabfc22aabb7a8846040516107b391815260200190565b60405180910390a4505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108275760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301526024820183905284169063a9059cbb90604401602060405180830381600087803b15801561089757600080fd5b505af11580156108ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108cf919061145a565b508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6b00f1c7883f053ba83e907fd1965b22fffe3c4111383e725f04638a566cdbfa846040516107b391815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109ad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f193505050501580156109f0573d6000803e3d6000fd5b5060405181815273ffffffffffffffffffffffffffffffffffffffff83169033907f1f12aa8b6d492dd9b98e2b00b0b20830c2a7ded65afac13b60d169a034ae90bc9060200160405180910390a35050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610aad5760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8473ffffffffffffffffffffffffffffffffffffffff168385604051610ad3919061147c565b6000604051808303818686f4925050503d8060008114610b0f576040519150601f19603f3d011682016040523d82523d6000602084013e610b14565b606091505b5091509150935093915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b885760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c365760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6105978147610946565b60038054610c4d90611333565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7990611333565b8015610cc65780601f10610c9b57610100808354040283529160200191610cc6565b820191906000526020600020905b815481529060010190602001808311610ca957829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d355760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610dda908390839073ffffffffffffffffffffffffffffffffffffffff8316906370a082319060240160206040518083038186803b158015610da257600080fd5b505afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102219190611498565b5050565b6000805460609073ffffffffffffffffffffffffffffffffffffffff163314610e495760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8573ffffffffffffffffffffffffffffffffffffffff16848487604051610e70919061147c565b600060405180830381858888f193505050503d8060008114610eae576040519150601f19603f3d011682016040523d82523d6000602084013e610eb3565b606091505b509150915094509492505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f285760405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a4544000000000000000000000000000000000000000060448201526064016103d9565b8051610dda906003906020840190828054610f4290611333565b90600052602060002090601f016020900481019282610f645760008555610faa565b82601f10610f7d57805160ff1916838001178555610faa565b82800160010185558215610faa579182015b82811115610faa578251825591602001919060010190610f8f565b50610fb6929150610fba565b5090565b5b80821115610fb65760008155600101610fbb565b73ffffffffffffffffffffffffffffffffffffffff8116811461059757600080fd5b60006020828403121561100357600080fd5b813561100e81610fcf565b9392505050565b60008060006060848603121561102a57600080fd5b833561103581610fcf565b9250602084013561104581610fcf565b929592945050506040919091013590565b6000806040838503121561106957600080fd5b823561107481610fcf565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126110c257600080fd5b813567ffffffffffffffff808211156110dd576110dd611082565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561112357611123611082565b8160405283815286602085880101111561113c57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561117157600080fd5b833561117c81610fcf565b9250602084013567ffffffffffffffff81111561119857600080fd5b6111a4868287016110b1565b925050604084013590509250925092565b60005b838110156111d05781810151838201526020016111b8565b838111156111df576000848401525b50505050565b600081518084526111fd8160208601602086016111b5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b821515815260406020820152600061124a60408301846111e5565b949350505050565b60208152600061100e60208301846111e5565b6000806040838503121561127857600080fd5b823561128381610fcf565b9150602083013561129381610fcf565b809150509250929050565b600080600080608085870312156112b457600080fd5b84356112bf81610fcf565b9350602085013567ffffffffffffffff8111156112db57600080fd5b6112e7878288016110b1565b949794965050505060408301359260600135919050565b60006020828403121561131057600080fd5b813567ffffffffffffffff81111561132757600080fd5b61124a848285016110b1565b600181811c9082168061134757607f821691505b60208210811415611381577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806113a357607f831692505b60208084108214156113dc577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b8180156113f0576001811461141f5761144c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086168952848901965061144c565b60008a81526020902060005b868110156114445781548b82015290850190830161142b565b505084890196505b509498975050505050505050565b60006020828403121561146c57600080fd5b8151801515811461100e57600080fd5b6000825161148e8184602087016111b5565b9190910192915050565b6000602082840312156114aa57600080fd5b505191905056fea26469706673582212203903a2f3f310c1942ac6f552df9012c64af2d384894531650c63a359397535f364736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {
"CALL(address,bytes,uint256,uint256)": {
"params": {
"_data": "Data to send with the call.",
"_gas": "Amount of gas to send with the call.",
"_target": "Address to call.",
"_value": "ETH value to send with the call."
},
"returns": {
"_0": "Boolean success value.",
"_1": "Bytes data returned by the call."
}
},
"DELEGATECALL(address,bytes,uint256)": {
"params": {
"_data": "Data to send with the call.",
"_gas": "Amount of gas to send with the call.",
"_target": "Address to call."
},
"returns": {
"_0": "Boolean success value.",
"_1": "Bytes data returned by the call."
}
},
"constructor": {
"params": {
"_owner": "Initial owner of the contract."
}
},
"setData(bytes)": {
"params": {
"_data": "New data to be sent to the recipient address."
}
},
"setRecipient(address)": {
"params": {
"_recipient": "New recipient address."
}
},
"setTeleportr(address)": {
"params": {
"_teleportr": "New Teleportr contract address."
}
},
"withdrawERC20(address,address)": {
"params": {
"_asset": "ERC20 token to withdraw.",
"_to": "Address to receive the ERC20 balance."
}
},
"withdrawERC20(address,address,uint256)": {
"params": {
"_amount": "Amount of ERC20 to withdraw.",
"_asset": "ERC20 token to withdraw.",
"_to": "Address to receive the ERC20 balance."
}
},
"withdrawERC721(address,address,uint256)": {
"params": {
"_asset": "ERC721 token to withdraw.",
"_id": "Token ID of the ERC721 token to withdraw.",
"_to": "Address to receive the ERC721 token."
}
},
"withdrawETH(address)": {
"params": {
"_to": "Address to receive the ETH balance."
}
},
"withdrawETH(address,uint256)": {
"params": {
"_amount": "Amount of ETH to withdraw.",
"_to": "Address to receive the ETH balance."
}
}
},
"title": "TeleportrWithdrawer",
"version": 1
},
"userdoc": {
"events": {
"ReceivedETH(address,uint256)": {
"notice": "Emitted when ETH is received by this address."
},
"WithdrewERC20(address,address,address,uint256)": {
"notice": "Emitted when ERC20 tokens are withdrawn from this address."
},
"WithdrewERC721(address,address,address,uint256)": {
"notice": "Emitted when ERC721 tokens are withdrawn from this address."
},
"WithdrewETH(address,address,uint256)": {
"notice": "Emitted when ETH is withdrawn from this address."
}
},
"kind": "user",
"methods": {
"CALL(address,bytes,uint256,uint256)": {
"notice": "Sends a CALL to a target address."
},
"DELEGATECALL(address,bytes,uint256)": {
"notice": "Sends a DELEGATECALL to a target address."
},
"data()": {
"notice": "Data to be sent to the recipient address."
},
"recipient()": {
"notice": "Address that will receive Teleportr withdrawals."
},
"setData(bytes)": {
"notice": "Allows the owner to update the data to be sent to the recipient address."
},
"setRecipient(address)": {
"notice": "Allows the owner to update the recipient address."
},
"setTeleportr(address)": {
"notice": "Allows the owner to update the Teleportr contract address."
},
"teleportr()": {
"notice": "Address of the Teleportr contract."
},
"withdrawERC20(address,address)": {
"notice": "Withdraws full ERC20 balance to the recipient."
},
"withdrawERC20(address,address,uint256)": {
"notice": "Withdraws partial ERC20 balance to the recipient."
},
"withdrawERC721(address,address,uint256)": {
"notice": "Withdraws ERC721 token to the recipient."
},
"withdrawETH(address)": {
"notice": "Withdraws full ETH balance to the recipient."
},
"withdrawETH(address,uint256)": {
"notice": "Withdraws partial ETH balance to the recipient."
},
"withdrawFromTeleportr()": {
"notice": "Withdraws the full balance of the Teleportr contract to the recipient address. Anyone is allowed to trigger this function since the recipient address cannot be controlled by the msg.sender."
}
},
"notice": "The TeleportrWithdrawer is a simple contract capable of withdrawing funds from the TeleportrContract and sending them to some recipient address.",
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 4371,
"contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer",
"label": "owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 6314,
"contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer",
"label": "teleportr",
"offset": 0,
"slot": "1",
"type": "t_address"
},
{
"astId": 6317,
"contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer",
"label": "recipient",
"offset": 0,
"slot": "2",
"type": "t_address"
},
{
"astId": 6320,
"contract": "contracts/universal/TeleportrWithdrawer.sol:TeleportrWithdrawer",
"label": "data",
"offset": 0,
"slot": "3",
"type": "t_bytes_storage"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_bytes_storage": {
"encoding": "bytes",
"label": "bytes",
"numberOfBytes": "32"
}
}
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/testing/helpers/TestERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n constructor() ERC20(\"TEST\", \"TST\", 18) {}\n\n function mint(address to, uint256 value) public {\n _mint(to, value);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * @notice Emitted when ETH is received by this address.\n *\n * @param from Address that sent ETH to this contract.\n * @param amount Amount of ETH received.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * @notice Emitted when ETH is withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param amount ETH amount withdrawn.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param amount ERC20 amount withdrawn.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * @notice Emitted when ERC20 tokens are withdrawn from this address.\n *\n * @param withdrawer Address that triggered the withdrawal.\n * @param recipient Address that received the withdrawal.\n * @param asset Address of the token being withdrawn.\n * @param id Token ID being withdrawn.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * @notice Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * @notice Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * @notice Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n (bool success, ) = _to.call{ value: _amount }(\"\");\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * @notice Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * @notice Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * @notice Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _value ETH value to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n *\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(address _target, bytes memory _data)\n external\n payable\n onlyOwner\n returns (bool, bytes memory)\n {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck)\n * and an execution interval. Drips cannot be executed faster than the execution interval.\n * Drips can trigger arbitrary contract calls where the calling contract is this contract\n * address. Drips can also send ETH value, which makes them ideal for keeping addresses\n * sufficiently funded with ETH. Drippie is designed to be connected with smart contract\n * automation services so that drips can be executed automatically. However, Drippie is\n * specifically designed to be separated from these services so that trust assumptions are\n * better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * @notice Enum representing different status options for a given drip.\n *\n * @custom:value NONE Drip does not exist.\n * @custom:value PAUSED Drip is paused and cannot be executed until reactivated.\n * @custom:value ACTIVE Drip is active and can be executed.\n * @custom:value ARCHIVED Drip is archived and can no longer be executed or reactivated.\n */\n enum DripStatus {\n NONE,\n PAUSED,\n ACTIVE,\n ARCHIVED\n }\n\n /**\n * @notice Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * @notice Represents the configuration for a given drip.\n */\n struct DripConfig {\n bool reentrant;\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * @notice Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n uint256 count;\n }\n\n /**\n * @notice Emitted when a new drip is created.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param config Config for the created drip.\n */\n event DripCreated(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n DripConfig config\n );\n\n /**\n * @notice Emitted when a drip status is updated.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param status New drip status.\n */\n event DripStatusUpdated(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n DripStatus status\n );\n\n /**\n * @notice Emitted when a drip is executed.\n *\n * @param nameref Indexed name parameter (hashed).\n * @param name Unindexed name parameter (unhashed).\n * @param executor Address that executed the drip.\n * @param timestamp Time when the drip was executed.\n */\n event DripExecuted(\n // Emit name twice because indexed version is hashed.\n string indexed nameref,\n string name,\n address executor,\n uint256 timestamp\n );\n\n /**\n * @notice Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * @notice Creates a new drip with the given name and configuration. Once created, drips cannot\n * be modified in any way (this is a security measure). If you want to update a drip,\n * simply pause (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string calldata _name, DripConfig calldata _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // Validate the drip interval, only allowing an interval of zero if the drip has explicitly\n // been marked as reentrant. Prevents client-side bugs making a drip infinitely executable\n // within the same block (of course, restricted by gas limits).\n if (_config.reentrant) {\n require(\n _config.interval == 0,\n \"Drippie: if allowing reentrant drip, must set interval to zero\"\n );\n } else {\n require(\n _config.interval > 0,\n \"Drippie: interval must be greater than zero if drip is not reentrant\"\n );\n }\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.reentrant = _config.reentrant;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _name, _config);\n }\n\n /**\n * @notice Sets the status for a given drip. The behavior of this function depends on the\n * status that the user is trying to set. A drip can always move between ACTIVE and\n * PAUSED, but it can never move back to NONE and once ARCHIVED, it can never move back\n * to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string calldata _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Load the drip status once to avoid unnecessary SLOADs.\n DripStatus curr = drips[_name].status;\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n curr != DripStatus.NONE,\n \"Drippie: drip with that name does not exist and cannot be updated\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n curr != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived and cannot be updated\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n curr != _status,\n \"Drippie: cannot set drip status to the same status as its current status\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n curr == DripStatus.PAUSED,\n \"Drippie: drip must first be paused before being archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, _name, _status);\n }\n\n /**\n * @notice Checks if a given drip is executable.\n *\n * @param _name Drip to check.\n *\n * @return True if the drip is executable, reverts otherwise.\n */\n function executable(string calldata _name) public view returns (bool) {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Alright, we're good to execute.\n return true;\n }\n\n /**\n * @notice Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative\n * signal that the drip should be executable according to the drip parameters, drip\n * check, and drip interval. Note that drip parameters are read entirely from the state\n * and are not supplied as user input, so there should not be any way for a\n * non-authorized user to influence the behavior of the drip. Note that the drip check\n * is executed only **once** at the beginning of the call to the drip function and will\n * not be executed again between the drip actions within this call.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string calldata _name) external {\n DripState storage state = drips[_name];\n\n // Make sure the drip can be executed. Since executable reverts if the drip is not ready to\n // be executed, we don't need to do an assertion that the returned value is true.\n executable(_name);\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Update the number of times this drip has been executed. Although this increases the cost\n // of using Drippie, it slightly simplifies the client-side by not having to worry about\n // counting drips via events. Useful for monitoring the rate of drip execution.\n state.count++;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, _name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n /**\n * @notice Checks whether a drip should be executable.\n *\n * @param _params Encoded parameters for the drip check.\n *\n * @return Whether the drip should be executed.\n */\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n struct Params {\n address target;\n uint256 threshold;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.16;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n struct Params {\n address target;\n uint256 threshold;\n }\n\n /**\n * @notice External event used to help client-side tooling encode parameters.\n *\n * @param params Parameters to encode.\n */\n event _EventToExposeStructInABI__Params(Params params);\n\n /**\n * @inheritdoc IDripCheck\n */\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
},
"contracts/testing/helpers/TestERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n constructor() ERC721(\"TEST\", \"TST\") {}\n\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n function tokenURI(uint256) public pure virtual override returns (string memory) {}\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * Emitted when ETH is received by this address.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * Emitted when ETH is withdrawn from this address.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * Emitted when ERC20 tokens are withdrawn from this address.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * Emitted when ERC721 tokens are withdrawn from this address.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n _to.transfer(_amount);\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @param _value ETH value to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _gas,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ gas: _gas, value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(\n address _target,\n bytes memory _data,\n uint256 _gas\n ) external payable onlyOwner returns (bool, bytes memory) {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall{ gas: _gas }(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck) and an\n * execution interval. Drips cannot be executed faster than the execution interval. Drips can\n * trigger arbitrary contract calls where the calling contract is this contract address. Drips can\n * also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.\n * Drippie is designed to be connected with smart contract automation services so that drips can be\n * executed automatically. However, Drippie is specifically designed to be separated from these\n * services so that trust assumptions are better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * Enum representing different status options for a given drip.\n */\n enum DripStatus {\n NONE,\n ACTIVE,\n PAUSED,\n ARCHIVED\n }\n\n /**\n * Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * Represents the configuration for a given drip.\n */\n struct DripConfig {\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n }\n\n /**\n * Emitted when a new drip is created.\n */\n event DripCreated(string indexed name, DripConfig config);\n\n /**\n * Emitted when a drip status is updated.\n */\n event DripStatusUpdated(string indexed name, DripStatus status);\n\n /**\n * Emitted when a drip is executed.\n */\n event DripExecuted(string indexed name, address indexed executor, uint256 timestamp);\n\n /**\n * Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * Creates a new drip with the given name and configuration. Once created, drips cannot be\n * modified in any way (this is a security measure). If you want to update a drip, simply pause\n * (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _config);\n }\n\n /**\n * Sets the status for a given drip. The behavior of this function depends on the status that\n * the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can\n * never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string memory _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n drips[_name].status != DripStatus.NONE,\n \"Drippie: drip with that name does not exist\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n drips[_name].status != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n drips[_name].status != _status,\n \"Drippie: cannot set drip status to same status as before\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n drips[_name].status == DripStatus.PAUSED,\n \"Drippie: drip must be paused to be archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, drips[_name].status);\n }\n\n /**\n * Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative signal that\n * the drip should be executable according to the drip parameters, drip check, and drip\n * interval. Note that drip parameters are read entirely from the state and are not supplied as\n * user input, so there should not be any way for a non-authorized user to influence the\n * behavior of the drip.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string memory _name) external {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * Emitted when ETH is received by this address.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * Emitted when ETH is withdrawn from this address.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * Emitted when ERC20 tokens are withdrawn from this address.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * Emitted when ERC721 tokens are withdrawn from this address.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n _to.transfer(_amount);\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @param _value ETH value to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _gas,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ gas: _gas, value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(\n address _target,\n bytes memory _data,\n uint256 _gas\n ) external payable onlyOwner returns (bool, bytes memory) {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall{ gas: _gas }(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck) and an\n * execution interval. Drips cannot be executed faster than the execution interval. Drips can\n * trigger arbitrary contract calls where the calling contract is this contract address. Drips can\n * also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.\n * Drippie is designed to be connected with smart contract automation services so that drips can be\n * executed automatically. However, Drippie is specifically designed to be separated from these\n * services so that trust assumptions are better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * Enum representing different status options for a given drip.\n */\n enum DripStatus {\n NONE,\n ACTIVE,\n PAUSED,\n ARCHIVED\n }\n\n /**\n * Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * Represents the configuration for a given drip.\n */\n struct DripConfig {\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n }\n\n /**\n * Emitted when a new drip is created.\n */\n event DripCreated(string indexed name, DripConfig config);\n\n /**\n * Emitted when a drip status is updated.\n */\n event DripStatusUpdated(string indexed name, DripStatus status);\n\n /**\n * Emitted when a drip is executed.\n */\n event DripExecuted(string indexed name, address indexed executor, uint256 timestamp);\n\n /**\n * Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * Creates a new drip with the given name and configuration. Once created, drips cannot be\n * modified in any way (this is a security measure). If you want to update a drip, simply pause\n * (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _config);\n }\n\n /**\n * Sets the status for a given drip. The behavior of this function depends on the status that\n * the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can\n * never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string memory _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n drips[_name].status != DripStatus.NONE,\n \"Drippie: drip with that name does not exist\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n drips[_name].status != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n drips[_name].status != _status,\n \"Drippie: cannot set drip status to same status as before\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n drips[_name].status == DripStatus.PAUSED,\n \"Drippie: drip must be paused to be archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, drips[_name].status);\n }\n\n /**\n * Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative signal that\n * the drip should be executable according to the drip parameters, drip check, and drip\n * interval. Note that drip parameters are read entirely from the state and are not supplied as\n * user input, so there should not be any way for a non-authorized user to influence the\n * behavior of the drip.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string memory _name) external {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"language": "Solidity",
"sources": {
"contracts/universal/op-nft/AttestationStation.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title AttestationStation\n * @author Optimism Collective\n * @author Gitcoin\n * @notice Where attestations live.\n */\ncontract AttestationStation is Semver {\n /**\n * @notice Struct representing data that is being attested.\n *\n * @custom:field about Address for which the attestation is about.\n * @custom:field key A bytes32 key for the attestation.\n * @custom:field val The attestation as arbitrary bytes.\n */\n struct AttestationData {\n address about;\n bytes32 key;\n bytes val;\n }\n\n /**\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\n */\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\n\n /**\n * @notice Emitted when Attestation is created.\n *\n * @param creator Address that made the attestation.\n * @param about Address attestation is about.\n * @param key Key of the attestation.\n * @param val Value of the attestation.\n */\n event AttestationCreated(\n address indexed creator,\n address indexed about,\n bytes32 indexed key,\n bytes val\n );\n\n /**\n * @custom:semver 1.1.0\n */\n constructor() Semver(1, 1, 0) {}\n\n /**\n * @notice Allows anyone to create an attestation.\n *\n * @param _about Address that the attestation is about.\n * @param _key A key used to namespace the attestation.\n * @param _val An arbitrary value stored as part of the attestation.\n */\n function attest(\n address _about,\n bytes32 _key,\n bytes memory _val\n ) public {\n attestations[msg.sender][_about][_key] = _val;\n\n emit AttestationCreated(msg.sender, _about, _key, _val);\n }\n\n /**\n * @notice Allows anyone to create attestations.\n *\n * @param _attestations An array of attestation data.\n */\n function attest(AttestationData[] calldata _attestations) external {\n uint256 length = _attestations.length;\n for (uint256 i = 0; i < length; ) {\n AttestationData memory attestation = _attestations[i];\n\n attest(attestation.about, attestation.key, attestation.val);\n\n unchecked {\n ++i;\n }\n }\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"contracts/universal/op-nft/Optimist.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\nimport {\n ERC721BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport { AttestationStation } from \"./AttestationStation.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @author Optimism Collective\n * @author Gitcoin\n * @title Optimist\n * @notice A Soul Bound Token for real humans only(tm).\n */\ncontract Optimist is ERC721BurnableUpgradeable, Semver {\n /**\n * @notice Address of the AttestationStation contract.\n */\n AttestationStation public immutable ATTESTATION_STATION;\n\n /**\n * @notice Attestor who attests to baseURI and allowlist.\n */\n address public immutable ATTESTOR;\n\n /**\n * @custom:semver 1.0.0\n * @param _name Token name.\n * @param _symbol Token symbol.\n * @param _attestor Address of the attestor.\n * @param _attestationStation Address of the AttestationStation contract.\n */\n constructor(\n string memory _name,\n string memory _symbol,\n address _attestor,\n AttestationStation _attestationStation\n ) Semver(1, 0, 0) {\n ATTESTOR = _attestor;\n ATTESTATION_STATION = _attestationStation;\n initialize(_name, _symbol);\n }\n\n /**\n * @notice Initializes the Optimist contract.\n *\n * @param _name Token name.\n * @param _symbol Token symbol.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __ERC721Burnable_init();\n }\n\n /**\n * @notice Allows an address to mint an Optimist NFT. Token ID is the uint256 representation\n * of the recipient's address. Recipients must be permitted to mint, eventually anyone\n * will be able to mint. One token per address.\n *\n * @param _recipient Address of the token recipient.\n */\n function mint(address _recipient) public {\n require(isOnAllowList(_recipient), \"Optimist: address is not on allowList\");\n _safeMint(_recipient, tokenIdOfAddress(_recipient));\n }\n\n /**\n * @notice Returns the baseURI for all tokens.\n *\n * @return BaseURI for all tokens.\n */\n function baseURI() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n ATTESTATION_STATION.attestations(\n ATTESTOR,\n address(this),\n bytes32(\"optimist.base-uri\")\n )\n )\n );\n }\n\n /**\n * @notice Returns the token URI for a given token by ID\n *\n * @param _tokenId Token ID to query.\n\n * @return Token URI for the given token by ID.\n */\n function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {\n return\n string(\n abi.encodePacked(\n baseURI(),\n \"/\",\n // Properly format the token ID as a 20 byte hex string (address).\n Strings.toHexString(_tokenId, 20),\n \".json\"\n )\n );\n }\n\n /**\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\n * restricted. Eventually anyone will be able to mint.\n *\n * @return Whether or not the address is allowed to mint yet.\n */\n function isOnAllowList(address _recipient) public view returns (bool) {\n return\n ATTESTATION_STATION\n .attestations(ATTESTOR, _recipient, bytes32(\"optimist.can-mint\"))\n .length > 0;\n }\n\n /**\n * @notice Returns the token ID for the token owned by a given address. This is the uint256\n * representation of the given address.\n *\n * @return Token ID for the token owned by the given address.\n */\n function tokenIdOfAddress(address _owner) public pure returns (uint256) {\n return uint256(uint160(_owner));\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function approve(address, uint256) public pure override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function setApprovalForAll(address, bool) public virtual override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Prevents transfers of the Optimist NFT (Soul Bound Token).\n *\n * @param _from Address of the token sender.\n * @param _to Address of the token recipient.\n */\n function _beforeTokenTransfer(\n address _from,\n address _to,\n uint256\n ) internal virtual override {\n require(_from == address(0) || _to == address(0), \"Optimist: soul bound token\");\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/universal/op-nft/AttestationStation.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\n\n/**\n * @title AttestationStation\n * @author Optimism Collective\n * @author Gitcoin\n * @notice Where attestations live.\n */\ncontract AttestationStation is Semver {\n /**\n * @notice Struct representing data that is being attested.\n *\n * @custom:field about Address for which the attestation is about.\n * @custom:field key A bytes32 key for the attestation.\n * @custom:field val The attestation as arbitrary bytes.\n */\n struct AttestationData {\n address about;\n bytes32 key;\n bytes val;\n }\n\n /**\n * @notice Maps addresses to attestations. Creator => About => Key => Value.\n */\n mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;\n\n /**\n * @notice Emitted when Attestation is created.\n *\n * @param creator Address that made the attestation.\n * @param about Address attestation is about.\n * @param key Key of the attestation.\n * @param val Value of the attestation.\n */\n event AttestationCreated(\n address indexed creator,\n address indexed about,\n bytes32 indexed key,\n bytes val\n );\n\n /**\n * @custom:semver 1.1.0\n */\n constructor() Semver(1, 1, 0) {}\n\n /**\n * @notice Allows anyone to create an attestation.\n *\n * @param _about Address that the attestation is about.\n * @param _key A key used to namespace the attestation.\n * @param _val An arbitrary value stored as part of the attestation.\n */\n function attest(\n address _about,\n bytes32 _key,\n bytes memory _val\n ) public {\n attestations[msg.sender][_about][_key] = _val;\n\n emit AttestationCreated(msg.sender, _about, _key, _val);\n }\n\n /**\n * @notice Allows anyone to create attestations.\n *\n * @param _attestations An array of attestation data.\n */\n function attest(AttestationData[] calldata _attestations) external {\n uint256 length = _attestations.length;\n for (uint256 i = 0; i < length; ) {\n AttestationData memory attestation = _attestations[i];\n\n attest(attestation.about, attestation.key, attestation.val);\n\n unchecked {\n ++i;\n }\n }\n }\n}\n"
},
"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.15;\n\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title Semver\n * @notice Semver is a simple contract for managing contract versions.\n */\ncontract Semver {\n /**\n * @notice Contract version number (major).\n */\n uint256 private immutable MAJOR_VERSION;\n\n /**\n * @notice Contract version number (minor).\n */\n uint256 private immutable MINOR_VERSION;\n\n /**\n * @notice Contract version number (patch).\n */\n uint256 private immutable PATCH_VERSION;\n\n /**\n * @param _major Version number (major).\n * @param _minor Version number (minor).\n * @param _patch Version number (patch).\n */\n constructor(\n uint256 _major,\n uint256 _minor,\n uint256 _patch\n ) {\n MAJOR_VERSION = _major;\n MINOR_VERSION = _minor;\n PATCH_VERSION = _patch;\n }\n\n /**\n * @notice Returns the full semver contract version.\n *\n * @return Semver contract version as a string.\n */\n function version() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n Strings.toString(MAJOR_VERSION),\n \".\",\n Strings.toString(MINOR_VERSION),\n \".\",\n Strings.toString(PATCH_VERSION)\n )\n );\n }\n}\n"
},
"@openzeppelin/contracts/utils/Strings.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"contracts/universal/op-nft/Optimist.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.15;\n\nimport { Semver } from \"@eth-optimism/contracts-bedrock/contracts/universal/Semver.sol\";\nimport {\n ERC721BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol\";\nimport { AttestationStation } from \"./AttestationStation.sol\";\nimport { Strings } from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @author Optimism Collective\n * @author Gitcoin\n * @title Optimist\n * @notice A Soul Bound Token for real humans only(tm).\n */\ncontract Optimist is ERC721BurnableUpgradeable, Semver {\n /**\n * @notice Address of the AttestationStation contract.\n */\n AttestationStation public immutable ATTESTATION_STATION;\n\n /**\n * @notice Attestor who attests to baseURI and allowlist.\n */\n address public immutable ATTESTOR;\n\n /**\n * @custom:semver 1.0.0\n * @param _name Token name.\n * @param _symbol Token symbol.\n * @param _attestor Address of the attestor.\n * @param _attestationStation Address of the AttestationStation contract.\n */\n constructor(\n string memory _name,\n string memory _symbol,\n address _attestor,\n AttestationStation _attestationStation\n ) Semver(1, 0, 0) {\n ATTESTOR = _attestor;\n ATTESTATION_STATION = _attestationStation;\n initialize(_name, _symbol);\n }\n\n /**\n * @notice Initializes the Optimist contract.\n *\n * @param _name Token name.\n * @param _symbol Token symbol.\n */\n function initialize(string memory _name, string memory _symbol) public initializer {\n __ERC721_init(_name, _symbol);\n __ERC721Burnable_init();\n }\n\n /**\n * @notice Allows an address to mint an Optimist NFT. Token ID is the uint256 representation\n * of the recipient's address. Recipients must be permitted to mint, eventually anyone\n * will be able to mint. One token per address.\n *\n * @param _recipient Address of the token recipient.\n */\n function mint(address _recipient) public {\n require(isOnAllowList(_recipient), \"Optimist: address is not on allowList\");\n _safeMint(_recipient, tokenIdOfAddress(_recipient));\n }\n\n /**\n * @notice Returns the baseURI for all tokens.\n *\n * @return BaseURI for all tokens.\n */\n function baseURI() public view returns (string memory) {\n return\n string(\n abi.encodePacked(\n ATTESTATION_STATION.attestations(\n ATTESTOR,\n address(this),\n bytes32(\"optimist.base-uri\")\n )\n )\n );\n }\n\n /**\n * @notice Returns the token URI for a given token by ID\n *\n * @param _tokenId Token ID to query.\n\n * @return Token URI for the given token by ID.\n */\n function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {\n return\n string(\n abi.encodePacked(\n baseURI(),\n \"/\",\n // Properly format the token ID as a 20 byte hex string (address).\n Strings.toHexString(_tokenId, 20),\n \".json\"\n )\n );\n }\n\n /**\n * @notice Checks whether a given address is allowed to mint the Optimist NFT yet. Since the\n * Optimist NFT will also be used as part of the Citizens House, mints are currently\n * restricted. Eventually anyone will be able to mint.\n *\n * @return Whether or not the address is allowed to mint yet.\n */\n function isOnAllowList(address _recipient) public view returns (bool) {\n return\n ATTESTATION_STATION\n .attestations(ATTESTOR, _recipient, bytes32(\"optimist.can-mint\"))\n .length > 0;\n }\n\n /**\n * @notice Returns the token ID for the token owned by a given address. This is the uint256\n * representation of the given address.\n *\n * @return Token ID for the token owned by the given address.\n */\n function tokenIdOfAddress(address _owner) public pure returns (uint256) {\n return uint256(uint160(_owner));\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function approve(address, uint256) public pure override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Disabled for the Optimist NFT (Soul Bound Token).\n */\n function setApprovalForAll(address, bool) public virtual override {\n revert(\"Optimist: soul bound token\");\n }\n\n /**\n * @notice Prevents transfers of the Optimist NFT (Soul Bound Token).\n *\n * @param _from Address of the token sender.\n * @param _to Address of the token recipient.\n */\n function _beforeTokenTransfer(\n address _from,\n address _to,\n uint256\n ) internal virtual override {\n require(_from == address(0) || _to == address(0), \"Optimist: soul bound token\");\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC721Upgradeable.sol\";\nimport \"../../../utils/ContextUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n function __ERC721Burnable_init() internal onlyInitializing {\n }\n\n function __ERC721Burnable_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev Burns `tokenId`. See {ERC721-_burn}.\n *\n * Requirements:\n *\n * - The caller must own `tokenId` or be an approved operator.\n */\n function burn(uint256 tokenId) public virtual {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _burn(tokenId);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
},
"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"language": "Solidity",
"sources": {
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * Emitted when ETH is received by this address.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * Emitted when ETH is withdrawn from this address.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * Emitted when ERC20 tokens are withdrawn from this address.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * Emitted when ERC721 tokens are withdrawn from this address.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n _to.transfer(_amount);\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n if (to.code.length != 0)\n require(\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @param _value ETH value to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _gas,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ gas: _gas, value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(\n address _target,\n bytes memory _data,\n uint256 _gas\n ) external payable onlyOwner returns (bool, bytes memory) {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall{ gas: _gas }(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck) and an\n * execution interval. Drips cannot be executed faster than the execution interval. Drips can\n * trigger arbitrary contract calls where the calling contract is this contract address. Drips can\n * also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.\n * Drippie is designed to be connected with smart contract automation services so that drips can be\n * executed automatically. However, Drippie is specifically designed to be separated from these\n * services so that trust assumptions are better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * Enum representing different status options for a given drip.\n */\n enum DripStatus {\n NONE,\n ACTIVE,\n PAUSED,\n ARCHIVED\n }\n\n /**\n * Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * Represents the configuration for a given drip.\n */\n struct DripConfig {\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n }\n\n /**\n * Emitted when a new drip is created.\n */\n event DripCreated(string indexed name, DripConfig config);\n\n /**\n * Emitted when a drip status is updated.\n */\n event DripStatusUpdated(string indexed name, DripStatus status);\n\n /**\n * Emitted when a drip is executed.\n */\n event DripExecuted(string indexed name, address indexed executor, uint256 timestamp);\n\n /**\n * Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * Creates a new drip with the given name and configuration. Once created, drips cannot be\n * modified in any way (this is a security measure). If you want to update a drip, simply pause\n * (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _config);\n }\n\n /**\n * Sets the status for a given drip. The behavior of this function depends on the status that\n * the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can\n * never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string memory _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n drips[_name].status != DripStatus.NONE,\n \"Drippie: drip with that name does not exist\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n drips[_name].status != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n drips[_name].status != _status,\n \"Drippie: cannot set drip status to same status as before\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n drips[_name].status == DripStatus.PAUSED,\n \"Drippie: drip must be paused to be archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, drips[_name].status);\n }\n\n /**\n * Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative signal that\n * the drip should be executable according to the drip parameters, drip check, and drip\n * interval. Note that drip parameters are read entirely from the state and are not supplied as\n * user input, so there should not be any way for a non-authorized user to influence the\n * behavior of the drip.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string memory _name) external {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
{
"language": "Solidity",
"sources": {
"contracts/universal/AssetReceiver.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { ERC20 } from \"@rari-capital/solmate/src/tokens/ERC20.sol\";\nimport { ERC721 } from \"@rari-capital/solmate/src/tokens/ERC721.sol\";\nimport { Transactor } from \"./Transactor.sol\";\n\n/**\n * @title AssetReceiver\n * @notice AssetReceiver is a minimal contract for receiving funds assets in the form of either\n * ETH, ERC20 tokens, or ERC721 tokens. Only the contract owner may withdraw the assets.\n */\ncontract AssetReceiver is Transactor {\n /**\n * Emitted when ETH is received by this address.\n */\n event ReceivedETH(address indexed from, uint256 amount);\n\n /**\n * Emitted when ETH is withdrawn from this address.\n */\n event WithdrewETH(address indexed withdrawer, address indexed recipient, uint256 amount);\n\n /**\n * Emitted when ERC20 tokens are withdrawn from this address.\n */\n event WithdrewERC20(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 amount\n );\n\n /**\n * Emitted when ERC721 tokens are withdrawn from this address.\n */\n event WithdrewERC721(\n address indexed withdrawer,\n address indexed recipient,\n address indexed asset,\n uint256 id\n );\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Transactor(_owner) {}\n\n /**\n * Make sure we can receive ETH.\n */\n receive() external payable {\n emit ReceivedETH(msg.sender, msg.value);\n }\n\n /**\n * Withdraws full ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n */\n function withdrawETH(address payable _to) external onlyOwner {\n withdrawETH(_to, address(this).balance);\n }\n\n /**\n * Withdraws partial ETH balance to the recipient.\n *\n * @param _to Address to receive the ETH balance.\n * @param _amount Amount of ETH to withdraw.\n */\n function withdrawETH(address payable _to, uint256 _amount) public onlyOwner {\n // slither-disable-next-line reentrancy-unlimited-gas\n _to.transfer(_amount);\n emit WithdrewETH(msg.sender, _to, _amount);\n }\n\n /**\n * Withdraws full ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n */\n function withdrawERC20(ERC20 _asset, address _to) external onlyOwner {\n withdrawERC20(_asset, _to, _asset.balanceOf(address(this)));\n }\n\n /**\n * Withdraws partial ERC20 balance to the recipient.\n *\n * @param _asset ERC20 token to withdraw.\n * @param _to Address to receive the ERC20 balance.\n * @param _amount Amount of ERC20 to withdraw.\n */\n function withdrawERC20(\n ERC20 _asset,\n address _to,\n uint256 _amount\n ) public onlyOwner {\n // slither-disable-next-line unchecked-transfer\n _asset.transfer(_to, _amount);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC20(msg.sender, _to, address(_asset), _amount);\n }\n\n /**\n * Withdraws ERC721 token to the recipient.\n *\n * @param _asset ERC721 token to withdraw.\n * @param _to Address to receive the ERC721 token.\n * @param _id Token ID of the ERC721 token to withdraw.\n */\n function withdrawERC721(\n ERC721 _asset,\n address _to,\n uint256 _id\n ) external onlyOwner {\n _asset.transferFrom(address(this), _to, _id);\n // slither-disable-next-line reentrancy-events\n emit WithdrewERC721(msg.sender, _to, address(_asset), _id);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC20.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n uint8 public immutable decimals;\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 public totalSupply;\n\n mapping(address => uint256) public balanceOf;\n\n mapping(address => mapping(address => uint256)) public allowance;\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal immutable INITIAL_CHAIN_ID;\n\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(\n string memory _name,\n string memory _symbol,\n uint8 _decimals\n ) {\n name = _name;\n symbol = _symbol;\n decimals = _decimals;\n\n INITIAL_CHAIN_ID = block.chainid;\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual returns (bool) {\n allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual returns (bool) {\n balanceOf[msg.sender] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual returns (bool) {\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n balanceOf[from] -= amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n // Unchecked because the only math done is incrementing\n // the owner's nonce which cannot realistically overflow.\n unchecked {\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n ),\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n ),\n v,\n r,\n s\n );\n\n require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n allowance[recoveredAddress][spender] = value;\n }\n\n emit Approval(owner, spender, value);\n }\n\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n }\n\n function computeDomainSeparator() internal view virtual returns (bytes32) {\n return\n keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name)),\n keccak256(\"1\"),\n block.chainid,\n address(this)\n )\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 amount) internal virtual {\n totalSupply += amount;\n\n // Cannot overflow because the sum of all user\n // balances can't exceed the max uint256 value.\n unchecked {\n balanceOf[to] += amount;\n }\n\n emit Transfer(address(0), to, amount);\n }\n\n function _burn(address from, uint256 amount) internal virtual {\n balanceOf[from] -= amount;\n\n // Cannot underflow because a user's balance\n // will never be larger than the total supply.\n unchecked {\n totalSupply -= amount;\n }\n\n emit Transfer(from, address(0), amount);\n }\n}\n"
},
"@rari-capital/solmate/src/tokens/ERC721.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721 {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event Transfer(address indexed from, address indexed to, uint256 indexed id);\n\n event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string public name;\n\n string public symbol;\n\n function tokenURI(uint256 id) public view virtual returns (string memory);\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) public getApproved;\n\n mapping(address => mapping(address => bool)) public isApprovedForAll;\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(string memory _name, string memory _symbol) {\n name = _name;\n symbol = _symbol;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public virtual {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual {\n isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n unchecked {\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n delete getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n bytes calldata data\n ) public virtual {\n transferFrom(from, to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC165 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return\n interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165\n interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721\n interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL MINT/BURN LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _mint(address to, uint256 id) internal virtual {\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(_ownerOf[id] == address(0), \"ALREADY_MINTED\");\n\n // Counter overflow is incredibly unrealistic.\n unchecked {\n _balanceOf[to]++;\n }\n\n _ownerOf[id] = to;\n\n emit Transfer(address(0), to, id);\n }\n\n function _burn(uint256 id) internal virtual {\n address owner = _ownerOf[id];\n\n require(owner != address(0), \"NOT_MINTED\");\n\n // Ownership check above ensures no underflow.\n unchecked {\n _balanceOf[owner]--;\n }\n\n delete _ownerOf[id];\n\n delete getApproved[id];\n\n emit Transfer(owner, address(0), id);\n }\n\n /*//////////////////////////////////////////////////////////////\n INTERNAL SAFE MINT LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function _safeMint(address to, uint256 id) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, \"\") ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function _safeMint(\n address to,\n uint256 id,\n bytes memory data\n ) internal virtual {\n _mint(to, id);\n\n require(\n to.code.length == 0 ||\n ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==\n ERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n}\n\n/// @notice A generic interface for a contract which properly accepts ERC721 tokens.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)\nabstract contract ERC721TokenReceiver {\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external virtual returns (bytes4) {\n return ERC721TokenReceiver.onERC721Received.selector;\n }\n}\n"
},
"contracts/universal/Transactor.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { Owned } from \"@rari-capital/solmate/src/auth/Owned.sol\";\n\n/**\n * @title Transactor\n * @notice Transactor is a minimal contract that can send transactions.\n */\ncontract Transactor is Owned {\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) Owned(_owner) {}\n\n /**\n * Sends a CALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @param _value ETH value to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function CALL(\n address _target,\n bytes memory _data,\n uint256 _gas,\n uint256 _value\n ) external payable onlyOwner returns (bool, bytes memory) {\n return _target.call{ gas: _gas, value: _value }(_data);\n }\n\n /**\n * Sends a DELEGATECALL to a target address.\n *\n * @param _target Address to call.\n * @param _data Data to send with the call.\n * @param _gas Amount of gas to send with the call.\n * @return Boolean success value.\n * @return Bytes data returned by the call.\n */\n function DELEGATECALL(\n address _target,\n bytes memory _data,\n uint256 _gas\n ) external payable onlyOwner returns (bool, bytes memory) {\n // slither-disable-next-line controlled-delegatecall\n return _target.delegatecall{ gas: _gas }(_data);\n }\n}\n"
},
"@rari-capital/solmate/src/auth/Owned.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Simple single owner authorization mixin.\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Owned.sol)\nabstract contract Owned {\n /*//////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////*/\n\n event OwnerUpdated(address indexed user, address indexed newOwner);\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP STORAGE\n //////////////////////////////////////////////////////////////*/\n\n address public owner;\n\n modifier onlyOwner() virtual {\n require(msg.sender == owner, \"UNAUTHORIZED\");\n\n _;\n }\n\n /*//////////////////////////////////////////////////////////////\n CONSTRUCTOR\n //////////////////////////////////////////////////////////////*/\n\n constructor(address _owner) {\n owner = _owner;\n\n emit OwnerUpdated(address(0), _owner);\n }\n\n /*//////////////////////////////////////////////////////////////\n OWNERSHIP LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function setOwner(address newOwner) public virtual onlyOwner {\n owner = newOwner;\n\n emit OwnerUpdated(msg.sender, newOwner);\n }\n}\n"
},
"contracts/universal/drippie/Drippie.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { AssetReceiver } from \"../AssetReceiver.sol\";\nimport { IDripCheck } from \"./IDripCheck.sol\";\n\n/**\n * @title Drippie\n * @notice Drippie is a system for managing automated contract interactions. A specific interaction\n * is called a \"drip\" and can be executed according to some condition (called a dripcheck) and an\n * execution interval. Drips cannot be executed faster than the execution interval. Drips can\n * trigger arbitrary contract calls where the calling contract is this contract address. Drips can\n * also send ETH value, which makes them ideal for keeping addresses sufficiently funded with ETH.\n * Drippie is designed to be connected with smart contract automation services so that drips can be\n * executed automatically. However, Drippie is specifically designed to be separated from these\n * services so that trust assumptions are better compartmentalized.\n */\ncontract Drippie is AssetReceiver {\n /**\n * Enum representing different status options for a given drip.\n */\n enum DripStatus {\n NONE,\n ACTIVE,\n PAUSED,\n ARCHIVED\n }\n\n /**\n * Represents a drip action.\n */\n struct DripAction {\n address payable target;\n bytes data;\n uint256 value;\n }\n\n /**\n * Represents the configuration for a given drip.\n */\n struct DripConfig {\n uint256 interval;\n IDripCheck dripcheck;\n bytes checkparams;\n DripAction[] actions;\n }\n\n /**\n * Represents the state of an active drip.\n */\n struct DripState {\n DripStatus status;\n DripConfig config;\n uint256 last;\n }\n\n /**\n * Emitted when a new drip is created.\n */\n event DripCreated(string indexed name, DripConfig config);\n\n /**\n * Emitted when a drip status is updated.\n */\n event DripStatusUpdated(string indexed name, DripStatus status);\n\n /**\n * Emitted when a drip is executed.\n */\n event DripExecuted(string indexed name, address indexed executor, uint256 timestamp);\n\n /**\n * Maps from drip names to drip states.\n */\n mapping(string => DripState) public drips;\n\n /**\n * @param _owner Initial contract owner.\n */\n constructor(address _owner) AssetReceiver(_owner) {}\n\n /**\n * Creates a new drip with the given name and configuration. Once created, drips cannot be\n * modified in any way (this is a security measure). If you want to update a drip, simply pause\n * (and potentially archive) the existing drip and create a new one.\n *\n * @param _name Name of the drip.\n * @param _config Configuration for the drip.\n */\n function create(string memory _name, DripConfig memory _config) external onlyOwner {\n // Make sure this drip doesn't already exist. We *must* guarantee that no other function\n // will ever set the status of a drip back to NONE after it's been created. This is why\n // archival is a separate status.\n require(\n drips[_name].status == DripStatus.NONE,\n \"Drippie: drip with that name already exists\"\n );\n\n // We initialize this way because Solidity won't let us copy arrays into storage yet.\n DripState storage state = drips[_name];\n state.status = DripStatus.PAUSED;\n state.config.interval = _config.interval;\n state.config.dripcheck = _config.dripcheck;\n state.config.checkparams = _config.checkparams;\n\n // Solidity doesn't let us copy arrays into storage, so we push each array one by one.\n for (uint256 i = 0; i < _config.actions.length; i++) {\n state.config.actions.push(_config.actions[i]);\n }\n\n // Tell the world!\n emit DripCreated(_name, _config);\n }\n\n /**\n * Sets the status for a given drip. The behavior of this function depends on the status that\n * the user is trying to set. A drip can always move between ACTIVE and PAUSED, but it can\n * never move back to NONE and once ARCHIVED, it can never move back to ACTIVE or PAUSED.\n *\n * @param _name Name of the drip to update.\n * @param _status New drip status.\n */\n function status(string memory _name, DripStatus _status) external onlyOwner {\n // Make sure we can never set drip status back to NONE. A simple security measure to\n // prevent accidental overwrites if this code is ever updated down the line.\n require(\n _status != DripStatus.NONE,\n \"Drippie: drip status can never be set back to NONE after creation\"\n );\n\n // Make sure the drip in question actually exists. Not strictly necessary but there doesn't\n // seem to be any clear reason why you would want to do this, and it may save some gas in\n // the case of a front-end bug.\n require(\n drips[_name].status != DripStatus.NONE,\n \"Drippie: drip with that name does not exist\"\n );\n\n // Once a drip has been archived, it cannot be un-archived. This is, after all, the entire\n // point of archiving a drip.\n require(\n drips[_name].status != DripStatus.ARCHIVED,\n \"Drippie: drip with that name has been archived\"\n );\n\n // Although not strictly necessary, we make sure that the status here is actually changing.\n // This may save the client some gas if there's a front-end bug and the user accidentally\n // tries to \"change\" the status to the same value as before.\n require(\n drips[_name].status != _status,\n \"Drippie: cannot set drip status to same status as before\"\n );\n\n // If the user is trying to archive this drip, make sure the drip has been paused. We do\n // not allow users to archive active drips so that the effects of this action are more\n // abundantly clear.\n if (_status == DripStatus.ARCHIVED) {\n require(\n drips[_name].status == DripStatus.PAUSED,\n \"Drippie: drip must be paused to be archived\"\n );\n }\n\n // If we made it here then we can safely update the status.\n drips[_name].status = _status;\n emit DripStatusUpdated(_name, drips[_name].status);\n }\n\n /**\n * Triggers a drip. This function is deliberately left as a public function because the\n * assumption being made here is that setting the drip to ACTIVE is an affirmative signal that\n * the drip should be executable according to the drip parameters, drip check, and drip\n * interval. Note that drip parameters are read entirely from the state and are not supplied as\n * user input, so there should not be any way for a non-authorized user to influence the\n * behavior of the drip.\n *\n * @param _name Name of the drip to trigger.\n */\n function drip(string memory _name) external {\n DripState storage state = drips[_name];\n\n // Only allow active drips to be executed, an obvious security measure.\n require(\n state.status == DripStatus.ACTIVE,\n \"Drippie: selected drip does not exist or is not currently active\"\n );\n\n // Don't drip if the drip interval has not yet elapsed since the last time we dripped. This\n // is a safety measure that prevents a malicious recipient from, e.g., spending all of\n // their funds and repeatedly requesting new drips. Limits the potential impact of a\n // compromised recipient to just a single drip interval, after which the drip can be paused\n // by the owner address.\n require(\n state.last + state.config.interval <= block.timestamp,\n \"Drippie: drip interval has not elapsed since last drip\"\n );\n\n // Make sure we're allowed to execute this drip.\n require(\n state.config.dripcheck.check(state.config.checkparams),\n \"Drippie: dripcheck failed so drip is not yet ready to be triggered\"\n );\n\n // Update the last execution time for this drip before the call. Note that it's entirely\n // possible for a drip to be executed multiple times per block or even multiple times\n // within the same transaction (via re-entrancy) if the drip interval is set to zero. Users\n // should set a drip interval of 1 if they'd like the drip to be executed only once per\n // block (since this will then prevent re-entrancy).\n state.last = block.timestamp;\n\n // Execute each action in the drip. We allow drips to have multiple actions because there\n // are scenarios in which a contract must do multiple things atomically. For example, the\n // contract may need to withdraw ETH from one account and then deposit that ETH into\n // another account within the same transaction.\n uint256 len = state.config.actions.length;\n for (uint256 i = 0; i < len; i++) {\n // Must be marked as \"storage\" because copying structs into memory is not yet supported\n // by Solidity. Won't significantly reduce gas costs but at least makes it easier to\n // read what the rest of this section is doing.\n DripAction storage action = state.config.actions[i];\n\n // Actually execute the action. We could use ExcessivelySafeCall here but not strictly\n // necessary (worst case, a drip gets bricked IFF the target is malicious, doubt this\n // will ever happen in practice). Could save a marginal amount of gas to ignore the\n // returndata.\n // slither-disable-next-line calls-loop\n (bool success, ) = action.target.call{ value: action.value }(action.data);\n\n // Generally should not happen, but could if there's a misconfiguration (e.g., passing\n // the wrong data to the target contract), the recipient is not payable, or\n // insufficient gas was supplied to this transaction. We revert so the drip can be\n // fixed and triggered again later. Means we cannot emit an event to alert of the\n // failure, but can reasonably be detected by off-chain services even without an event.\n // Note that this forces the drip executor to supply sufficient gas to the call\n // (assuming there is some sufficient gas limit that exists, otherwise the drip will\n // not execute).\n require(\n success,\n \"Drippie: drip was unsuccessful, please check your configuration for mistakes\"\n );\n }\n\n emit DripExecuted(_name, msg.sender, block.timestamp);\n }\n}\n"
},
"contracts/universal/drippie/IDripCheck.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ninterface IDripCheck {\n // DripCheck contracts that want to take parameters as inputs MUST expose a struct called\n // Params and an event _EventForExposingParamsStructInABI(Params params). This makes it\n // possible to easily encode parameters on the client side. Solidity does not support generics\n // so it's not possible to do this with explicit typing.\n\n function check(bytes memory _params) external view returns (bool);\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckTrue.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckTrue\n * @notice DripCheck that always returns true.\n */\ncontract CheckTrue is IDripCheck {\n function check(bytes memory) external pure returns (bool) {\n return true;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckGelatoLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\ninterface IGelatoTreasury {\n function userTokenBalance(address _user, address _token) external view returns (uint256);\n}\n\n/**\n * @title CheckGelatoLow\n * @notice DripCheck for checking if an account's Gelato ETH balance is below some threshold.\n */\ncontract CheckGelatoLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address treasury;\n uint256 threshold;\n address recipient;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check GelatoTreasury ETH balance is below threshold.\n return\n IGelatoTreasury(params.treasury).userTokenBalance(\n params.recipient,\n // Gelato represents ETH as 0xeeeee....eeeee\n 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\n ) < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceLow.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceLow\n * @notice DripCheck for checking if an account's balance is below a given threshold.\n */\ncontract CheckBalanceLow is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target ETH balance is below threshold.\n return params.target.balance < params.threshold;\n }\n}\n"
},
"contracts/universal/drippie/dripchecks/CheckBalanceHigh.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\nimport { IDripCheck } from \"../IDripCheck.sol\";\n\n/**\n * @title CheckBalanceHigh\n * @notice DripCheck for checking if an account's balance is above a given threshold.\n */\ncontract CheckBalanceHigh is IDripCheck {\n event _EventToExposeStructInABI__Params(Params params);\n struct Params {\n address target;\n uint256 threshold;\n }\n\n function check(bytes memory _params) external view returns (bool) {\n Params memory params = abi.decode(_params, (Params));\n\n // Check target balance is above threshold.\n return params.target.balance > params.threshold;\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 10000
},
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
[profile.default]
# The source directory
src = 'contracts/universal'
# The test directory
test = 'contracts/foundry-tests'
# We need to build seperate artifacts for forge and hh, because they each expect a different
# structure for the artifacts directory.
# The artifact directory
out = 'forge-artifacts'
# Enables or disables the optimizer
optimizer = true
# The number of optimizer runs
optimizer_runs = 200
# A list of remappings
remappings = [
'@rari-capital/solmate/=node_modules/@rari-capital/solmate',
'forge-std/=node_modules/forge-std/src',
'ds-test/=node_modules/ds-test/src',
'multicall/=lib/multicall',
'@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/',
'@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/',
'@eth-optimism/contracts-bedrock/=node_modules/@eth-optimism/contracts-bedrock',
]
allow_paths = ["../../node_modules", "./**"]
# The metadata hash can be removed from the bytecode by setting "none"
bytecode_hash = "none"
libs = ["node_modules", "lib"]
# Required to use `deployCode` to deploy the multicall contract which has incompatible version
fs_permissions = [{ access = "read", path = "./forge-artifacts/Multicall3.sol/Multicall3.json"}]
import assert from 'assert'
import { HardhatUserConfig, subtask } from 'hardhat/config'
import { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } from 'hardhat/builtin-tasks/task-names'
import { getenv } from '@eth-optimism/core-utils'
import * as dotenv from 'dotenv'
import { configSpec } from './src/config/deploy'
// Hardhat plugins
import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-waffle'
import '@nomiclabs/hardhat-etherscan'
import '@eth-optimism/hardhat-deploy-config'
import '@typechain/hardhat'
import 'solidity-coverage'
import 'hardhat-gas-reporter'
import 'hardhat-deploy'
// Hardhat tasks
import './tasks'
// Load environment variables from .env
dotenv.config()
subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(
async (_, __, runSuper) => {
const paths = await runSuper()
return paths.filter((p: string) => !p.endsWith('.t.sol'))
}
)
assert(
!(getenv('PRIVATE_KEY') && getenv('LEDGER_ADDRESS')),
'use only one of PRIVATE_KEY or LEDGER_ADDRESS'
)
const accounts = getenv('PRIVATE_KEY')
? [getenv('PRIVATE_KEY')]
: (undefined as any)
const config: HardhatUserConfig = {
networks: {
optimism: {
chainId: 10,
url: 'https://mainnet.optimism.io',
accounts,
verify: {
etherscan: {
apiKey: getenv('OPTIMISTIC_ETHERSCAN_API_KEY'),
},
},
companionNetworks: {
l1: 'mainnet',
},
},
'optimism-goerli': {
chainId: 420,
url: 'https://goerli.optimism.io',
accounts,
verify: {
etherscan: {
apiKey: getenv('OPTIMISTIC_ETHERSCAN_API_KEY'),
},
},
companionNetworks: {
l1: 'goerli',
},
},
mainnet: {
chainId: 1,
url: `https://mainnet.infura.io/v3/${getenv('INFURA_PROJECT_ID')}`,
accounts,
verify: {
etherscan: {
apiKey: getenv('ETHEREUM_ETHERSCAN_API_KEY'),
},
},
companionNetworks: {
l2: 'optimism',
},
},
goerli: {
chainId: 5,
url: `https://goerli.infura.io/v3/${getenv('INFURA_PROJECT_ID')}`,
accounts,
verify: {
etherscan: {
apiKey: getenv('ETHEREUM_ETHERSCAN_API_KEY'),
},
},
companionNetworks: {
l2: 'optimism-goerli',
},
},
ropsten: {
chainId: 3,
url: `https://ropsten.infura.io/v3/${getenv('INFURA_PROJECT_ID')}`,
accounts,
verify: {
etherscan: {
apiKey: getenv('ETHEREUM_ETHERSCAN_API_KEY'),
},
},
},
'ops-l2': {
chainId: 17,
accounts: [
'0x3b8d2345102cce2443acb240db6e87c8edd4bb3f821b17fab8ea2c9da08ea132',
'0xa6aecc98b63bafb0de3b29ae9964b14acb4086057808be29f90150214ebd4a0f',
],
url: 'http://127.0.0.1:8545',
companionNetworks: {
l1: 'ops-l1',
},
},
'ops-l1': {
chainId: 31337,
accounts: [
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
],
url: 'http://127.0.0.1:9545',
companionNetworks: {
l2: 'ops-l2',
},
},
},
paths: {
deployConfig: './config/deploy',
},
external: {
contracts: [
{
artifacts: '../contracts/artifacts',
},
],
deployments: {
goerli: ['../contracts/deployments/goerli'],
mainnet: ['../contracts/deployments/mainnet'],
},
},
deployConfigSpec: configSpec,
mocha: {
timeout: 50000,
},
typechain: {
outDir: 'dist/types',
target: 'ethers-v5',
},
solidity: {
compilers: [
{
version: '0.8.16',
settings: {
optimizer: { enabled: true, runs: 10_000 },
},
},
{
version: '0.8.15',
settings: {
optimizer: { enabled: true, runs: 10_000 },
},
},
],
settings: {
metadata: {
bytecodeHash: 'none',
},
outputSelection: {
'*': {
'*': ['metadata', 'storageLayout'],
},
},
},
},
namedAccounts: {
deployer: {
default: getenv('LEDGER_ADDRESS')
? `ledger://${getenv('LEDGER_ADDRESS')}`
: 0,
hardhat: 0,
},
},
}
export default config
Subproject commit a1fa0644fa412cd3237ef7081458ecb2ffad7dbe
{
"name": "@eth-optimism/contracts-periphery",
"version": "1.0.8",
"description": "[Optimism] External (out-of-protocol) L1 and L2 smart contracts for Optimism",
"main": "dist/index",
"types": "dist/index",
"files": [
"dist/**/*.js",
"dist/**/*.d.ts",
"dist/types",
"artifacts/contracts/**/*.json",
"deployments/**/*.json",
"contracts"
],
"scripts": {
"build": "pnpm build:hh",
"build:hh": "hardhat compile --show-stack-traces",
"build:forge": "forge build",
"test": "pnpm test:forge",
"test:forge": "forge test",
"test:coverage": "pnpm test:coverage:forge",
"test:coverage:forge": "forge coverage",
"test:slither": "slither .",
"gas-snapshot": "forge snapshot",
"pretest:slither": "rm -f @openzeppelin && rm -f hardhat && ln -s node_modules/@openzeppelin @openzeppelin && ln -s ../../node_modules/hardhat hardhat",
"posttest:slither": "rm -f @openzeppelin && rm -f hardhat",
"lint:ts:check": "eslint . --max-warnings=0",
"lint:contracts:check": "pnpm solhint -f table 'contracts/**/*.sol'",
"lint:check": "pnpm lint:contracts:check && pnpm lint:ts:check",
"lint:ts:fix": "eslint --fix .",
"lint:contracts:fix": "pnpm prettier --write 'contracts/**/*.sol'",
"lint:fix": "pnpm lint:contracts:fix && pnpm lint:ts:fix",
"lint": "pnpm lint:fix && pnpm lint:check",
"clean": "rm -rf ./dist ./artifacts ./forge-artifacts ./cache ./coverage ./tsconfig.tsbuildinfo",
"prepublishOnly": "pnpm copyfiles -u 1 -e \"**/test-*/**/*\" \"contracts/**/*\" ./",
"postpublish": "rimraf chugsplash L1 L2 libraries standards",
"prepack": "pnpm prepublishOnly",
"postpack": "pnpm postpublish",
"pre-commit": "lint-staged"
},
"keywords": [
"optimism",
"ethereum",
"contracts",
"periphery",
"solidity"
],
"homepage": "https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-periphery#readme",
"license": "MIT",
"author": "Optimism PBC",
"repository": {
"type": "git",
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"devDependencies": {
"@eth-optimism/contracts-bedrock": "0.15.0",
"@eth-optimism/core-utils": "^0.12.1",
"@eth-optimism/hardhat-deploy-config": "^0.2.6",
"@ethersproject/hardware-wallets": "^5.7.0",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-etherscan": "^3.0.3",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@openzeppelin/contracts": "4.7.3",
"@openzeppelin/contracts-upgradeable": "4.7.3",
"@rari-capital/solmate": "7.0.0-alpha.3",
"@typechain/ethers-v5": "^10.1.0",
"@typechain/hardhat": "^6.1.2",
"@types/node": "^17.0.21",
"babel-eslint": "^10.1.0",
"chai": "^4.3.4",
"copyfiles": "^2.3.0",
"dotenv": "^10.0.0",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.7.0",
"hardhat": "^2.9.6",
"hardhat-deploy": "^0.11.10",
"hardhat-gas-reporter": "^1.0.8",
"lint-staged": "11.0.0",
"mkdirp": "^1.0.4",
"node-fetch": "^2.6.7",
"prettier": "^2.8.0",
"prettier-plugin-solidity": "^1.0.0-beta.18",
"solhint": "^3.3.6",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.7.17",
"ts-node": "^10.9.1",
"typechain": "^8.1.0"
},
"dependencies": {
"ds-test": "github:dapphub/ds-test#c9ce3f25bde29fc5eb9901842bf02850dfd2d084",
"forge-std": "github:foundry-rs/forge-std#e8a047e3f40f13fa37af6fe14e6e06283d9a060e"
}
}
{
"detectors_to_exclude": "conformance-to-solidity-naming-conventions,assembly-usage,low-level-calls,block-timestamp,pragma,solc-version,too-many-digits,boolean-equal,missing-zero-check",
"exclude_informational": false,
"exclude_low": false,
"exclude_medium": false,
"exclude_high": false,
"solc_disable_warnings": false,
"hardhat_ignore_compile": false,
"disable_color": false,
"exclude_dependencies": false,
"filter_paths": "@openzeppelin|hardhat|contracts/testing"
}
import { DeployConfigSpec } from '@eth-optimism/hardhat-deploy-config/dist/src/types'
/**
* Defines the configuration for a deployment.
*/
export interface DeployConfig {
/**
* Dedicated Deterministic Deployer address (DDD).
* When deploying authenticated deterministic smart contracts to the same address on various
* chains, it's necessary to have a single root address that will initially own the contract and
* later transfer ownership to the final contract owner. We call this address the DDD. We expect
* the DDD to transfer ownership to the final contract owner very quickly after deployment.
*/
ddd: string
/**
* Number of confs before considering it final
*/
numDeployConfirmations?: number
/**
* Name of the NFT in the Optimist contract.
*/
optimistName: string
/**
* Symbol of the NFT in the Optimist contract.
*/
optimistSymbol: string
/**
* Address of the privileged attestor for the Optimist contract.
*/
optimistBaseUriAttestorAddress: string
/**
* Address of the privileged account for the OptimistInviter contract that can grant invites.
*/
optimistInviterInviteGranter: string
/**
* Name of OptimistInviter contract, used for the EIP712 domain separator.
*/
optimistInviterName: string
/**
* Address of previleged account for the OptimistAllowlist contract that can add/remove people
* from allowlist.
*/
optimistAllowlistAllowlistAttestor: string
/**
* Address of Coinbase attestor that attests to whether someone has completed Quest.
*/
optimistAllowlistCoinbaseQuestAttestor: string
/**
* Address of the owner of the proxies on L2. There will be a ProxyAdmin deployed as a predeploy
* after bedrock, so the owner of proxies should be updated to that after the upgrade.
* This currently is used as the owner of the nft related proxies.
*/
l2ProxyOwnerAddress: string
}
/**
* Specification for each of the configuration options.
*/
export const configSpec: DeployConfigSpec<DeployConfig> = {
ddd: {
type: 'address',
},
numDeployConfirmations: {
type: 'number',
default: 1,
},
optimistName: {
type: 'string',
default: 'Optimist',
},
optimistSymbol: {
type: 'string',
default: 'OPTIMIST',
},
optimistBaseUriAttestorAddress: {
type: 'address',
},
optimistInviterInviteGranter: {
type: 'address',
},
optimistInviterName: {
type: 'string',
},
optimistAllowlistAllowlistAttestor: {
type: 'address',
},
optimistAllowlistCoinbaseQuestAttestor: {
type: 'address',
},
l2ProxyOwnerAddress: {
type: 'address',
},
}
import assert from 'assert'
import { BigNumberish, ethers } from 'ethers'
import { Interface } from 'ethers/lib/utils'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { Etherscan } from '../etherscan'
export interface DripConfig {
reentrant?: boolean
interval: BigNumberish
dripcheck: string
checkparams?: any
actions: Array<{
target: string
value?: BigNumberish
data?:
| string
| {
fn: string
args?: any[]
}
}>
}
export interface DrippieConfig {
[name: string]: DripConfig
}
export enum Time {
SECOND = 1,
MINUTE = 60 * Time.SECOND,
HOUR = 60 * Time.MINUTE,
DAY = 24 * Time.HOUR,
WEEK = 7 * Time.DAY,
}
export const getDrippieConfig = async (
hre: HardhatRuntimeEnvironment
): Promise<Required<DrippieConfig>> => {
let config: DrippieConfig
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
config = require(`../../config/drippie/${hre.network.name}.ts`).default
} catch (err) {
throw new Error(
`error while loading drippie config for network: ${hre.network.name}, ${err}`
)
}
return parseDrippieConfig(hre, config)
}
export const encodeDripCheckParams = (
iface: Interface,
params: any
): string => {
return ethers.utils.defaultAbiCoder.encode(
[iface.getEvent('_EventToExposeStructInABI__Params').inputs[0]],
[params]
)
}
export const parseDrippieConfig = async (
hre: HardhatRuntimeEnvironment,
config: DrippieConfig
): Promise<Required<DrippieConfig>> => {
// Create a clone of the config object. Shallow clone is fine because none of the input options
// are expected to be objects or functions etc.
const parsed = { ...config }
const etherscan = new Etherscan(
hre.network.config.verify.etherscan.apiKey,
hre.network.config.chainId
)
for (const dripConfig of Object.values(parsed)) {
for (const action of dripConfig.actions) {
assert(ethers.utils.isAddress(action.target), 'target is not an address')
if (action.data === undefined) {
action.data = '0x'
} else if (typeof action.data === 'string') {
assert(
ethers.utils.isHexString(action.data),
'action is not a hex string'
)
} else {
const abi = await etherscan.getContractABI(action.target)
const iface = new ethers.utils.Interface(abi)
action.data = iface.encodeFunctionData(
action.data.fn,
action.data.args || []
)
}
if (action.value === undefined) {
action.value = ethers.BigNumber.from(0)
} else {
action.value = ethers.BigNumber.from(action.value)
}
}
const dripcheck = await hre.deployments.get(dripConfig.dripcheck)
dripConfig.dripcheck = dripcheck.address
if (dripConfig.checkparams === undefined) {
dripConfig.checkparams = '0x'
} else {
dripConfig.checkparams = encodeDripCheckParams(
new ethers.utils.Interface(dripcheck.abi),
dripConfig.checkparams
)
}
dripConfig.interval = ethers.BigNumber.from(dripConfig.interval)
dripConfig.reentrant = dripConfig.reentrant || false
}
return parsed as Required<DrippieConfig>
}
export const isSameConfig = (a: DripConfig, b: DripConfig): boolean => {
return (
a.dripcheck.toLowerCase() === b.dripcheck.toLowerCase() &&
a.checkparams === b.checkparams &&
ethers.BigNumber.from(a.interval).eq(b.interval) &&
a.actions.length === b.actions.length &&
a.actions.every((ax, i) => {
return (
ax.target === b.actions[i].target &&
ax.data === b.actions[i].data &&
ethers.BigNumber.from(ax.value).eq(b.actions[i].value)
)
})
)
}
export * from './deploy'
export * from './drippie'
export * from './config'
export * from './etherscan'
export * from './gnosis-safe-checksum'
export * from './install-drippie-config'
export * from './install-drippie-config-multisig'
import fs from 'fs'
import { task } from 'hardhat/config'
import { getChainId } from '@eth-optimism/core-utils'
import { isSameConfig, getDrippieConfig, addChecksum } from '../src'
task('install-drippie-config-multisig')
.addParam('safe', 'address of the Gnosis Safe to execute this bundle')
.addParam('outfile', 'where to write the bundle JSON file')
.setAction(async (args, hre) => {
if (!hre.ethers.utils.isAddress(args.safe)) {
throw new Error(`given safe is not an address: ${args.safe}`)
}
console.log(`connecting to Drippie...`)
const Drippie = await hre.ethers.getContractAt(
'Drippie',
(
await hre.deployments.get('Drippie')
).address
)
console.log(`loading local version of Drippie config for network...`)
const config = await getDrippieConfig(hre)
// Gnosis Safe transaction bundle.
const bundle: any = {
version: '1.0',
chainId: (await getChainId(hre.ethers.provider)).toString(),
createdAt: Date.now(),
meta: {
name: 'Transactions Batch',
description: '',
txBuilderVersion: '1.8.0',
createdFromSafeAddress: args.safe,
createdFromOwnerAddress: '',
},
transactions: [],
}
console.log(`generating transaction bundle...`)
for (const [dripName, dripConfig] of Object.entries(config)) {
console.log(`checking config for drip: ${dripName}`)
const drip = await Drippie.drips(dripName)
if (drip.status === 0) {
console.log(`drip does not exist yet: ${dripName}`)
console.log(`adding drip creation to bundle...`)
bundle.transactions.push({
to: Drippie.address,
value: '0',
data: null,
contractMethod: {
inputs: [
{ internalType: 'string', name: '_name', type: 'string' },
{
components: [
{
internalType: 'uint256',
name: 'interval',
type: 'uint256',
},
{
internalType: 'contract IDripCheck',
name: 'dripcheck',
type: 'address',
},
{ internalType: 'bytes', name: 'checkparams', type: 'bytes' },
{
components: [
{
internalType: 'address payable',
name: 'target',
type: 'address',
},
{ internalType: 'bytes', name: 'data', type: 'bytes' },
{
internalType: 'uint256',
name: 'value',
type: 'uint256',
},
],
internalType: 'struct Drippie.DripAction[]',
name: 'actions',
type: 'tuple[]',
},
],
internalType: 'struct Drippie.DripConfig',
name: '_config',
type: 'tuple',
},
],
name: 'create',
payable: false,
},
contractInputsValues: {
_name: dripName,
_config: JSON.stringify([
hre.ethers.BigNumber.from(dripConfig.interval).toString(),
dripConfig.dripcheck,
dripConfig.checkparams,
dripConfig.actions.map((action) => {
return [
action.target,
action.data,
hre.ethers.BigNumber.from(action.value).toString(),
]
}),
]),
},
})
} else if (!isSameConfig(dripConfig, drip.config)) {
console.log(`drip exists but local config is different: ${dripName}`)
console.log(`drips cannot be modified for security reasons`)
console.log(`please do not modify the local config for existing drips`)
console.log(`you can archive the old drip and create another`)
} else {
console.log(`drip is already installed`)
}
}
console.log(`writing bundle to ${args.outfile}...`)
fs.writeFileSync(args.outfile, JSON.stringify(addChecksum(bundle), null, 2))
})
import { task } from 'hardhat/config'
import { LedgerSigner } from '@ethersproject/hardware-wallets'
import { PopulatedTransaction } from 'ethers'
import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy'
import { isSameConfig, getDrippieConfig } from '../src'
task('install-drippie-config').setAction(async (args, hre) => {
console.log(`connecting to ledger...`)
const signer = new LedgerSigner(
hre.ethers.provider,
'default',
hre.ethers.utils.defaultPath
)
console.log(`connecting to Drippie...`)
const Drippie = await hre.ethers.getContractAt(
'Drippie',
(
await hre.deployments.get('Drippie')
).address,
signer
)
console.log(`loading local version of Drippie config for network...`)
const config = await getDrippieConfig(hre)
// Need this to deal with annoying Ethers/Ledger 1559 issue.
const sendtx = async (tx: PopulatedTransaction): Promise<void> => {
const gas = await signer.estimateGas(tx)
tx.type = 1
tx.gasLimit = gas
const ret = await signer.sendTransaction(tx)
console.log(`sent tx: ${ret.hash}`)
console.log(`waiting for tx to be confirmed...`)
await ret.wait()
console.log(`tx confirmed`)
}
console.log(`installing Drippie config file...`)
for (const [dripName, dripConfig] of Object.entries(config)) {
console.log(`checking config for drip: ${dripName}`)
const drip = await Drippie.drips(dripName)
if (drip.status === 0) {
console.log(`drip does not exist yet: ${dripName}`)
console.log(`creating drip...`)
const tx = await Drippie.populateTransaction.create(dripName, dripConfig)
await sendtx(tx)
} else if (!isSameConfig(dripConfig, drip.config)) {
console.log(`drip exists but local config is different: ${dripName}`)
console.log(`drips cannot be modified for security reasons`)
console.log(`please do not modify the local config for existing drips`)
console.log(`you can archive the old drip and create another`)
} else {
console.log(`drip is already installed`)
}
}
console.log(`config is fully installed`)
})
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": [
"src/**/*"
]
}
...@@ -32,19 +32,20 @@ ...@@ -32,19 +32,20 @@
"url": "https://github.com/ethereum-optimism/optimism.git" "url": "https://github.com/ethereum-optimism/optimism.git"
}, },
"dependencies": { "dependencies": {
"ethers": "^5.7.0",
"@ethersproject/abi": "^5.7.0", "@ethersproject/abi": "^5.7.0",
"@ethersproject/abstract-provider": "^5.7.0", "@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/address": "^5.7.0", "@ethersproject/address": "^5.7.0",
"@ethersproject/bignumber": "^5.7.0", "@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0", "@ethersproject/bytes": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/constants": "^5.7.0", "@ethersproject/constants": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/keccak256": "^5.7.0", "@ethersproject/keccak256": "^5.7.0",
"@ethersproject/rlp": "^5.7.0",
"@ethersproject/properties": "^5.7.0", "@ethersproject/properties": "^5.7.0",
"@ethersproject/rlp": "^5.7.0",
"@ethersproject/web": "^5.7.0", "@ethersproject/web": "^5.7.0",
"chai": "^4.3.4" "chai": "^4.3.4",
"ethers": "^5.7.0",
"node-fetch": "^2.6.7"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^12.12.6", "@types/node": "^12.12.6",
......
export * from './common' export * from './common'
export * from './external' export * from './external'
export * from './optimism' export * from './optimism'
export * from './gnosis-safe-checksum'
export * from './etherscan'
export * from './helpers/setupProxyContract'
ignores: [
"@babel/eslint-parser",
"@typescript-eslint/parser",
"eslint-plugin-import",
"eslint-plugin-unicorn",
"eslint-plugin-jsdoc",
"eslint-plugin-prefer-arrow",
"eslint-plugin-react",
"@typescript-eslint/eslint-plugin",
"eslint-config-prettier",
"eslint-plugin-prettier",
"chai"
]
module.exports = {
extends: '../../.eslintrc.js',
}
module.exports = {
...require('../../.prettierrc.js'),
};
# @eth-optimism/hardhat-deploy-config
## 0.2.6
### Patch Changes
- 5cf646bab: Add getter for other network's deploy config
## 0.2.5
### Patch Changes
- 1d3c749a2: Bumps the version of ts-node used
## 0.2.4
### Patch Changes
- dd5ab8c0: Allow `paths` to be unset in hardhat config
## 0.2.3
### Patch Changes
- 7215f4ce: Bump ethers to 5.7.0 globally
## 0.2.2
### Patch Changes
- 6ce47f38: Support JSON-formatted deploy configs
## 0.2.1
### Patch Changes
- 2fd0a2fe: Use lazyObject
- 89d01f2e: Update dev deps
## 0.2.0
### Minor Changes
- 27234f68: Initial release of hardhat-deploy-config
### Patch Changes
- a320e744: Properly exports DeployConfigSpec type
- 29ff7462: Revert es target back to 2017
(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.
# @eth-optimism/hardhat-deploy-config
`hardhat-deploy-config` is a simple plugin that adds support for global deploy configuration values.
## Installation
```
pnpm i @eth-optimism/hardhat-deploy-config
```
{
"name": "@eth-optimism/hardhat-deploy-config",
"version": "0.2.6",
"description": "[Optimism] Hardhat deploy configuration plugin",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/*"
],
"scripts": {
"test:coverage": "echo 'No tests defined.'",
"build": "tsc -p tsconfig.json",
"clean": "rimraf dist/ ./tsconfig.tsbuildinfo",
"lint": "pnpm lint:fix && pnpm lint:check",
"pre-commit": "lint-staged",
"lint:fix": "pnpm lint:check --fix",
"lint:check": "eslint . --max-warnings=0"
},
"keywords": [
"optimism",
"ethereum",
"hardhat",
"deploy",
"config",
"plugin"
],
"homepage": "https://github.com/ethereum-optimism/optimism/tree/develop/packages/hardhat-deploy-config#readme",
"license": "MIT",
"author": "Optimism PBC",
"repository": {
"type": "git",
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"devDependencies": {
"ethers": "^5.7.0",
"ts-node": "^10.9.1",
"hardhat": "^2.9.6"
}
}
import './type-extensions'
import './plugin'
import * as path from 'path'
import * as fs from 'fs'
import { extendEnvironment, extendConfig } from 'hardhat/config'
import {
HardhatConfig,
HardhatRuntimeEnvironment,
HardhatUserConfig,
} from 'hardhat/types'
import { lazyObject, lazyFunction } from 'hardhat/plugins'
import { ethers } from 'ethers'
// From: https://github.com/wighawag/hardhat-deploy/blob/master/src/index.ts#L63-L76
const normalizePath = (
config: HardhatConfig,
userPath: string | undefined,
defaultPath: string
): string => {
if (userPath === undefined) {
userPath = path.join(config.paths.root, defaultPath)
} else {
if (!path.isAbsolute(userPath)) {
userPath = path.normalize(path.join(config.paths.root, userPath))
}
}
return userPath
}
const getDeployConfig = (
dir: string,
network: string
): { [key: string]: any } => {
let config: any
try {
const base = `${dir}/${network}`
if (fs.existsSync(`${base}.ts`)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
config = require(`${base}.ts`).default
} else if (fs.existsSync(`${base}.json`)) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
config = require(`${base}.json`)
} else {
throw new Error('not found')
}
} catch (err) {
throw new Error(
`error while loading deploy config for network: ${network}, ${err}`
)
}
return config
}
export const loadDeployConfig = (hre: HardhatRuntimeEnvironment): any => {
const paths = hre.config.paths.deployConfig
const conf = getDeployConfig(paths, hre.network.name)
const spec = parseDeployConfig(hre, conf)
return new Proxy(spec, {
get: (target, prop) => {
if (target.hasOwnProperty(prop)) {
return target[prop]
}
// Explicitly throw if the property is not found
throw new Error(
`property does not exist in deploy config: ${String(prop)}`
)
},
})
}
export const parseDeployConfig = (
hre: HardhatRuntimeEnvironment,
config: any
): any => {
// Create a clone of the config object. Shallow clone is fine because none of the input options
// are expected to be objects or functions etc.
const parsed = { ...config }
// If the deployConfigSpec is not provided, do no validation
if (!hre.config.deployConfigSpec) {
return parsed
}
for (const [key, spec] of Object.entries(hre.config.deployConfigSpec)) {
// Make sure the value is defined, or use a default.
if (parsed[key] === undefined) {
if ('default' in spec) {
parsed[key] = spec.default
} else {
throw new Error(
`deploy config is missing required field: ${key} (${spec.type})`
)
}
} else {
// Make sure the default has the correct type.
if (spec.type === 'address') {
if (!ethers.utils.isAddress(parsed[key])) {
throw new Error(
`deploy config field: ${key} is not of type ${spec.type}: ${parsed[key]}`
)
}
} else if (typeof parsed[key] !== spec.type) {
throw new Error(
`deploy config field: ${key} is not of type ${spec.type}: ${parsed[key]}`
)
}
}
}
return parsed
}
extendConfig(
(config: HardhatConfig, userConfig: Readonly<HardhatUserConfig>) => {
config.paths.deployConfig = normalizePath(
config,
userConfig.paths?.deployConfig,
'deploy-config'
)
}
)
extendEnvironment((hre) => {
hre.deployConfig = lazyObject(() => loadDeployConfig(hre))
hre.getDeployConfig = lazyFunction(() => {
const paths = hre.config.paths.deployConfig
return (network: string) => getDeployConfig(paths, network)
})
})
import 'hardhat/types/runtime'
import 'hardhat/types/config'
import { DeployConfigSpec } from './types'
declare module 'hardhat/types/config' {
interface HardhatUserConfig {
deployConfigSpec?: DeployConfigSpec<any>
}
interface HardhatConfig {
deployConfigSpec?: DeployConfigSpec<any>
}
interface ProjectPathsUserConfig {
deployConfig?: string
}
interface ProjectPathsConfig {
deployConfig?: string
}
}
declare module 'hardhat/types/runtime' {
interface HardhatRuntimeEnvironment {
deployConfig: {
[key: string]: any
}
getDeployConfig(network: string): { [key: string]: any }
}
}
export type DeployConfigSpec<
TDeployConfig extends {
[key: string]: any
}
> = {
[K in keyof TDeployConfig]: {
type: 'address' | 'number' | 'string' | 'boolean'
default?: any
}
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": [
"src/**/*"
]
}
...@@ -59,11 +59,6 @@ const config: HardhatUserConfig = { ...@@ -59,11 +59,6 @@ const config: HardhatUserConfig = {
'../contracts-bedrock/deployments/goerli', '../contracts-bedrock/deployments/goerli',
'../contracts/deployments/goerli', '../contracts/deployments/goerli',
], ],
'final-migration-rehearsal': [
'../contracts-bedrock/deployments/final-migration-rehearsal',
'../contracts/deployments/goerli',
'../contracts-periphery/deployments/goerli',
],
}, },
}, },
} }
......
...@@ -30,6 +30,7 @@ export enum L2ChainID { ...@@ -30,6 +30,7 @@ export enum L2ChainID {
OPTIMISM_BEDROCK_LOCAL_DEVNET = 901, OPTIMISM_BEDROCK_LOCAL_DEVNET = 901,
OPTIMISM_BEDROCK_ALPHA_TESTNET = 28528, OPTIMISM_BEDROCK_ALPHA_TESTNET = 28528,
BASE_GOERLI = 84531, BASE_GOERLI = 84531,
BASE_MAINNET = 8453,
ZORA_GOERLI = 999, ZORA_GOERLI = 999,
ZORA_MAINNET = 7777777, ZORA_MAINNET = 7777777,
} }
......
...@@ -72,6 +72,7 @@ export const DEPOSIT_CONFIRMATION_BLOCKS: { ...@@ -72,6 +72,7 @@ export const DEPOSIT_CONFIRMATION_BLOCKS: {
[L2ChainID.OPTIMISM_BEDROCK_LOCAL_DEVNET]: 2 as const, [L2ChainID.OPTIMISM_BEDROCK_LOCAL_DEVNET]: 2 as const,
[L2ChainID.OPTIMISM_BEDROCK_ALPHA_TESTNET]: 12 as const, [L2ChainID.OPTIMISM_BEDROCK_ALPHA_TESTNET]: 12 as const,
[L2ChainID.BASE_GOERLI]: 12 as const, [L2ChainID.BASE_GOERLI]: 12 as const,
[L2ChainID.BASE_MAINNET]: 50 as const,
[L2ChainID.ZORA_GOERLI]: 12 as const, [L2ChainID.ZORA_GOERLI]: 12 as const,
[L2ChainID.ZORA_MAINNET]: 50 as const, [L2ChainID.ZORA_MAINNET]: 50 as const,
} }
...@@ -218,6 +219,22 @@ export const CONTRACT_ADDRESSES: { ...@@ -218,6 +219,22 @@ export const CONTRACT_ADDRESSES: {
}, },
l2: DEFAULT_L2_CONTRACT_ADDRESSES, l2: DEFAULT_L2_CONTRACT_ADDRESSES,
}, },
[L2ChainID.BASE_MAINNET]: {
l1: {
AddressManager: '0x8EfB6B5c4767B09Dc9AA6Af4eAA89F749522BaE2' as const,
L1CrossDomainMessenger:
'0x866E82a600A1414e583f7F13623F1aC5d58b0Afa' as const,
L1StandardBridge: '0x3154Cf16ccdb4C6d922629664174b904d80F2C35' as const,
StateCommitmentChain:
'0x0000000000000000000000000000000000000000' as const,
CanonicalTransactionChain:
'0x0000000000000000000000000000000000000000' as const,
BondManager: '0x0000000000000000000000000000000000000000' as const,
OptimismPortal: '0x49048044D57e1C92A77f79988d21Fa8fAF74E97e' as const,
L2OutputOracle: '0x56315b90c40730925ec5485cf004d835058518A0' as const,
},
l2: DEFAULT_L2_CONTRACT_ADDRESSES,
},
// Zora Goerli // Zora Goerli
[L2ChainID.ZORA_GOERLI]: { [L2ChainID.ZORA_GOERLI]: {
l1: { l1: {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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