Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 120 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Claim Genesis | 17457120 | 999 days ago | IN | 0 ETH | 0.01187479 | ||||
| Claim Genesis | 17456784 | 999 days ago | IN | 0 ETH | 0.01201534 | ||||
| Claim Genesis | 17119115 | 1046 days ago | IN | 0 ETH | 0.02800999 | ||||
| Claim Genesis | 17119112 | 1046 days ago | IN | 0 ETH | 0.02711768 | ||||
| Claim Genesis | 16592979 | 1120 days ago | IN | 0 ETH | 0.00455076 | ||||
| Claim | 16571490 | 1123 days ago | IN | 0 ETH | 0.00645783 | ||||
| Claim Genesis | 16082416 | 1192 days ago | IN | 0 ETH | 0.00306259 | ||||
| Claim Genesis | 16019224 | 1200 days ago | IN | 0 ETH | 0.00136322 | ||||
| Claim Genesis | 15996232 | 1204 days ago | IN | 0 ETH | 0.00201977 | ||||
| Claim Genesis | 15966363 | 1208 days ago | IN | 0 ETH | 0.0021603 | ||||
| Claim Genesis | 15955318 | 1209 days ago | IN | 0 ETH | 0.00244036 | ||||
| Claim | 15950112 | 1210 days ago | IN | 0 ETH | 0.0037846 | ||||
| Claim Genesis | 15949819 | 1210 days ago | IN | 0 ETH | 0.00313965 | ||||
| Claim Genesis | 15949473 | 1210 days ago | IN | 0 ETH | 0.00209346 | ||||
| Claim | 15932015 | 1213 days ago | IN | 0 ETH | 0.00613658 | ||||
| Claim Genesis | 15914860 | 1215 days ago | IN | 0 ETH | 0.00166482 | ||||
| Claim Genesis | 15909790 | 1216 days ago | IN | 0 ETH | 0.00163656 | ||||
| Claim Genesis | 15906752 | 1216 days ago | IN | 0 ETH | 0.00142731 | ||||
| Claim Genesis | 15906522 | 1216 days ago | IN | 0 ETH | 0.00181391 | ||||
| Claim Genesis | 15899756 | 1217 days ago | IN | 0 ETH | 0.00322962 | ||||
| Claim Genesis | 15895204 | 1218 days ago | IN | 0 ETH | 0.00232135 | ||||
| Claim Genesis | 15894552 | 1218 days ago | IN | 0 ETH | 0.00128271 | ||||
| Claim Genesis | 15889530 | 1219 days ago | IN | 0 ETH | 0.00120118 | ||||
| Claim Genesis | 15888949 | 1219 days ago | IN | 0 ETH | 0.00118132 | ||||
| Claim Genesis | 15883185 | 1219 days ago | IN | 0 ETH | 0.00035302 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SafeHouseClaim
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 0 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {ERC721UDS} from "UDS/tokens/ERC721UDS.sol";
import {OwnableUDS} from "UDS/auth/OwnableUDS.sol";
import {UUPSUpgrade} from "UDS/proxy/UUPSUpgrade.sol";
import {FxBaseRootTunnel} from "fx-contracts/base/FxBaseRootTunnel.sol";
bytes4 constant CONSECUTIVE_MINT_ERC721_SELECTOR = bytes4(keccak256("consecutiveMint(address)"));
error ExceedsLimit();
error AlreadyClaimed();
error IncorrectOwner();
error InvalidBurnAmount();
/// @title Safe House Claim
/// @author phaze (https://github.com/0xPhaze)
contract SafeHouseClaim is OwnableUDS, FxBaseRootTunnel {
string public constant name = "Safe House Claim";
string public constant symbol = "SAFE";
address public immutable troupe;
address public immutable genesis;
uint256 public immutable claimEnd;
uint256 public constant burnAmount = 5;
address public constant burnAddress = 0x000000000000000000000000000000000000dEaD;
mapping(uint256 => bool) public genesisClaimed;
constructor(
address genesis_,
address troupe_,
address checkpointManager,
address fxRoot
) FxBaseRootTunnel(checkpointManager, fxRoot) {
__Ownable_init();
troupe = troupe_;
genesis = genesis_;
claimEnd = block.timestamp + 4 weeks;
}
/* ------------- external ------------- */
function claim(uint256[][] calldata ids) external {
unchecked {
if (ids.length > 20) revert ExceedsLimit();
for (uint256 c; c < ids.length; ++c) {
if (ids[c].length != burnAmount) revert InvalidBurnAmount();
for (uint256 i; i < ids[c].length; ++i) {
ERC721UDS(troupe).transferFrom(msg.sender, burnAddress, ids[c][i]);
}
_sendMessageToChild(abi.encodeWithSelector(CONSECUTIVE_MINT_ERC721_SELECTOR, msg.sender));
}
}
}
function claimGenesis(uint256[] calldata ids) external {
unchecked {
if (ids.length > 20) revert ExceedsLimit();
for (uint256 i; i < ids.length; ++i) {
if (genesisClaimed[ids[i]]) revert AlreadyClaimed();
if (IGenesis(genesis).trueOwnerOf(ids[i]) != msg.sender) revert IncorrectOwner();
genesisClaimed[ids[i]] = true;
_sendMessageToChild(abi.encodeWithSelector(CONSECUTIVE_MINT_ERC721_SELECTOR, msg.sender));
}
}
}
/* ------------- owner ------------- */
function setClaimEnd() internal onlyOwner {}
/* ------------- overrides ------------- */
function _authorizeTunnelController() internal override onlyOwner {}
}
interface IGenesis {
function trueOwnerOf(uint256 id) external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Context} from "../utils/Context.sol";
import {Initializable} from "../utils/Initializable.sol";
import {EIP712PermitUDS} from "../auth/EIP712PermitUDS.sol";
// ------------- storage
bytes32 constant DIAMOND_STORAGE_ERC721 = keccak256("diamond.storage.erc721");
function s() pure returns (ERC721DS storage diamondStorage) {
bytes32 slot = DIAMOND_STORAGE_ERC721;
assembly { diamondStorage.slot := slot } // prettier-ignore
}
struct ERC721DS {
string name;
string symbol;
mapping(uint256 => address) ownerOf;
mapping(address => uint256) balanceOf;
mapping(uint256 => address) getApproved;
mapping(address => mapping(address => bool)) isApprovedForAll;
}
// ------------- errors
error NonexistentToken();
error NonERC721Receiver();
error MintExistingToken();
error MintToZeroAddress();
error BalanceOfZeroAddress();
error TransferToZeroAddress();
error CallerNotOwnerNorApproved();
error TransferFromIncorrectOwner();
/// @title ERC721 (Upgradeable Diamond Storage)
/// @author phaze (https://github.com/0xPhaze/UDS)
/// @author Modified from Solmate (https://github.com/Rari-Capital/solmate)
/// @notice Integrates EIP712Permit
abstract contract ERC721UDS is Context, Initializable, EIP712PermitUDS {
ERC721DS private __storageLayout; // storage layout for upgrade compatibility checks
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed operator, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/* ------------- init ------------- */
function __ERC721_init(string memory name_, string memory symbol_) internal virtual initializer {
s().name = name_;
s().symbol = symbol_;
}
/* ------------- virtual ------------- */
function tokenURI(uint256 id) public view virtual returns (string memory);
/* ------------- view ------------- */
function name() external view virtual returns (string memory) {
return s().name;
}
function symbol() external view virtual returns (string memory) {
return s().symbol;
}
function ownerOf(uint256 id) public view virtual returns (address owner) {
if ((owner = s().ownerOf[id]) == address(0)) revert NonexistentToken();
}
function balanceOf(address owner) public view virtual returns (uint256) {
if (owner == address(0)) revert BalanceOfZeroAddress();
return s().balanceOf[owner];
}
function getApproved(uint256 id) public view returns (address) {
return s().getApproved[id];
}
function isApprovedForAll(address owner, address operator) public view returns (bool) {
return s().isApprovedForAll[owner][operator];
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
}
/* ------------- public ------------- */
function approve(address operator, uint256 id) public virtual {
address owner = s().ownerOf[id];
if (_msgSender() != owner && !s().isApprovedForAll[owner][_msgSender()]) revert CallerNotOwnerNorApproved();
s().getApproved[id] = operator;
emit Approval(owner, operator, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
s().isApprovedForAll[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
if (to == address(0)) revert TransferToZeroAddress();
if (from != s().ownerOf[id]) revert TransferFromIncorrectOwner();
bool isApprovedOrOwner = (_msgSender() == from ||
s().isApprovedForAll[from][_msgSender()] ||
s().getApproved[id] == _msgSender());
if (!isApprovedOrOwner) revert CallerNotOwnerNorApproved();
unchecked {
s().balanceOf[from]--;
s().balanceOf[to]++;
}
s().ownerOf[id] = to;
delete s().getApproved[id];
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
if (
to.code.length != 0 &&
ERC721TokenReceiver(to).onERC721Received(_msgSender(), from, id, "") !=
ERC721TokenReceiver.onERC721Received.selector
) revert NonERC721Receiver();
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes calldata data
) public virtual {
transferFrom(from, to, id);
if (
to.code.length != 0 &&
ERC721TokenReceiver(to).onERC721Received(_msgSender(), from, id, data) !=
ERC721TokenReceiver.onERC721Received.selector
) revert NonERC721Receiver();
}
// EIP-4494 permit; differs from the current EIP
function permit(
address owner,
address operator,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s_
) public virtual {
_usePermit(owner, operator, 1, deadline, v, r, s_);
s().isApprovedForAll[owner][operator] = true;
emit ApprovalForAll(owner, operator, true);
}
/* ------------- internal ------------- */
function _mint(address to, uint256 id) internal virtual {
if (to == address(0)) revert MintToZeroAddress();
if (s().ownerOf[id] != address(0)) revert MintExistingToken();
unchecked {
s().balanceOf[to]++;
}
s().ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = s().ownerOf[id];
if (owner == address(0)) revert NonexistentToken();
unchecked {
s().balanceOf[owner]--;
}
delete s().ownerOf[id];
delete s().getApproved[id];
emit Transfer(owner, address(0), id);
}
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
if (
to.code.length != 0 &&
ERC721TokenReceiver(to).onERC721Received(_msgSender(), address(0), id, "") !=
ERC721TokenReceiver.onERC721Received.selector
) revert NonERC721Receiver();
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
if (
to.code.length != 0 &&
ERC721TokenReceiver(to).onERC721Received(_msgSender(), address(0), id, data) !=
ERC721TokenReceiver.onERC721Received.selector
) revert NonERC721Receiver();
}
}
/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/)
abstract contract ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Context} from "../utils/Context.sol";
import {Initializable} from "../utils/Initializable.sol";
// ------------- storage
bytes32 constant DIAMOND_STORAGE_OWNABLE = keccak256("diamond.storage.ownable");
function s() pure returns (OwnableDS storage diamondStorage) {
bytes32 slot = DIAMOND_STORAGE_OWNABLE;
assembly { diamondStorage.slot := slot } // prettier-ignore
}
struct OwnableDS {
address owner;
}
// ------------- errors
error CallerNotOwner();
/// @title Ownable (Upgradeable Diamond Storage)
/// @author phaze (https://github.com/0xPhaze/UDS)
/// @dev Requires `__Ownable_init` to be called in proxy
abstract contract OwnableUDS is Context, Initializable {
OwnableDS private __storageLayout; // storage layout for upgrade compatibility checks
event OwnerChanged(address oldOwner, address newOwner);
function __Ownable_init() internal initializer {
s().owner = _msgSender();
}
/* ------------- external ------------- */
function owner() public view returns (address) {
return s().owner;
}
function transferOwnership(address newOwner) external onlyOwner {
s().owner = newOwner;
emit OwnerChanged(_msgSender(), newOwner);
}
/* ------------- modifier ------------- */
modifier onlyOwner() {
if (_msgSender() != s().owner) revert CallerNotOwner();
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {ERC1967, ERC1967_PROXY_STORAGE_SLOT} from "./ERC1967Proxy.sol";
// ------------- errors
error OnlyProxyCallAllowed();
error DelegateCallNotAllowed();
/// @title Minimal UUPSUpgrade
/// @author phaze (https://github.com/0xPhaze/UDS)
abstract contract UUPSUpgrade is ERC1967 {
address private immutable __implementation = address(this);
/* ------------- external ------------- */
function upgradeToAndCall(address logic, bytes calldata data) external virtual {
_authorizeUpgrade();
_upgradeToAndCall(logic, data);
}
/* ------------- view ------------- */
function proxiableUUID() external view virtual returns (bytes32) {
if (address(this) != __implementation) revert DelegateCallNotAllowed();
return ERC1967_PROXY_STORAGE_SLOT;
}
/* ------------- virtual ------------- */
function _authorizeUpgrade() internal virtual;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Merkle} from "../lib/Merkle.sol";
import {RLPReader} from "../lib/RLPReader.sol";
import {ExitPayloadReader} from "../lib/ExitPayloadReader.sol";
import {MerklePatriciaProof} from "../lib/MerklePatriciaProof.sol";
// ------------- interfaces
interface IFxStateSender {
function sendMessageToChild(address _receiver, bytes calldata _data) external;
}
interface ICheckpointManager {
function headerBlocks(uint256 headerNumber)
external
view
returns (
bytes32 root,
uint256 start,
uint256 end,
uint256 createdAt,
address proposer
);
}
// ------------- storage
bytes32 constant DIAMOND_STORAGE_FX_BASE_ROOT_TUNNEL = keccak256("diamond.storage.fx.base.root.tunnel");
function s() pure returns (FxBaseRootTunnelDS storage diamondStorage) {
bytes32 slot = DIAMOND_STORAGE_FX_BASE_ROOT_TUNNEL;
assembly { diamondStorage.slot := slot } // prettier-ignore
}
struct FxBaseRootTunnelDS {
address fxChildTunnel;
mapping(bytes32 => bool) processedExits;
}
// ------------- errors
error FxChildUnset();
error InvalidHeader();
error InvalidSelector();
error InvalidReceiptProof();
error InvalidFxChildTunnel();
error ExitAlreadyProcessed();
abstract contract FxBaseRootTunnel {
using RLPReader for RLPReader.RLPItem;
using Merkle for bytes32;
using ExitPayloadReader for bytes;
using ExitPayloadReader for ExitPayloadReader.ExitPayload;
using ExitPayloadReader for ExitPayloadReader.Log;
using ExitPayloadReader for ExitPayloadReader.LogTopics;
using ExitPayloadReader for ExitPayloadReader.Receipt;
bytes32 private constant SEND_MESSAGE_EVENT_SELECTOR =
0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036;
IFxStateSender public immutable fxRoot;
ICheckpointManager public immutable checkpointManager;
constructor(address checkpointManager_, address fxRoot_) {
checkpointManager = ICheckpointManager(checkpointManager_);
fxRoot = IFxStateSender(fxRoot_);
}
/* ------------- virtual ------------- */
function _authorizeTunnelController() internal virtual;
/* ------------- view ------------- */
function fxChildTunnel() public view virtual returns (address) {
return s().fxChildTunnel;
}
function processedExits(bytes32 exitHash) public view virtual returns (bool) {
return s().processedExits[exitHash];
}
function setFxChildTunnel(address fxChildTunnel_) public virtual {
_authorizeTunnelController();
s().fxChildTunnel = fxChildTunnel_;
}
/* ------------- internal ------------- */
function _sendMessageToChild(bytes memory message) internal virtual {
if (s().fxChildTunnel == address(0)) revert FxChildUnset();
fxRoot.sendMessageToChild(s().fxChildTunnel, message);
}
/**
* @notice receive message from L2 to L1, validated by proof
* @dev This function verifies if the transaction actually happened on child chain
*
* @param proofData RLP encoded data of the reference tx containing following list of fields
* 0 - headerNumber - Checkpoint header block number containing the reference tx
* 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root
* 2 - blockNumber - Block number containing the reference tx on child chain
* 3 - blockTime - Reference tx block time
* 4 - txRoot - Transactions root of block
* 5 - receiptRoot - Receipts root of block
* 6 - receipt - Receipt of the reference transaction
* 7 - receiptProof - Merkle proof of the reference receipt
* 8 - branchMask - 32 bits denoting the path of receipt in merkle tree
* 9 - receiptLogIndex - Log Index to read from the receipt
*/
function _validateAndExtractMessage(bytes memory proofData) internal returns (bytes memory) {
address childTunnel = s().fxChildTunnel;
if (childTunnel == address(0)) revert FxChildUnset();
ExitPayloadReader.ExitPayload memory payload = proofData.toExitPayload();
bytes memory branchMaskBytes = payload.getBranchMaskAsBytes();
uint256 blockNumber = payload.getBlockNumber();
// checking if exit has already been processed
// unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex)
bytes32 exitHash = keccak256(
abi.encodePacked(
blockNumber,
// first 2 nibbles are dropped while generating nibble array
// this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only)
// so converting to nibble array and then hashing it
MerklePatriciaProof._getNibbleArray(branchMaskBytes),
payload.getReceiptLogIndex()
)
);
if (s().processedExits[exitHash]) revert ExitAlreadyProcessed();
s().processedExits[exitHash] = true;
ExitPayloadReader.Receipt memory receipt = payload.getReceipt();
ExitPayloadReader.Log memory log = receipt.getLog();
// check child tunnel
if (childTunnel != log.getEmitter()) revert InvalidFxChildTunnel();
bytes32 receiptRoot = payload.getReceiptRoot();
// verify receipt inclusion
if (!MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot))
revert InvalidReceiptProof();
(bytes32 headerRoot, uint256 startBlock, , , ) = checkpointManager.headerBlocks(payload.getHeaderNumber());
bytes32 leaf = keccak256(
abi.encodePacked(blockNumber, payload.getBlockTime(), payload.getTxRoot(), receiptRoot)
);
if (!leaf.checkMembership(blockNumber - startBlock, headerRoot, payload.getBlockProof()))
revert InvalidHeader();
ExitPayloadReader.LogTopics memory topics = log.getTopics();
if (bytes32(topics.getField(0).toUint()) != SEND_MESSAGE_EVENT_SELECTOR) revert InvalidSelector();
// received message data
bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message
return message;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Context
/// @notice Overridable context for meta-transactions
/// @author OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts)
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {s as erc1967ds} from "../proxy/ERC1967Proxy.sol";
// ------------- errors
error ProxyCallRequired();
error AlreadyInitialized();
/// @title Initializable
/// @author phaze (https://github.com/0xPhaze/UDS)
/// @dev functions using the `initializer` modifier are only callable during proxy deployment
/// @dev functions using the `reinitializer` modifier are only callable through a proxy
/// @dev and only before a proxy upgrade migration has completed
/// @dev (only when `upgradeToAndCall`'s `initCalldata` is being executed)
/// @dev allows re-initialization during upgrades
abstract contract Initializable {
address private immutable __implementation = address(this);
/* ------------- modifier ------------- */
modifier initializer() {
if (address(this).code.length != 0) revert AlreadyInitialized();
_;
}
modifier reinitializer() {
if (address(this) == __implementation) revert ProxyCallRequired();
if (erc1967ds().implementation == __implementation) revert AlreadyInitialized();
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// ------------- storage
bytes32 constant DIAMOND_STORAGE_EIP_712_PERMIT = keccak256("diamond.storage.eip.712.permit");
function s() pure returns (EIP2612DS storage diamondStorage) {
bytes32 slot = DIAMOND_STORAGE_EIP_712_PERMIT;
assembly { diamondStorage.slot := slot } // prettier-ignore
}
struct EIP2612DS {
mapping(address => uint256) nonces;
}
// ------------- errors
error InvalidSigner();
error DeadlineExpired();
/// @title EIP712Permit (Upgradeable Diamond Storage)
/// @author phaze (https://github.com/0xPhaze/UDS)
/// @author Modified from Solmate (https://github.com/Rari-Capital/solmate)
/// @dev `DOMAIN_SEPARATOR` needs to be re-computed every time
/// @dev for use with a proxy due to `address(this)`
abstract contract EIP712PermitUDS {
EIP2612DS private __storageLayout; // storage layout for upgrade compatibility checks
/* ------------- public ------------- */
function nonces(address owner) public view returns (uint256) {
return s().nonces[owner];
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256("EIP712"),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/* ------------- internal ------------- */
function _usePermit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v_,
bytes32 r_,
bytes32 s_
) internal virtual {
if (deadline < block.timestamp) revert DeadlineExpired();
unchecked {
uint256 nonce = s().nonces[owner]++;
address recovered = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonce,
deadline
)
)
)
),
v_,
r_,
s_
);
if (recovered == address(0) || recovered != owner) revert InvalidSigner();
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// ------------- storage
// keccak256("eip1967.proxy.implementation") - 1
bytes32 constant ERC1967_PROXY_STORAGE_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
function s() pure returns (ERC1967UpgradeDS storage diamondStorage) {
assembly { diamondStorage.slot := ERC1967_PROXY_STORAGE_SLOT } // prettier-ignore
}
struct ERC1967UpgradeDS {
address implementation;
}
// ------------- errors
error InvalidUUID();
error NotAContract();
/// @title ERC1967
/// @author phaze (https://github.com/0xPhaze/UDS)
abstract contract ERC1967 {
event Upgraded(address indexed implementation);
function _upgradeToAndCall(address logic, bytes memory data) internal {
if (logic.code.length == 0) revert NotAContract();
if (ERC1822(logic).proxiableUUID() != ERC1967_PROXY_STORAGE_SLOT) revert InvalidUUID();
if (data.length != 0) {
(bool success, ) = logic.delegatecall(data);
if (!success) {
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
s().implementation = logic;
emit Upgraded(logic);
}
}
/// @title Minimal ERC1967Proxy
/// @author phaze (https://github.com/0xPhaze/UDS)
contract ERC1967Proxy is ERC1967 {
constructor(address logic, bytes memory data) payable {
_upgradeToAndCall(logic, data);
}
fallback() external payable {
assembly {
calldatacopy(0, 0, calldatasize())
let success := delegatecall(gas(), sload(ERC1967_PROXY_STORAGE_SLOT), 0, calldatasize(), 0, 0)
returndatacopy(0, 0, returndatasize())
if success {
return(0, returndatasize())
}
revert(0, returndatasize())
}
}
}
/// @title ERC1822
/// @author phaze (https://github.com/0xPhaze/UDS)
abstract contract ERC1822 {
function proxiableUUID() external view virtual returns (bytes32);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
library Merkle {
function checkMembership(
bytes32 leaf,
uint256 index,
bytes32 rootHash,
bytes memory proof
) internal pure returns (bool) {
require(proof.length % 32 == 0, "Invalid proof length");
uint256 proofHeight = proof.length / 32;
// Proof of size n means, height of the tree is n+1.
// In a tree of height n+1, max #leafs possible is 2 ^ n
require(index < 2**proofHeight, "Leaf index is too big");
bytes32 proofElement;
bytes32 computedHash = leaf;
for (uint256 i = 32; i <= proof.length; i += 32) {
assembly {
proofElement := mload(add(proof, i))
}
if (index % 2 == 0) {
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
index = index / 2;
}
return computedHash == rootHash;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* @author Hamdi Allam hamdi.allam97@gmail.com
* Please reach out with any questions or concerns
*/
library RLPReader {
uint8 constant STRING_SHORT_START = 0x80;
uint8 constant STRING_LONG_START = 0xb8;
uint8 constant LIST_SHORT_START = 0xc0;
uint8 constant LIST_LONG_START = 0xf8;
uint8 constant WORD_SIZE = 32;
struct RLPItem {
uint256 len;
uint256 memPtr;
}
struct Iterator {
RLPItem item; // Item that's being iterated over.
uint256 nextPtr; // Position of the next item in the list.
}
/*
* @dev Returns the next element in the iteration. Reverts if it has not next element.
* @param self The iterator.
* @return The next element in the iteration.
*/
function next(Iterator memory self) internal pure returns (RLPItem memory) {
require(hasNext(self));
uint256 ptr = self.nextPtr;
uint256 itemLength = _itemLength(ptr);
self.nextPtr = ptr + itemLength;
return RLPItem(itemLength, ptr);
}
/*
* @dev Returns true if the iteration has more elements.
* @param self The iterator.
* @return true if the iteration has more elements.
*/
function hasNext(Iterator memory self) internal pure returns (bool) {
RLPItem memory item = self.item;
return self.nextPtr < item.memPtr + item.len;
}
/*
* @param item RLP encoded bytes
*/
function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
uint256 memPtr;
assembly {
memPtr := add(item, 0x20)
}
return RLPItem(item.length, memPtr);
}
/*
* @dev Create an iterator. Reverts if item is not a list.
* @param self The RLP item.
* @return An 'Iterator' over the item.
*/
function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
require(isList(self));
uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);
return Iterator(self, ptr);
}
/*
* @param item RLP encoded bytes
*/
function rlpLen(RLPItem memory item) internal pure returns (uint256) {
return item.len;
}
/*
* @param item RLP encoded bytes
*/
function payloadLen(RLPItem memory item) internal pure returns (uint256) {
return item.len - _payloadOffset(item.memPtr);
}
/*
* @param item RLP encoded list in bytes
*/
function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
require(isList(item));
uint256 items = numItems(item);
RLPItem[] memory result = new RLPItem[](items);
uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);
uint256 dataLen;
for (uint256 i = 0; i < items; i++) {
dataLen = _itemLength(memPtr);
result[i] = RLPItem(dataLen, memPtr);
memPtr = memPtr + dataLen;
}
return result;
}
// @return indicator whether encoded payload is a list. negate this function call for isData.
function isList(RLPItem memory item) internal pure returns (bool) {
if (item.len == 0) return false;
uint8 byte0;
uint256 memPtr = item.memPtr;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < LIST_SHORT_START) return false;
return true;
}
/*
* @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.
* @return keccak256 hash of RLP encoded bytes.
*/
function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {
uint256 ptr = item.memPtr;
uint256 len = item.len;
bytes32 result;
assembly {
result := keccak256(ptr, len)
}
return result;
}
function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {
uint256 offset = _payloadOffset(item.memPtr);
uint256 memPtr = item.memPtr + offset;
uint256 len = item.len - offset; // data length
return (memPtr, len);
}
/*
* @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.
* @return keccak256 hash of the item payload.
*/
function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {
(uint256 memPtr, uint256 len) = payloadLocation(item);
bytes32 result;
assembly {
result := keccak256(memPtr, len)
}
return result;
}
/** RLPItem conversions into data types **/
// @returns raw rlp encoding in bytes
function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
bytes memory result = new bytes(item.len);
if (result.length == 0) return result;
uint256 ptr;
assembly {
ptr := add(0x20, result)
}
copy(item.memPtr, ptr, item.len);
return result;
}
// any non-zero byte is considered true
function toBoolean(RLPItem memory item) internal pure returns (bool) {
require(item.len == 1);
uint256 result;
uint256 memPtr = item.memPtr;
assembly {
result := byte(0, mload(memPtr))
}
return result == 0 ? false : true;
}
function toAddress(RLPItem memory item) internal pure returns (address) {
// 1 byte for the length prefix
require(item.len == 21);
return address(uint160(toUint(item)));
}
function toUint(RLPItem memory item) internal pure returns (uint256) {
require(item.len > 0 && item.len <= 33);
uint256 offset = _payloadOffset(item.memPtr);
uint256 len = item.len - offset;
uint256 result;
uint256 memPtr = item.memPtr + offset;
assembly {
result := mload(memPtr)
// shfit to the correct location if neccesary
if lt(len, 32) {
result := div(result, exp(256, sub(32, len)))
}
}
return result;
}
// enforces 32 byte length
function toUintStrict(RLPItem memory item) internal pure returns (uint256) {
// one byte prefix
require(item.len == 33);
uint256 result;
uint256 memPtr = item.memPtr + 1;
assembly {
result := mload(memPtr)
}
return result;
}
function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
require(item.len > 0);
uint256 offset = _payloadOffset(item.memPtr);
uint256 len = item.len - offset; // data length
bytes memory result = new bytes(len);
uint256 destPtr;
assembly {
destPtr := add(0x20, result)
}
copy(item.memPtr + offset, destPtr, len);
return result;
}
/*
* Private Helpers
*/
// @return number of payload items inside an encoded list.
function numItems(RLPItem memory item) private pure returns (uint256) {
if (item.len == 0) return 0;
uint256 count = 0;
uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);
uint256 endPtr = item.memPtr + item.len;
while (currPtr < endPtr) {
currPtr = currPtr + _itemLength(currPtr); // skip over an item
count++;
}
return count;
}
// @return entire rlp item byte length
function _itemLength(uint256 memPtr) private pure returns (uint256) {
uint256 itemLen;
uint256 byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START) itemLen = 1;
else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1;
else if (byte0 < LIST_SHORT_START) {
assembly {
let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
memPtr := add(memPtr, 1) // skip over the first byte
/* 32 byte word size */
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
itemLen := add(dataLen, add(byteLen, 1))
}
} else if (byte0 < LIST_LONG_START) {
itemLen = byte0 - LIST_SHORT_START + 1;
} else {
assembly {
let byteLen := sub(byte0, 0xf7)
memPtr := add(memPtr, 1)
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
itemLen := add(dataLen, add(byteLen, 1))
}
}
return itemLen;
}
// @return number of bytes until the data
function _payloadOffset(uint256 memPtr) private pure returns (uint256) {
uint256 byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START) return 0;
else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1;
else if (byte0 < LIST_SHORT_START)
// being explicit
return byte0 - (STRING_LONG_START - 1) + 1;
else return byte0 - (LIST_LONG_START - 1) + 1;
}
/*
* @param src Pointer to source
* @param dest Pointer to destination
* @param len Amount of memory to copy from the source
*/
function copy(
uint256 src,
uint256 dest,
uint256 len
) private pure {
if (len == 0) return;
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
if (len == 0) return;
// left over bytes. Mask is used to remove unwanted bytes from the word
uint256 mask = 256**(WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {RLPReader} from "./RLPReader.sol";
library ExitPayloadReader {
using RLPReader for bytes;
using RLPReader for RLPReader.RLPItem;
uint8 constant WORD_SIZE = 32;
struct ExitPayload {
RLPReader.RLPItem[] data;
}
struct Receipt {
RLPReader.RLPItem[] data;
bytes raw;
uint256 logIndex;
}
struct Log {
RLPReader.RLPItem data;
RLPReader.RLPItem[] list;
}
struct LogTopics {
RLPReader.RLPItem[] data;
}
// copy paste of private copy() from RLPReader to avoid changing of existing contracts
function copy(
uint256 src,
uint256 dest,
uint256 len
) private pure {
if (len == 0) return;
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
// left over bytes. Mask is used to remove unwanted bytes from the word
uint256 mask = 256**(WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
}
}
function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) {
RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList();
return ExitPayload(payloadData);
}
function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[0].toUint();
}
function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[1].toBytes();
}
function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[2].toUint();
}
function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[3].toUint();
}
function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) {
return bytes32(payload.data[4].toUint());
}
function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) {
return bytes32(payload.data[5].toUint());
}
function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) {
receipt.raw = payload.data[6].toBytes();
RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();
if (receiptItem.isList()) {
// legacy tx
receipt.data = receiptItem.toList();
} else {
// pop first byte before parsting receipt
bytes memory typedBytes = receipt.raw;
bytes memory result = new bytes(typedBytes.length - 1);
uint256 srcPtr;
uint256 destPtr;
assembly {
srcPtr := add(33, typedBytes)
destPtr := add(0x20, result)
}
copy(srcPtr, destPtr, result.length);
receipt.data = result.toRlpItem().toList();
}
receipt.logIndex = getReceiptLogIndex(payload);
return receipt;
}
function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[7].toBytes();
}
function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[8].toBytes();
}
function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[8].toUint();
}
function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[9].toUint();
}
// Receipt methods
function toBytes(Receipt memory receipt) internal pure returns (bytes memory) {
return receipt.raw;
}
function getLog(Receipt memory receipt) internal pure returns (Log memory) {
RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];
return Log(logData, logData.toList());
}
// Log methods
function getEmitter(Log memory log) internal pure returns (address) {
return RLPReader.toAddress(log.list[0]);
}
function getTopics(Log memory log) internal pure returns (LogTopics memory) {
return LogTopics(log.list[1].toList());
}
function getData(Log memory log) internal pure returns (bytes memory) {
return log.list[2].toBytes();
}
function toRlpBytes(Log memory log) internal pure returns (bytes memory) {
return log.data.toRlpBytes();
}
// LogTopics methods
function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) {
return topics.data[index];
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {RLPReader} from "./RLPReader.sol";
library MerklePatriciaProof {
/*
* @dev Verifies a merkle patricia proof.
* @param value The terminating value in the trie.
* @param encodedPath The path in the trie leading to value.
* @param rlpParentNodes The rlp encoded stack of nodes.
* @param root The root hash of the trie.
* @return The boolean validity of the proof.
*/
function verify(
bytes memory value,
bytes memory encodedPath,
bytes memory rlpParentNodes,
bytes32 root
) internal pure returns (bool) {
RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);
RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);
bytes memory currentNode;
RLPReader.RLPItem[] memory currentNodeList;
bytes32 nodeKey = root;
uint256 pathPtr = 0;
bytes memory path = _getNibbleArray(encodedPath);
if (path.length == 0) {
return false;
}
for (uint256 i = 0; i < parentNodes.length; i++) {
if (pathPtr > path.length) {
return false;
}
currentNode = RLPReader.toRlpBytes(parentNodes[i]);
if (nodeKey != keccak256(currentNode)) {
return false;
}
currentNodeList = RLPReader.toList(parentNodes[i]);
if (currentNodeList.length == 17) {
if (pathPtr == path.length) {
if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) {
return true;
} else {
return false;
}
}
uint8 nextPathNibble = uint8(path[pathPtr]);
if (nextPathNibble > 16) {
return false;
}
nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble]));
pathPtr += 1;
} else if (currentNodeList.length == 2) {
uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr);
if (pathPtr + traversed == path.length) {
//leaf node
if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) {
return true;
} else {
return false;
}
}
//extension node
if (traversed == 0) {
return false;
}
pathPtr += traversed;
nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));
} else {
return false;
}
}
return false;
}
function _nibblesToTraverse(
bytes memory encodedPartialPath,
bytes memory path,
uint256 pathPtr
) private pure returns (uint256) {
uint256 len = 0;
// encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath
// and slicedPath have elements that are each one hex character (1 nibble)
bytes memory partialPath = _getNibbleArray(encodedPartialPath);
bytes memory slicedPath = new bytes(partialPath.length);
// pathPtr counts nibbles in path
// partialPath.length is a number of nibbles
for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {
bytes1 pathNibble = path[i];
slicedPath[i - pathPtr] = pathNibble;
}
if (keccak256(partialPath) == keccak256(slicedPath)) {
len = partialPath.length;
} else {
len = 0;
}
return len;
}
// bytes b must be hp encoded
function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) {
bytes memory nibbles = "";
if (b.length > 0) {
uint8 offset;
uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));
if (hpNibble == 1 || hpNibble == 3) {
nibbles = new bytes(b.length * 2 - 1);
bytes1 oddNibble = _getNthNibbleOfBytes(1, b);
nibbles[0] = oddNibble;
offset = 1;
} else {
nibbles = new bytes(b.length * 2 - 2);
offset = 0;
}
for (uint256 i = offset; i < nibbles.length; i++) {
nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);
}
}
return nibbles;
}
function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) {
return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10);
}
}{
"remappings": [
"/=src/",
"ERC721M/=lib/ERC721M/src/",
"UDS/=lib/UDS/src/",
"ds-test/=lib/ERC721M/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"futils/=lib/futils/src/",
"fx-contracts/=lib/fx-contracts/src/",
"fx-portal/=lib/ERC721M/lib/fx-portal/contracts/",
"solady/=lib/solady/src/",
"solmate/=lib/solmate/src/",
"upgrade-scripts/=lib/upgrade-scripts/src/"
],
"optimizer": {
"enabled": true,
"runs": 0
},
"metadata": {
"bytecodeHash": "none"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"genesis_","type":"address"},{"internalType":"address","name":"troupe_","type":"address"},{"internalType":"address","name":"checkpointManager","type":"address"},{"internalType":"address","name":"fxRoot","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"CallerNotOwner","type":"error"},{"inputs":[],"name":"ExceedsLimit","type":"error"},{"inputs":[],"name":"FxChildUnset","type":"error"},{"inputs":[],"name":"IncorrectOwner","type":"error"},{"inputs":[],"name":"InvalidBurnAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointManager","outputs":[{"internalType":"contract ICheckpointManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[][]","name":"ids","type":"uint256[][]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"claimGenesis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fxChildTunnel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fxRoot","outputs":[{"internalType":"contract IFxStateSender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesis","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"genesisClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"exitHash","type":"bytes32"}],"name":"processedExits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fxChildTunnel_","type":"address"}],"name":"setFxChildTunnel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"troupe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6101406040523060805234801561001557600080fd5b50604051610ccd380380610ccd833981016040819052610034916100ec565b6001600160a01b0380831660c052811660a05261004f61007e565b6001600160a01b0380841660e052841661010052610070426224ea00610140565b610120525061016792505050565b303b1561009d5760405162dc149f60e41b815260040160405180910390fd5b7f87917b04fc43108fc3d291ac961b425fe1ddcf80087b2cb7e3c48f3e9233ea3380546001600160a01b03191633179055565b80516001600160a01b03811681146100e757600080fd5b919050565b6000806000806080858703121561010257600080fd5b61010b856100d0565b9350610119602086016100d0565b9250610127604086016100d0565b9150610135606086016100d0565b905092959194509250565b8082018082111561016157634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e0516101005161012051610b056101c8600039600061012a01526000818161021e015261058c01526000818161024501526103a10152600061027f0152600081816102a601526107eb015260005050610b056000f3fe608060405234801561001057600080fd5b50600436106100db5760003560e01c806306fdde03146100e05780633ccfa92f14610125578063486a7e6b1461015a578063607f2d421461016257806370d5ae051461018557806373b0f1191461019b57806373cb5534146101be5780638da5cb5b146101d357806395d89b41146101db578063972c4928146101fe578063a2bededf14610206578063a7f0b3de14610219578063acc85dab14610240578063aea4e49e14610267578063c0857ba01461027a578063de9b771f146102a1578063f2fde38b146102c8575b600080fd5b61010f6040518060400160405280601081526020016f5361666520486f75736520436c61696d60801b81525081565b60405161011c9190610928565b60405180910390f35b61014c7f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161011c565b61014c600581565b610175610170366004610942565b6102db565b604051901515815260200161011c565b61018e61dead81565b60405161011c919061095b565b6101756101a9366004610942565b60016020526000908152604090205460ff1681565b6101d16101cc3660046109ba565b6102fc565b005b61018e6104e8565b61010f604051806040016040528060048152602001635341464560e01b81525081565b61018e610501565b6101d16102143660046109ba565b61050b565b61018e7f000000000000000000000000000000000000000000000000000000000000000081565b61018e7f000000000000000000000000000000000000000000000000000000000000000081565b6101d1610275366004610a13565b6106c6565b61018e7f000000000000000000000000000000000000000000000000000000000000000081565b61018e7f000000000000000000000000000000000000000000000000000000000000000081565b6101d16102d6366004610a13565b6106f8565b60006102e5610793565b600092835260010160205250604090205460ff1690565b601481111561031e57604051632795088960e11b815260040160405180910390fd5b60005b818110156104e357600583838381811061033d5761033d610a30565b905060200281019061034f9190610a46565b90501461036f576040516302075cc160e41b815260040160405180910390fd5b60005b83838381811061038457610384610a30565b90506020028101906103969190610a46565b9050811015610480577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166323b872dd3361dead8787878181106103e4576103e4610a30565b90506020028101906103f69190610a46565b8681811061040657610406610a30565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561045d57600080fd5b505af1158015610471573d6000803e3d6000fd5b50505050806001019050610372565b506104db600080516020610ad9833981519152336040516024016104a4919061095b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526107b7565b600101610321565b505050565b60006104f2610882565b546001600160a01b0316919050565b60006104f2610793565b601481111561052d57604051632795088960e11b815260040160405180910390fd5b60005b818110156104e3576001600084848481811061054e5761054e610a30565b602090810292909201358352508101919091526040016000205460ff161561058957604051630c8d9eab60e31b815260040160405180910390fd5b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166388486f868585858181106105cb576105cb610a30565b905060200201356040518263ffffffff1660e01b81526004016105f091815260200190565b602060405180830381865afa15801561060d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106319190610a8f565b6001600160a01b03161461065857604051633a6bbed360e01b815260040160405180910390fd5b600180600085858581811061066f5761066f610a30565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055506106be600080516020610ad9833981519152336040516024016104a4919061095b565b600101610530565b6106ce6108a6565b806106d7610793565b80546001600160a01b0319166001600160a01b039290921691909117905550565b610700610882565b546001600160a01b0316336001600160a01b03161461073257604051632e6c18c960e11b815260040160405180910390fd5b8061073b610882565b80546001600160a01b0319166001600160a01b0392831617905560408051338152918316602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a150565b7f3849b0d9a476107bbeb9ff6ae9ec519d63a65bac06efa495b84a43dbacfd948490565b60006107c1610793565b546001600160a01b0316036107e957604051632bf41a0d60e21b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b4720477610820610793565b546040516001600160e01b031960e084901b16815261084d916001600160a01b0316908590600401610aac565b600060405180830381600087803b15801561086757600080fd5b505af115801561087b573d6000803e3d6000fd5b5050505050565b7f87917b04fc43108fc3d291ac961b425fe1ddcf80087b2cb7e3c48f3e9233ea3390565b6108ae610882565b546001600160a01b0316336001600160a01b0316146108e057604051632e6c18c960e11b815260040160405180910390fd5b565b6000815180845260005b81811015610908576020818501810151868301820152016108ec565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061093b60208301846108e2565b9392505050565b60006020828403121561095457600080fd5b5035919050565b6001600160a01b0391909116815260200190565b60008083601f84011261098157600080fd5b5081356001600160401b0381111561099857600080fd5b6020830191508360208260051b85010111156109b357600080fd5b9250929050565b600080602083850312156109cd57600080fd5b82356001600160401b038111156109e357600080fd5b6109ef8582860161096f565b90969095509350505050565b6001600160a01b0381168114610a1057600080fd5b50565b600060208284031215610a2557600080fd5b813561093b816109fb565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112610a5d57600080fd5b8301803591506001600160401b03821115610a7757600080fd5b6020019150600581901b36038213156109b357600080fd5b600060208284031215610aa157600080fd5b815161093b816109fb565b6001600160a01b0383168152604060208201819052600090610ad0908301846108e2565b94935050505056fe2b2b8ab4928cca6048d7e1598ac0acf11cf60dd123d74a91787e9c305dab64f6a164736f6c6343000811000a0000000000000000000000003ad30c5e2985e960e89f4a28efc91ba73e104b7700000000000000000000000074d9d90a7fc261fbe92ed47b606b6e0e00d75e7000000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100db5760003560e01c806306fdde03146100e05780633ccfa92f14610125578063486a7e6b1461015a578063607f2d421461016257806370d5ae051461018557806373b0f1191461019b57806373cb5534146101be5780638da5cb5b146101d357806395d89b41146101db578063972c4928146101fe578063a2bededf14610206578063a7f0b3de14610219578063acc85dab14610240578063aea4e49e14610267578063c0857ba01461027a578063de9b771f146102a1578063f2fde38b146102c8575b600080fd5b61010f6040518060400160405280601081526020016f5361666520486f75736520436c61696d60801b81525081565b60405161011c9190610928565b60405180910390f35b61014c7f0000000000000000000000000000000000000000000000000000000063838c4f81565b60405190815260200161011c565b61014c600581565b610175610170366004610942565b6102db565b604051901515815260200161011c565b61018e61dead81565b60405161011c919061095b565b6101756101a9366004610942565b60016020526000908152604090205460ff1681565b6101d16101cc3660046109ba565b6102fc565b005b61018e6104e8565b61010f604051806040016040528060048152602001635341464560e01b81525081565b61018e610501565b6101d16102143660046109ba565b61050b565b61018e7f0000000000000000000000003ad30c5e2985e960e89f4a28efc91ba73e104b7781565b61018e7f00000000000000000000000074d9d90a7fc261fbe92ed47b606b6e0e00d75e7081565b6101d1610275366004610a13565b6106c6565b61018e7f00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c28781565b61018e7f000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a281565b6101d16102d6366004610a13565b6106f8565b60006102e5610793565b600092835260010160205250604090205460ff1690565b601481111561031e57604051632795088960e11b815260040160405180910390fd5b60005b818110156104e357600583838381811061033d5761033d610a30565b905060200281019061034f9190610a46565b90501461036f576040516302075cc160e41b815260040160405180910390fd5b60005b83838381811061038457610384610a30565b90506020028101906103969190610a46565b9050811015610480577f00000000000000000000000074d9d90a7fc261fbe92ed47b606b6e0e00d75e706001600160a01b03166323b872dd3361dead8787878181106103e4576103e4610a30565b90506020028101906103f69190610a46565b8681811061040657610406610a30565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152606401600060405180830381600087803b15801561045d57600080fd5b505af1158015610471573d6000803e3d6000fd5b50505050806001019050610372565b506104db600080516020610ad9833981519152336040516024016104a4919061095b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526107b7565b600101610321565b505050565b60006104f2610882565b546001600160a01b0316919050565b60006104f2610793565b601481111561052d57604051632795088960e11b815260040160405180910390fd5b60005b818110156104e3576001600084848481811061054e5761054e610a30565b602090810292909201358352508101919091526040016000205460ff161561058957604051630c8d9eab60e31b815260040160405180910390fd5b337f0000000000000000000000003ad30c5e2985e960e89f4a28efc91ba73e104b776001600160a01b03166388486f868585858181106105cb576105cb610a30565b905060200201356040518263ffffffff1660e01b81526004016105f091815260200190565b602060405180830381865afa15801561060d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106319190610a8f565b6001600160a01b03161461065857604051633a6bbed360e01b815260040160405180910390fd5b600180600085858581811061066f5761066f610a30565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055506106be600080516020610ad9833981519152336040516024016104a4919061095b565b600101610530565b6106ce6108a6565b806106d7610793565b80546001600160a01b0319166001600160a01b039290921691909117905550565b610700610882565b546001600160a01b0316336001600160a01b03161461073257604051632e6c18c960e11b815260040160405180910390fd5b8061073b610882565b80546001600160a01b0319166001600160a01b0392831617905560408051338152918316602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a150565b7f3849b0d9a476107bbeb9ff6ae9ec519d63a65bac06efa495b84a43dbacfd948490565b60006107c1610793565b546001600160a01b0316036107e957604051632bf41a0d60e21b815260040160405180910390fd5b7f000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a26001600160a01b031663b4720477610820610793565b546040516001600160e01b031960e084901b16815261084d916001600160a01b0316908590600401610aac565b600060405180830381600087803b15801561086757600080fd5b505af115801561087b573d6000803e3d6000fd5b5050505050565b7f87917b04fc43108fc3d291ac961b425fe1ddcf80087b2cb7e3c48f3e9233ea3390565b6108ae610882565b546001600160a01b0316336001600160a01b0316146108e057604051632e6c18c960e11b815260040160405180910390fd5b565b6000815180845260005b81811015610908576020818501810151868301820152016108ec565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061093b60208301846108e2565b9392505050565b60006020828403121561095457600080fd5b5035919050565b6001600160a01b0391909116815260200190565b60008083601f84011261098157600080fd5b5081356001600160401b0381111561099857600080fd5b6020830191508360208260051b85010111156109b357600080fd5b9250929050565b600080602083850312156109cd57600080fd5b82356001600160401b038111156109e357600080fd5b6109ef8582860161096f565b90969095509350505050565b6001600160a01b0381168114610a1057600080fd5b50565b600060208284031215610a2557600080fd5b813561093b816109fb565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112610a5d57600080fd5b8301803591506001600160401b03821115610a7757600080fd5b6020019150600581901b36038213156109b357600080fd5b600060208284031215610aa157600080fd5b815161093b816109fb565b6001600160a01b0383168152604060208201819052600090610ad0908301846108e2565b94935050505056fe2b2b8ab4928cca6048d7e1598ac0acf11cf60dd123d74a91787e9c305dab64f6a164736f6c6343000811000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003ad30c5e2985e960e89f4a28efc91ba73e104b7700000000000000000000000074d9d90a7fc261fbe92ed47b606b6e0e00d75e7000000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
-----Decoded View---------------
Arg [0] : genesis_ (address): 0x3aD30c5e2985e960E89F4a28eFc91BA73e104b77
Arg [1] : troupe_ (address): 0x74d9d90a7fc261FBe92eD47B606b6E0E00d75E70
Arg [2] : checkpointManager (address): 0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287
Arg [3] : fxRoot (address): 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000003ad30c5e2985e960e89f4a28efc91ba73e104b77
Arg [1] : 00000000000000000000000074d9d90a7fc261fbe92ed47b606b6e0e00d75e70
Arg [2] : 00000000000000000000000086e4dc95c7fbdbf52e33d563bbdb00823894c287
Arg [3] : 000000000000000000000000fe5e5d361b2ad62c541bab87c45a0b9b018389a2
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.