Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 25 from a total of 26 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw | 30958536 | 39 days ago | IN | 0 ETH | 0.00000614 | ||||
| Transfer | 27178124 | 60 days ago | IN | 10 ETH | 0.00000487 | ||||
| Withdraw | 21233205 | 102 days ago | IN | 0 ETH | 0.00000505 | ||||
| Transfer | 20139040 | 119 days ago | IN | 10 ETH | 0.00000405 | ||||
| Withdraw | 20139021 | 119 days ago | IN | 0 ETH | 0.00000502 | ||||
| Transfer | 13302964 | 206 days ago | IN | 10 ETH | 0.00000402 | ||||
| Withdraw | 13302865 | 206 days ago | IN | 0 ETH | 0.00000517 | ||||
| Transfer | 13302841 | 206 days ago | IN | 0.05 ETH | 0.00000383 | ||||
| Set Approval Tar... | 13302839 | 206 days ago | IN | 0 ETH | 0.00000385 | ||||
| Set Approval Tar... | 13302836 | 206 days ago | IN | 0 ETH | 0.00000385 | ||||
| Set Payment Toke... | 13302834 | 206 days ago | IN | 0 ETH | 0.00000362 | ||||
| Set Payment Toke... | 13302832 | 206 days ago | IN | 0 ETH | 0.00000362 | ||||
| Set Authorized C... | 13302830 | 206 days ago | IN | 0 ETH | 0.00000387 | ||||
| Set Authorized C... | 13302828 | 206 days ago | IN | 0 ETH | 0.00000387 | ||||
| Set Authorized C... | 13302827 | 206 days ago | IN | 0 ETH | 0.00000387 | ||||
| Set Authorized C... | 13302824 | 206 days ago | IN | 0 ETH | 0.0000048 | ||||
| Transfer | 12967086 | 210 days ago | IN | 0.05 ETH | 0.00000383 | ||||
| Set Approval Tar... | 12967085 | 210 days ago | IN | 0 ETH | 0.0000037 | ||||
| Set Approval Tar... | 12967083 | 210 days ago | IN | 0 ETH | 0.0000037 | ||||
| Set Payment Toke... | 12967081 | 210 days ago | IN | 0 ETH | 0.0000037 | ||||
| Set Payment Toke... | 12967079 | 210 days ago | IN | 0 ETH | 0.0000037 | ||||
| Set Authorized C... | 12967077 | 210 days ago | IN | 0 ETH | 0.00000372 | ||||
| Set Authorized C... | 12967075 | 210 days ago | IN | 0 ETH | 0.00000372 | ||||
| Set Authorized C... | 12967072 | 210 days ago | IN | 0 ETH | 0.00000372 | ||||
| Set Authorized C... | 12967070 | 210 days ago | IN | 0 ETH | 0.00000372 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 30958536 | 39 days ago | 3.93370597 ETH | ||||
| 30162806 | 44 days ago | 0.00001313 ETH | ||||
| 30162557 | 44 days ago | 0.00001312 ETH | ||||
| 30100663 | 44 days ago | 0.00001312 ETH | ||||
| 30100637 | 44 days ago | 0.00001313 ETH | ||||
| 29809512 | 45 days ago | 0.00001458 ETH | ||||
| 29809477 | 45 days ago | 0.00001457 ETH | ||||
| 29809354 | 45 days ago | 0.00001458 ETH | ||||
| 29732695 | 46 days ago | 0.00001315 ETH | ||||
| 29732648 | 46 days ago | 0.00001315 ETH | ||||
| 29732566 | 46 days ago | 0.00001314 ETH | ||||
| 29732524 | 46 days ago | 0.00001315 ETH | ||||
| 29718243 | 46 days ago | 0.00001318 ETH | ||||
| 29713711 | 46 days ago | 0.00001327 ETH | ||||
| 29704640 | 46 days ago | 0.00001329 ETH | ||||
| 29704581 | 46 days ago | 0.00001302 ETH | ||||
| 29704463 | 46 days ago | 0.0000103 ETH | ||||
| 29702778 | 46 days ago | 0.00001328 ETH | ||||
| 29680449 | 46 days ago | 0.00001314 ETH | ||||
| 29680400 | 46 days ago | 0.00001315 ETH | ||||
| 29674031 | 46 days ago | 0.00001316 ETH | ||||
| 29665649 | 46 days ago | 0.00001315 ETH | ||||
| 29626919 | 46 days ago | 0.00001316 ETH | ||||
| 29626891 | 46 days ago | 0.00001315 ETH | ||||
| 29626849 | 46 days ago | 0.00001315 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
AGWMintPaymaster
Compiler Version
v0.8.28+commit.7893614a
ZkSolc Version
v1.5.11
Optimization Enabled:
Yes with Mode 3
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Transaction} from "@zksync-contracts-0.0.1/contracts/system-contracts/libraries/TransactionHelper.sol";
import {
IPaymaster,
ExecutionResult,
PAYMASTER_VALIDATION_SUCCESS_MAGIC
} from "@zksync-contracts-0.0.1/contracts/system-contracts/interfaces/IPaymaster.sol";
import {BOOTLOADER_FORMAL_ADDRESS} from "@zksync-contracts-0.0.1/contracts/system-contracts/Constants.sol";
import {Ownable} from "solady-0.1.12/src/auth/Ownable.sol";
import {SafeTransferLib} from "solady-0.1.12/src/utils/ext/zksync/SafeTransferLib.sol";
import {IAGWRegistry} from "./interfaces/IAGWRegistry.sol";
contract AGWMintPaymaster is IPaymaster, Ownable {
using SafeTransferLib for address;
using SafeTransferLib for address payable;
error OnlyBootloader();
error OnlyAGW();
error WithdrawalFailed();
error BootloaderCallFailed();
error UnauthorizedCall();
mapping(address target => mapping(bytes4 selector => bool authorized)) private _authorizedCalls;
mapping(address token => bool isPaymentToken) private _paymentTokens;
mapping(address target => bool isApprovalTarget) private _approvalTargets;
IAGWRegistry public immutable AGW_REGISTRY = IAGWRegistry(0xd5E3efDA6bB5aB545cc2358796E96D9033496Dda);
constructor(address _owner) {
_initializeOwner(_owner);
}
function validateAndPayForPaymasterTransaction(bytes32, bytes32, Transaction calldata _transaction)
external
payable
returns (bytes4 magic, bytes memory context)
{
if (msg.sender != BOOTLOADER_FORMAL_ADDRESS) {
revert OnlyBootloader();
}
if (!AGW_REGISTRY.isAGW(address(uint160(_transaction.from)))) {
revert OnlyAGW();
}
address target = address(uint160(_transaction.to));
if (_transaction.data.length == 0) {
revert UnauthorizedCall();
}
bytes4 selector = bytes4(_transaction.data[0:4]);
if (selector == 0x095ea7b3) {
if (!_paymentTokens[target]) {
revert UnauthorizedCall();
}
(address approvalTarget,) = abi.decode(_transaction.data[4:], (address, uint256));
if (!_approvalTargets[approvalTarget]) {
revert UnauthorizedCall();
}
} else if (!isAuthorized(target, selector)) {
revert UnauthorizedCall();
}
context = "";
magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC;
uint256 requiredETH = _transaction.gasLimit * _transaction.maxFeePerGas;
BOOTLOADER_FORMAL_ADDRESS.safeTransferETH(requiredETH);
}
function isAuthorized(address target, bytes4 selector) public view returns (bool) {
return _authorizedCalls[target][selector];
}
function setAuthorizedCall(address target, bytes4 selector, bool authorized) external onlyOwner {
_authorizedCalls[target][selector] = authorized;
}
function setPaymentToken(address token, bool isPaymentToken) external onlyOwner {
_paymentTokens[token] = isPaymentToken;
}
function setApprovalTarget(address target, bool isApprovalTarget) external onlyOwner {
_approvalTargets[target] = isApprovalTarget;
}
function postTransaction(
bytes calldata _context,
Transaction calldata _transaction,
bytes32 _txHash,
bytes32 _suggestedSignedHash,
ExecutionResult _txResult,
uint256 _maxRefundedGas
) external payable {}
function withdraw() external onlyOwner {
msg.sender.safeTransferAllETH();
}
function withdrawPartial(uint256 amount) external onlyOwner {
msg.sender.safeTransferETH(amount);
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
/// @dev The type id of ZKsync's EIP-712-signed transaction.
uint8 constant EIP_712_TX_TYPE = 0x71;
/// @dev The type id of legacy transactions.
uint8 constant LEGACY_TX_TYPE = 0x0;
/// @dev The type id of legacy transactions.
uint8 constant EIP_2930_TX_TYPE = 0x01;
/// @dev The type id of EIP1559 transactions.
uint8 constant EIP_1559_TX_TYPE = 0x02;
/// @notice Structure used to represent a ZKsync transaction.
struct Transaction {
// The type of the transaction.
uint256 txType;
// The caller.
uint256 from;
// The callee.
uint256 to;
// The gasLimit to pass with the transaction.
// It has the same meaning as Ethereum's gasLimit.
uint256 gasLimit;
// The maximum amount of gas the user is willing to pay for a byte of pubdata.
uint256 gasPerPubdataByteLimit;
// The maximum fee per gas that the user is willing to pay.
// It is akin to EIP1559's maxFeePerGas.
uint256 maxFeePerGas;
// The maximum priority fee per gas that the user is willing to pay.
// It is akin to EIP1559's maxPriorityFeePerGas.
uint256 maxPriorityFeePerGas;
// The transaction's paymaster. If there is no paymaster, it is equal to 0.
uint256 paymaster;
// The nonce of the transaction.
uint256 nonce;
// The value to pass with the transaction.
uint256 value;
// In the future, we might want to add some
// new fields to the struct. The `txData` struct
// is to be passed to account and any changes to its structure
// would mean a breaking change to these accounts. In order to prevent this,
// we should keep some fields as "reserved".
// It is also recommended that their length is fixed, since
// it would allow easier proof integration (in case we will need
// some special circuit for preprocessing transactions).
uint256[4] reserved;
// The transaction's calldata.
bytes data;
// The signature of the transaction.
bytes signature;
// The properly formatted hashes of bytecodes that must be published on L1
// with the inclusion of this transaction. Note, that a bytecode has been published
// before, the user won't pay fees for its republishing.
bytes32[] factoryDeps;
// The input to the paymaster.
bytes paymasterInput;
// Reserved dynamic type for the future use-case. Using it should be avoided,
// But it is still here, just in case we want to enable some additional functionality.
bytes reservedDynamic;
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
import {Transaction} from "../libraries/TransactionHelper.sol";
enum ExecutionResult {
Revert,
Success
}
bytes4 constant PAYMASTER_VALIDATION_SUCCESS_MAGIC = IPaymaster
.validateAndPayForPaymasterTransaction
.selector;
interface IPaymaster {
/// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
/// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
/// address.
/// @param _txHash The hash of the transaction
/// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
/// @param _transaction The transaction itself.
/// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
/// if the paymaster agrees to pay for the transaction.
/// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
/// passed to the `postTransaction` method of the account.
/// @dev The developer should strive to preserve as many steps as possible both for valid
/// and invalid transactions as this very method is also used during the gas fee estimation
/// (without some of the necessary data, e.g. signature).
function validateAndPayForPaymasterTransaction(
bytes32 _txHash,
bytes32 _suggestedSignedHash,
Transaction calldata _transaction
) external payable returns (bytes4 magic, bytes memory context);
/// @dev Called by the bootloader after the execution of the transaction. Please note that
/// there is no guarantee that this method will be called at all. Unlike the original EIP4337,
/// this method won't be called if the transaction execution results in out-of-gas.
/// @param _context, the context of the execution, returned by the "validateAndPayForPaymasterTransaction" method.
/// @param _transaction, the users' transaction.
/// @param _txResult, the result of the transaction execution (success or failure).
/// @param _maxRefundedGas, the upper bound on the amount of gas that could be refunded to the paymaster.
/// @dev The exact amount refunded depends on the gas spent by the "postOp" itself and so the developers should
/// take that into account.
function postTransaction(
bytes calldata _context,
Transaction calldata _transaction,
bytes32 _txHash,
bytes32 _suggestedSignedHash,
ExecutionResult _txResult,
uint256 _maxRefundedGas
) external payable;
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol";
import {INonceHolder} from "./interfaces/INonceHolder.sol";
import {IContractDeployer} from "./interfaces/IContractDeployer.sol";
import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol";
import {IImmutableSimulator} from "./interfaces/IImmutableSimulator.sol";
import {IBaseToken} from "./interfaces/IBaseToken.sol";
import {IBridgehub} from "./interfaces/IBridgehub.sol";
import {IL1Messenger} from "./interfaces/IL1Messenger.sol";
import {ISystemContext} from "./interfaces/ISystemContext.sol";
import {ICompressor} from "./interfaces/ICompressor.sol";
import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol";
import {IBootloaderUtilities} from "./interfaces/IBootloaderUtilities.sol";
import {IPubdataChunkPublisher} from "./interfaces/IPubdataChunkPublisher.sol";
import {IMessageRoot} from "./interfaces/IMessageRoot.sol";
import {ICreate2Factory} from "./interfaces/ICreate2Factory.sol";
/// @dev All the system contracts introduced by ZKsync have their addresses
/// started from 2^15 in order to avoid collision with Ethereum precompiles.
uint160 constant SYSTEM_CONTRACTS_OFFSET = 0x8000; // 2^15
/// @dev Unlike the value above, it is not overridden for the purpose of testing and
/// is identical to the constant value actually used as the system contracts offset on
/// mainnet.
uint160 constant REAL_SYSTEM_CONTRACTS_OFFSET = 0x8000;
/// @dev All the system contracts must be located in the kernel space,
/// i.e. their addresses must be below 2^16.
uint160 constant MAX_SYSTEM_CONTRACT_ADDRESS = 0xffff; // 2^16 - 1
/// @dev The offset from which the built-in, but user space contracts are located.
uint160 constant USER_CONTRACTS_OFFSET = MAX_SYSTEM_CONTRACT_ADDRESS + 1;
address constant ECRECOVER_SYSTEM_CONTRACT = address(0x01);
address constant SHA256_SYSTEM_CONTRACT = address(0x02);
address constant ECADD_SYSTEM_CONTRACT = address(0x06);
address constant ECMUL_SYSTEM_CONTRACT = address(0x07);
address constant ECPAIRING_SYSTEM_CONTRACT = address(0x08);
/// @dev The number of gas that need to be spent for a single byte of pubdata regardless of the pubdata price.
/// This variable is used to ensure the following:
/// - That the long-term storage of the operator is compensated properly.
/// - That it is not possible that the pubdata counter grows too high without spending proportional amount of computation.
uint256 constant COMPUTATIONAL_PRICE_FOR_PUBDATA = 80;
/// @dev The maximal possible address of an L1-like precompie. These precompiles maintain the following properties:
/// - Their extcodehash is EMPTY_STRING_KECCAK
/// - Their extcodesize is 0 despite having a bytecode formally deployed there.
uint256 constant CURRENT_MAX_PRECOMPILE_ADDRESS = 0xff;
address payable constant BOOTLOADER_FORMAL_ADDRESS = payable(address(SYSTEM_CONTRACTS_OFFSET + 0x01));
IAccountCodeStorage constant ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT = IAccountCodeStorage(
address(SYSTEM_CONTRACTS_OFFSET + 0x02)
);
INonceHolder constant NONCE_HOLDER_SYSTEM_CONTRACT = INonceHolder(address(SYSTEM_CONTRACTS_OFFSET + 0x03));
IKnownCodesStorage constant KNOWN_CODE_STORAGE_CONTRACT = IKnownCodesStorage(address(SYSTEM_CONTRACTS_OFFSET + 0x04));
IImmutableSimulator constant IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT = IImmutableSimulator(
address(SYSTEM_CONTRACTS_OFFSET + 0x05)
);
IContractDeployer constant DEPLOYER_SYSTEM_CONTRACT = IContractDeployer(address(SYSTEM_CONTRACTS_OFFSET + 0x06));
IContractDeployer constant REAL_DEPLOYER_SYSTEM_CONTRACT = IContractDeployer(address(REAL_SYSTEM_CONTRACTS_OFFSET + 0x06));
// A contract that is allowed to deploy any codehash
// on any address. To be used only during an upgrade.
address constant FORCE_DEPLOYER = address(SYSTEM_CONTRACTS_OFFSET + 0x07);
IL1Messenger constant L1_MESSENGER_CONTRACT = IL1Messenger(address(SYSTEM_CONTRACTS_OFFSET + 0x08));
address constant MSG_VALUE_SYSTEM_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x09);
IBaseToken constant BASE_TOKEN_SYSTEM_CONTRACT = IBaseToken(address(SYSTEM_CONTRACTS_OFFSET + 0x0a));
IBaseToken constant REAL_BASE_TOKEN_SYSTEM_CONTRACT = IBaseToken(address(REAL_SYSTEM_CONTRACTS_OFFSET + 0x0a));
ICreate2Factory constant L2_CREATE2_FACTORY = ICreate2Factory(address(USER_CONTRACTS_OFFSET));
address constant L2_ASSET_ROUTER = address(USER_CONTRACTS_OFFSET + 0x03);
IBridgehub constant L2_BRIDGE_HUB = IBridgehub(address(USER_CONTRACTS_OFFSET + 0x02));
address constant L2_NATIVE_TOKEN_VAULT_ADDR = address(USER_CONTRACTS_OFFSET + 0x04);
IMessageRoot constant L2_MESSAGE_ROOT = IMessageRoot(address(USER_CONTRACTS_OFFSET + 0x05));
// Note, that on its own this contract does not provide much functionality, but having it on a constant address
// serves as a convenient storage for its bytecode to be accessible via `extcodehash`.
address constant SLOAD_CONTRACT_ADDRESS = address(USER_CONTRACTS_OFFSET + 0x06);
address constant WRAPPED_BASE_TOKEN_IMPL_ADDRESS = address(USER_CONTRACTS_OFFSET + 0x07);
// Hardcoded because even for tests we should keep the address. (Instead `SYSTEM_CONTRACTS_OFFSET + 0x10`)
// Precompile call depends on it.
// And we don't want to mock this contract.
address constant KECCAK256_SYSTEM_CONTRACT = address(0x8010);
ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(payable(address(SYSTEM_CONTRACTS_OFFSET + 0x0b)));
ISystemContext constant REAL_SYSTEM_CONTEXT_CONTRACT = ISystemContext(payable(address(REAL_SYSTEM_CONTRACTS_OFFSET + 0x0b)));
IBootloaderUtilities constant BOOTLOADER_UTILITIES = IBootloaderUtilities(address(SYSTEM_CONTRACTS_OFFSET + 0x0c));
// It will be a different value for tests, while shouldn't. But for now, this constant is not used by other contracts, so that's fine.
address constant EVENT_WRITER_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x0d);
ICompressor constant COMPRESSOR_CONTRACT = ICompressor(address(SYSTEM_CONTRACTS_OFFSET + 0x0e));
IComplexUpgrader constant COMPLEX_UPGRADER_CONTRACT = IComplexUpgrader(address(SYSTEM_CONTRACTS_OFFSET + 0x0f));
IPubdataChunkPublisher constant PUBDATA_CHUNK_PUBLISHER = IPubdataChunkPublisher(
address(SYSTEM_CONTRACTS_OFFSET + 0x11)
);
/// @dev If the bitwise AND of the extraAbi[2] param when calling the MSG_VALUE_SIMULATOR
/// is non-zero, the call will be assumed to be a system one.
uint256 constant MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT = 1;
/// @dev The maximal msg.value that context can have
uint256 constant MAX_MSG_VALUE = type(uint128).max;
/// @dev Prefix used during derivation of account addresses using CREATE2
/// @dev keccak256("zksyncCreate2")
bytes32 constant CREATE2_PREFIX = 0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c088b7fc7c103c00ca494;
/// @dev Prefix used during derivation of account addresses using CREATE
/// @dev keccak256("zksyncCreate")
bytes32 constant CREATE_PREFIX = 0x63bae3a9951d38e8a3fbb7b70909afc1200610fc5bc55ade242f815974674f23;
/// @dev Each state diff consists of 156 bytes of actual data and 116 bytes of unused padding, needed for circuit efficiency.
uint256 constant STATE_DIFF_ENTRY_SIZE = 272;
enum SystemLogKey {
L2_TO_L1_LOGS_TREE_ROOT_KEY,
PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY,
CHAINED_PRIORITY_TXN_HASH_KEY,
NUMBER_OF_LAYER_1_TXS_KEY,
// Note, that it is important that `PREV_BATCH_HASH_KEY` has position
// `4` since it is the same as it was in the previous protocol version and
// it is the only one that is emitted before the system contracts are upgraded.
PREV_BATCH_HASH_KEY,
L2_DA_VALIDATOR_OUTPUT_HASH_KEY,
USED_L2_DA_VALIDATOR_ADDRESS_KEY,
EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY
}
/// @dev The number of leaves in the L2->L1 log Merkle tree.
/// While formally a tree of any length is acceptable, the node supports only a constant length of 16384 leaves.
uint256 constant L2_TO_L1_LOGS_MERKLE_TREE_LEAVES = 16_384;
/// @dev The length of the derived key in bytes inside compressed state diffs.
uint256 constant DERIVED_KEY_LENGTH = 32;
/// @dev The length of the enum index in bytes inside compressed state diffs.
uint256 constant ENUM_INDEX_LENGTH = 8;
/// @dev The length of value in bytes inside compressed state diffs.
uint256 constant VALUE_LENGTH = 32;
/// @dev The length of the compressed initial storage write in bytes.
uint256 constant COMPRESSED_INITIAL_WRITE_SIZE = DERIVED_KEY_LENGTH + VALUE_LENGTH;
/// @dev The length of the compressed repeated storage write in bytes.
uint256 constant COMPRESSED_REPEATED_WRITE_SIZE = ENUM_INDEX_LENGTH + VALUE_LENGTH;
/// @dev The position from which the initial writes start in the compressed state diffs.
uint256 constant INITIAL_WRITE_STARTING_POSITION = 4;
/// @dev Each storage diffs consists of the following elements:
/// [20bytes address][32bytes key][32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value]
/// @dev The offset of the derived key in a storage diff.
uint256 constant STATE_DIFF_DERIVED_KEY_OFFSET = 52;
/// @dev The offset of the enum index in a storage diff.
uint256 constant STATE_DIFF_ENUM_INDEX_OFFSET = 84;
/// @dev The offset of the final value in a storage diff.
uint256 constant STATE_DIFF_FINAL_VALUE_OFFSET = 124;
/// @dev Total number of bytes in a blob. Blob = 4096 field elements * 31 bytes per field element
/// @dev EIP-4844 defines it as 131_072 but we use 4096 * 31 within our circuits to always fit within a field element
/// @dev Our circuits will prove that a EIP-4844 blob and our internal blob are the same.
uint256 constant BLOB_SIZE_BYTES = 126_976;
/// @dev Max number of blobs currently supported
uint256 constant MAX_NUMBER_OF_BLOBS = 6;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The caller is not authorized to call the function.
error Unauthorized();
/// @dev The `newOwner` cannot be the zero address.
error NewOwnerIsZeroAddress();
/// @dev The `pendingOwner` does not have a valid handover request.
error NoHandoverRequest();
/// @dev Cannot double-initialize.
error AlreadyInitialized();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ownership is transferred from `oldOwner` to `newOwner`.
/// This event is intentionally kept the same as OpenZeppelin's Ownable to be
/// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
/// despite it not being as lightweight as a single argument event.
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
/// @dev An ownership handover to `pendingOwner` has been requested.
event OwnershipHandoverRequested(address indexed pendingOwner);
/// @dev The ownership handover to `pendingOwner` has been canceled.
event OwnershipHandoverCanceled(address indexed pendingOwner);
/// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;
/// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;
/// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The owner slot is given by:
/// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
/// It is intentionally chosen to be a high value
/// to avoid collision with lower slots.
/// The choice of manual storage layout is to enable compatibility
/// with both regular and upgradeable contracts.
bytes32 internal constant _OWNER_SLOT =
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;
/// The ownership handover slot of `newOwner` is given by:
/// ```
/// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
/// let handoverSlot := keccak256(0x00, 0x20)
/// ```
/// It stores the expiry timestamp of the two-step ownership handover.
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
function _guardInitializeOwner() internal pure virtual returns (bool guard) {}
/// @dev Initializes the owner directly without authorization guard.
/// This function must be called upon initialization,
/// regardless of whether the contract is upgradeable or not.
/// This is to enable generalization to both regular and upgradeable contracts,
/// and to save gas in case the initial owner is not the caller.
/// For performance reasons, this function will not check if there
/// is an existing owner.
function _initializeOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
if sload(ownerSlot) {
mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
revert(0x1c, 0x04)
}
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
} else {
/// @solidity memory-safe-assembly
assembly {
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Store the new value.
sstore(_OWNER_SLOT, newOwner)
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
}
}
}
/// @dev Sets the owner directly without authorization guard.
function _setOwner(address newOwner) internal virtual {
if (_guardInitializeOwner()) {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
}
} else {
/// @solidity memory-safe-assembly
assembly {
let ownerSlot := _OWNER_SLOT
// Clean the upper 96 bits.
newOwner := shr(96, shl(96, newOwner))
// Emit the {OwnershipTransferred} event.
log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
// Store the new value.
sstore(ownerSlot, newOwner)
}
}
}
/// @dev Throws if the sender is not the owner.
function _checkOwner() internal view virtual {
/// @solidity memory-safe-assembly
assembly {
// If the caller is not the stored owner, revert.
if iszero(eq(caller(), sload(_OWNER_SLOT))) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Returns how long a two-step ownership handover is valid for in seconds.
/// Override to return a different value if needed.
/// Made internal to conserve bytecode. Wrap it in a public function if needed.
function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
return 48 * 3600;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC UPDATE FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Allows the owner to transfer the ownership to `newOwner`.
function transferOwnership(address newOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
if iszero(shl(96, newOwner)) {
mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
revert(0x1c, 0x04)
}
}
_setOwner(newOwner);
}
/// @dev Allows the owner to renounce their ownership.
function renounceOwnership() public payable virtual onlyOwner {
_setOwner(address(0));
}
/// @dev Request a two-step ownership handover to the caller.
/// The request will automatically expire in 48 hours (172800 seconds) by default.
function requestOwnershipHandover() public payable virtual {
unchecked {
uint256 expires = block.timestamp + _ownershipHandoverValidFor();
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to `expires`.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), expires)
// Emit the {OwnershipHandoverRequested} event.
log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
}
}
/// @dev Cancels the two-step ownership handover to the caller, if any.
function cancelOwnershipHandover() public payable virtual {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
sstore(keccak256(0x0c, 0x20), 0)
// Emit the {OwnershipHandoverCanceled} event.
log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
}
}
/// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
/// Reverts if there is no existing ownership handover requested by `pendingOwner`.
function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
let handoverSlot := keccak256(0x0c, 0x20)
// If the handover does not exist, or has expired.
if gt(timestamp(), sload(handoverSlot)) {
mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
revert(0x1c, 0x04)
}
// Set the handover slot to 0.
sstore(handoverSlot, 0)
}
_setOwner(pendingOwner);
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PUBLIC READ FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the owner of the contract.
function owner() public view virtual returns (address result) {
/// @solidity memory-safe-assembly
assembly {
result := sload(_OWNER_SLOT)
}
}
/// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
function ownershipHandoverExpiresAt(address pendingOwner)
public
view
virtual
returns (uint256 result)
{
/// @solidity memory-safe-assembly
assembly {
// Compute the handover slot.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
// Load the handover slot.
result := sload(keccak256(0x0c, 0x20))
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* MODIFIERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Marks a function as only callable by the owner.
modifier onlyOwner() virtual {
_checkOwner();
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import {SingleUseETHVault} from "./SingleUseETHVault.sol";
/// @notice Library for force safe transferring ETH and ERC20s in ZKsync.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SafeTransferLib.sol)
library SafeTransferLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* EVENTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev A single use ETH vault has been created for `to`, with `amount`.
event SingleUseETHVaultCreated(address indexed to, uint256 amount, address vault);
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The ETH transfer has failed.
error ETHTransferFailed();
/// @dev The ERC20 `transferFrom` has failed.
error TransferFromFailed();
/// @dev The ERC20 `transfer` has failed.
error TransferFailed();
/// @dev The ERC20 `approve` has failed.
error ApproveFailed();
/// @dev The ERC20 `totalSupply` query has failed.
error TotalSupplyQueryFailed();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Suggested gas stipend for contract receiving ETH to perform a few
/// storage reads and writes, but low enough to prevent griefing.
uint256 internal constant GAS_STIPEND_NO_GRIEF = 1000000;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ETH OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
//
// The regular variants:
// - Forwards all remaining gas to the target.
// - Reverts if the target reverts.
// - Reverts if the current contract has insufficient balance.
//
// The force variants:
// - Forwards with an optional gas stipend
// (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
// - If the target reverts, or if the gas stipend is exhausted,
// creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
// Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
// - Reverts if the current contract has insufficient balance.
//
// The try variants:
// - Forwards with a mandatory gas stipend.
// - Instead of reverting, returns whether the transfer succeeded.
/// @dev Sends `amount` (in wei) ETH to `to`.
function safeTransferETH(address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
if iszero(call(gas(), to, amount, 0x00, 0x00, 0x00, 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Sends all the ETH in the current contract to `to`.
function safeTransferAllETH(address to) internal {
/// @solidity memory-safe-assembly
assembly {
// Transfer all the ETH and check if it succeeded or not.
if iszero(call(gas(), to, selfbalance(), 0x00, 0x00, 0x00, 0x00)) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
}
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (address vault)
{
if (amount == uint256(0)) return address(0); // Early return if `amount` is zero.
uint256 selfBalanceBefore = address(this).balance;
/// @solidity memory-safe-assembly
assembly {
if lt(selfBalanceBefore, amount) {
mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
revert(0x1c, 0x04)
}
pop(call(gasStipend, to, amount, 0x00, 0x00, 0x00, 0x00))
}
if (address(this).balance == selfBalanceBefore) {
vault = address(new SingleUseETHVault());
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, shr(96, shl(96, to)))
if iszero(call(gas(), vault, amount, 0x00, 0x20, 0x00, 0x00)) { revert(0x00, 0x00) }
}
emit SingleUseETHVaultCreated(to, amount, vault);
}
}
/// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (address vault)
{
vault = forceSafeTransferETH(to, address(this).balance, gasStipend);
}
/// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferETH(address to, uint256 amount) internal returns (address vault) {
vault = forceSafeTransferETH(to, amount, GAS_STIPEND_NO_GRIEF);
}
/// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
/// If force transfer is used, returns the vault. Else returns `address(0)`.
function forceSafeTransferAllETH(address to) internal returns (address vault) {
vault = forceSafeTransferETH(to, address(this).balance, GAS_STIPEND_NO_GRIEF);
}
/// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, amount, 0x00, 0x00, 0x00, 0x00)
}
}
/// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
success := call(gasStipend, to, selfbalance(), 0x00, 0x00, 0x00, 0x00)
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ERC20 OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have at least `amount` approved for
/// the current contract to manage.
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
///
/// The `from` account must have at least `amount` approved for the current contract to manage.
function trySafeTransferFrom(address token, address from, address to, uint256 amount)
internal
returns (bool success)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
success := lt(or(iszero(extcodesize(token)), returndatasize()), success)
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends all of ERC20 `token` from `from` to `to`.
/// Reverts upon failure.
///
/// The `from` account must have their entire balance approved for the current contract to manage.
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
/// @solidity memory-safe-assembly
assembly {
let m := mload(0x40) // Cache the free memory pointer.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(96, from)) // Store the `from` argument.
mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x60, 0) // Restore the zero slot to zero.
mstore(0x40, m) // Restore the free memory pointer.
}
}
/// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransfer(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sends all of ERC20 `token` from the current contract to `to`.
/// Reverts upon failure.
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
mstore(0x20, address()) // Store the address of the current contract.
// Read the balance, reverting upon failure.
if iszero(
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
mstore(0x14, to) // Store the `to` argument.
amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
// Perform the transfer, reverting upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// Reverts upon failure.
function safeApprove(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
/// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
/// then retries the approval again (some tokens, e.g. USDT, requires this).
/// Reverts upon failure.
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
// Perform the approval, retrying upon failure.
let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x34, 0) // Store 0 for the `amount`.
mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
pop(call(gas(), token, 0, 0x10, 0x44, 0x00, 0x00)) // Reset the approval.
mstore(0x34, amount) // Store back the original `amount`.
// Retry the approval, reverting upon failure.
success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
if iszero(and(eq(mload(0x00), 1), success)) {
// Check the `extcodesize` again just in case the token selfdestructs lol.
if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
revert(0x1c, 0x04)
}
}
}
}
mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
}
}
/// @dev Returns the amount of ERC20 `token` owned by `account`.
/// Returns zero if the `token` does not exist.
function balanceOf(address token, address account) internal view returns (uint256 amount) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x14, account) // Store the `account` argument.
mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
amount :=
mul( // The arguments of `mul` are evaluated from right to left.
mload(0x20),
and( // The arguments of `and` are evaluated from right to left.
gt(returndatasize(), 0x1f), // At least 32 bytes returned.
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
/// @dev Returns the total supply of the `token`.
/// Reverts if the token does not exist or does not implement `totalSupply()`.
function totalSupply(address token) internal view returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, 0x18160ddd) // `totalSupply()`.
if iszero(
and(gt(returndatasize(), 0x1f), staticcall(gas(), token, 0x1c, 0x04, 0x00, 0x20))
) {
mstore(0x00, 0x54cd9435) // `TotalSupplyQueryFailed()`.
revert(0x1c, 0x04)
}
result := mload(0x00)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IAGWRegistry {
function isAGW(address user) external view returns (bool);
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
interface IAccountCodeStorage {
function storeAccountConstructingCodeHash(
address _address,
bytes32 _hash
) external;
function storeAccountConstructedCodeHash(
address _address,
bytes32 _hash
) external;
function markAccountCodeHashAsConstructed(address _address) external;
function getRawCodeHash(
address _address
) external view returns (bytes32 codeHash);
function getCodeHash(
uint256 _input
) external view returns (bytes32 codeHash);
function getCodeSize(
uint256 _input
) external view returns (uint256 codeSize);
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
/**
* @author Matter Labs
* @dev Interface of the nonce holder contract -- a contract used by the system to ensure
* that there is always a unique identifier for a transaction with a particular account (we call it nonce).
* In other words, the pair of (address, nonce) should always be unique.
* @dev Custom accounts should use methods of this contract to store nonces or other possible unique identifiers
* for the transaction.
*/
interface INonceHolder {
event ValueSetUnderNonce(
address indexed accountAddress,
uint256 indexed key,
uint256 value
);
/// @dev Returns the current minimal nonce for account.
function getMinNonce(address _address) external view returns (uint256);
/// @dev Returns the raw version of the current minimal nonce
/// (equal to minNonce + 2^128 * deployment nonce).
function getRawNonce(address _address) external view returns (uint256);
/// @dev Increases the minimal nonce for the msg.sender.
function increaseMinNonce(uint256 _value) external returns (uint256);
/// @dev Sets the nonce value `key` as used.
function setValueUnderNonce(uint256 _key, uint256 _value) external;
/// @dev Gets the value stored inside a custom nonce.
function getValueUnderNonce(uint256 _key) external view returns (uint256);
/// @dev A convenience method to increment the minimal nonce if it is equal
/// to the `_expectedNonce`.
function incrementMinNonceIfEquals(uint256 _expectedNonce) external;
/// @dev Returns the deployment nonce for the accounts used for CREATE opcode.
function getDeploymentNonce(
address _address
) external view returns (uint256);
/// @dev Increments the deployment nonce for the account and returns the previous one.
function incrementDeploymentNonce(
address _address
) external returns (uint256);
/// @dev Determines whether a certain nonce has been already used for an account.
function validateNonceUsage(
address _address,
uint256 _key,
bool _shouldBeUsed
) external view;
/// @dev Returns whether a nonce has been used for an account.
function isNonceUsed(
address _address,
uint256 _nonce
) external view returns (bool);
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
/// @notice A struct that describes a forced deployment on an address
struct ForceDeployment {
// The bytecode hash to put on an address
bytes32 bytecodeHash;
// The address on which to deploy the bytecodehash to
address newAddress;
// Whether to run the constructor on the force deployment
bool callConstructor;
// The value with which to initialize a contract
uint256 value;
// The constructor calldata
bytes input;
}
interface IContractDeployer {
/// @notice Defines the version of the account abstraction protocol
/// that a contract claims to follow.
/// - `None` means that the account is just a contract and it should never be interacted
/// with as a custom account
/// - `Version1` means that the account follows the first version of the account abstraction protocol
enum AccountAbstractionVersion {
None,
Version1
}
/// @notice Defines the nonce ordering used by the account
/// - `Sequential` means that it is expected that the nonces are monotonic and increment by 1
/// at a time (the same as EOAs).
/// - `Arbitrary` means that the nonces for the accounts can be arbitrary. The operator
/// should serve the transactions from such an account on a first-come-first-serve basis.
/// @dev This ordering is more of a suggestion to the operator on how the AA expects its transactions
/// to be processed and is not considered as a system invariant.
enum AccountNonceOrdering {
Sequential,
Arbitrary
}
struct AccountInfo {
AccountAbstractionVersion supportedAAVersion;
AccountNonceOrdering nonceOrdering;
}
event ContractDeployed(
address indexed deployerAddress,
bytes32 indexed bytecodeHash,
address indexed contractAddress
);
event AccountNonceOrderingUpdated(
address indexed accountAddress,
AccountNonceOrdering nonceOrdering
);
event AccountVersionUpdated(
address indexed accountAddress,
AccountAbstractionVersion aaVersion
);
function getNewAddressCreate2(
address _sender,
bytes32 _bytecodeHash,
bytes32 _salt,
bytes calldata _input
) external view returns (address newAddress);
function getNewAddressCreate(
address _sender,
uint256 _senderNonce
) external pure returns (address newAddress);
function create2(
bytes32 _salt,
bytes32 _bytecodeHash,
bytes calldata _input
) external payable returns (address newAddress);
function create2Account(
bytes32 _salt,
bytes32 _bytecodeHash,
bytes calldata _input,
AccountAbstractionVersion _aaVersion
) external payable returns (address newAddress);
/// @dev While the `_salt` parameter is not used anywhere here,
/// it is still needed for consistency between `create` and
/// `create2` functions (required by the compiler).
function create(
bytes32 _salt,
bytes32 _bytecodeHash,
bytes calldata _input
) external payable returns (address newAddress);
/// @dev While `_salt` is never used here, we leave it here as a parameter
/// for the consistency with the `create` function.
function createAccount(
bytes32 _salt,
bytes32 _bytecodeHash,
bytes calldata _input,
AccountAbstractionVersion _aaVersion
) external payable returns (address newAddress);
/// @notice Returns the information about a certain AA.
function getAccountInfo(
address _address
) external view returns (AccountInfo memory info);
/// @notice Can be called by an account to update its account version
function updateAccountVersion(AccountAbstractionVersion _version) external;
/// @notice Can be called by an account to update its nonce ordering
function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external;
/// @notice This method is to be used only during an upgrade to set bytecodes on specific addresses.
function forceDeployOnAddresses(
ForceDeployment[] calldata _deployments
) external payable;
}// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice The interface for the KnownCodesStorage contract, which is responsible * for storing the hashes of the bytecodes that have been published to the network. */ interface IKnownCodesStorage { event MarkedAsKnown( bytes32 indexed bytecodeHash, bool indexed sendBytecodeToL1 ); function markFactoryDeps( bool _shouldSendToL1, bytes32[] calldata _hashes ) external; function markBytecodeAsPublished(bytes32 _bytecodeHash) external; function getMarker(bytes32 _hash) external view returns (uint256); }
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
struct ImmutableData {
uint256 index;
bytes32 value;
}
interface IImmutableSimulator {
function getImmutable(
address _dest,
uint256 _index
) external view returns (bytes32);
function setImmutables(
address _dest,
ImmutableData[] calldata _immutables
) external;
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
interface IBaseToken {
function balanceOf(uint256) external view returns (uint256);
function transferFromTo(
address _from,
address _to,
uint256 _amount
) external;
function totalSupply() external view returns (uint256);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function mint(address _account, uint256 _amount) external;
function withdraw(address _l1Receiver) external payable;
function withdrawWithMessage(
address _l1Receiver,
bytes calldata _additionalData
) external payable;
event Mint(address indexed account, uint256 amount);
event Transfer(address indexed from, address indexed to, uint256 value);
event Withdrawal(
address indexed _l2Sender,
address indexed _l1Receiver,
uint256 _amount
);
event WithdrawalWithMessage(
address indexed _l2Sender,
address indexed _l1Receiver,
uint256 _amount,
bytes _additionalData
);
}// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /// @author Matter Labs /// @custom:security-contact [email protected] interface IBridgehub { function setAddresses( address _assetRouter, address _ctmDeployer, address _messageRoot ) external; function owner() external view returns (address); }
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
/// @dev The log passed from L2
/// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter. All other values are not used but are reserved for the future
/// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address.
/// This field is required formally but does not have any special meaning.
/// @param txNumberInBlock The L2 transaction number in a block, in which the log was sent
/// @param sender The L2 address which sent the log
/// @param key The 32 bytes of information that was sent in the log
/// @param value The 32 bytes of information that was sent in the log
// Both `key` and `value` are arbitrary 32-bytes selected by the log sender
struct L2ToL1Log {
uint8 l2ShardId;
bool isService;
uint16 txNumberInBlock;
address sender;
bytes32 key;
bytes32 value;
}
/// @dev Bytes in raw L2 to L1 log
/// @dev Equal to the bytes size of the tuple - (uint8 ShardId, bool isService, uint16 txNumberInBlock, address sender, bytes32 key, bytes32 value)
uint256 constant L2_TO_L1_LOG_SERIALIZE_SIZE = 88;
/// @dev The value of default leaf hash for L2 to L1 logs Merkle tree
/// @dev An incomplete fixed-size tree is filled with this value to be a full binary tree
/// @dev Actually equal to the `keccak256(new bytes(L2_TO_L1_LOG_SERIALIZE_SIZE))`
bytes32 constant L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH = 0x72abee45b59e344af8a6e520241c4744aff26ed411f4c4b00f8af09adada43ba;
/// @dev The current version of state diff compression being used.
uint256 constant STATE_DIFF_COMPRESSION_VERSION_NUMBER = 1;
/**
* @author Matter Labs
* @custom:security-contact [email protected]
* @notice The interface of the L1 Messenger contract, responsible for sending messages to L1.
*/
interface IL1Messenger {
// Possibly in the future we will be able to track the messages sent to L1 with
// some hooks in the VM. For now, it is much easier to track them with L2 events.
event L1MessageSent(
address indexed _sender,
bytes32 indexed _hash,
bytes _message
);
event L2ToL1LogSent(L2ToL1Log _l2log);
event BytecodeL1PublicationRequested(bytes32 _bytecodeHash);
function sendToL1(bytes calldata _message) external returns (bytes32);
function sendL2ToL1Log(
bool _isService,
bytes32 _key,
bytes32 _value
) external returns (uint256 logIdInMerkleTree);
// This function is expected to be called only by the KnownCodesStorage system contract
function requestBytecodeL1Publication(bytes32 _bytecodeHash) external;
}// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice Contract that stores some of the context variables, that may be either * block-scoped, tx-scoped or system-wide. */ interface ISystemContext { struct BlockInfo { uint128 timestamp; uint128 number; } /// @notice A structure representing the timeline for the upgrade from the batch numbers to the L2 block numbers. /// @dev It will be used for the L1 batch -> L2 block migration in Q3 2023 only. struct VirtualBlockUpgradeInfo { /// @notice In order to maintain consistent results for `blockhash` requests, we'll /// have to remember the number of the batch when the upgrade to the virtual blocks has been done. /// The hashes for virtual blocks before the upgrade are identical to the hashes of the corresponding batches. uint128 virtualBlockStartBatch; /// @notice L2 block when the virtual blocks have caught up with the L2 blocks. Starting from this block, /// all the information returned to users for block.timestamp/number, etc should be the information about the L2 blocks and /// not virtual blocks. uint128 virtualBlockFinishL2Block; } function chainId() external view returns (uint256); function origin() external view returns (address); function gasPrice() external view returns (uint256); function blockGasLimit() external view returns (uint256); function coinbase() external view returns (address); function difficulty() external view returns (uint256); function baseFee() external view returns (uint256); function txNumberInBlock() external view returns (uint16); function getBlockHashEVM(uint256 _block) external view returns (bytes32); function getBatchHash( uint256 _batchNumber ) external view returns (bytes32 hash); function getBlockNumber() external view returns (uint128); function getBlockTimestamp() external view returns (uint128); function getBatchNumberAndTimestamp() external view returns (uint128 blockNumber, uint128 blockTimestamp); function getL2BlockNumberAndTimestamp() external view returns (uint128 blockNumber, uint128 blockTimestamp); function gasPerPubdataByte() external view returns (uint256 gasPerPubdataByte); function getCurrentPubdataSpent() external view returns (uint256 currentPubdataSpent); function setChainId(uint256 _newChainId) external; }
// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; // The bitmask by applying which to the compressed state diff metadata we retrieve its operation. uint8 constant OPERATION_BITMASK = 7; // The number of bits shifting the compressed state diff metadata by which we retrieve its length. uint8 constant LENGTH_BITS_OFFSET = 3; // The maximal length in bytes that an enumeration index can have. uint8 constant MAX_ENUMERATION_INDEX_SIZE = 8; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice The interface for the Compressor contract, responsible for verifying the correctness of * the compression of the state diffs and bytecodes. */ interface ICompressor { function publishCompressedBytecode( bytes calldata _bytecode, bytes calldata _rawCompressedData ) external returns (bytes32 bytecodeHash); function verifyCompressedStateDiffs( uint256 _numberOfStateDiffs, uint256 _enumerationIndexSize, bytes calldata _stateDiffs, bytes calldata _compressedStateDiffs ) external returns (bytes32 stateDiffHash); }
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
import {ForceDeployment} from "./IContractDeployer.sol";
/**
* @author Matter Labs
* @custom:security-contact [email protected]
* @notice The interface for the ComplexUpgrader contract.
*/
interface IComplexUpgrader {
function forceDeployAndUpgrade(
ForceDeployment[] calldata _forceDeployments,
address _delegateTo,
bytes calldata _calldata
) external payable;
function upgrade(
address _delegateTo,
bytes calldata _calldata
) external payable;
}// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
import {Transaction} from "../libraries/TransactionHelper.sol";
interface IBootloaderUtilities {
function getTransactionHashes(
Transaction calldata _transaction
) external view returns (bytes32 txHash, bytes32 signedTxHash);
}// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** * @author Matter Labs * @custom:security-contact [email protected] * @notice Interface for contract responsible chunking pubdata into the appropriate size for EIP-4844 blobs. */ interface IPubdataChunkPublisher { /// @notice Chunks pubdata into pieces that can fit into blobs. /// @param _pubdata The total l2 to l1 pubdata that will be sent via L1 blobs. /// @dev Note: This is an early implementation, in the future we plan to support up to 16 blobs per l1 batch. function chunkPubdataToBlobs( bytes calldata _pubdata ) external pure returns (bytes32[] memory blobLinearHashes); }
// SPDX-License-Identifier: MIT // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.0; /** * @author Matter Labs * @notice MessageRoot contract is responsible for storing and aggregating the roots of the batches from different chains into the MessageRoot. * @custom:security-contact [email protected] */ interface IMessageRoot { /// @notice The aggregated root of the batches from different chains. /// @return aggregatedRoot of the batches from different chains. function getAggregatedRoot() external view returns (bytes32 aggregatedRoot); }
// SPDX-License-Identifier: MIT
// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version.
pragma solidity ^0.8.0;
import {IContractDeployer} from "./IContractDeployer.sol";
/// @custom:security-contact [email protected]
/// @author Matter Labs
/// @notice The contract that can be used for deterministic contract deployment.
interface ICreate2Factory {
/// @notice Function that calls the `create2` method of the `ContractDeployer` contract.
/// @dev This function accepts the same parameters as the `create2` function of the ContractDeployer system contract,
/// so that we could efficiently relay the calldata.
function create2(
bytes32, // _salt
bytes32, // _bytecodeHash
bytes calldata // _input
) external payable returns (address);
/// @notice Function that calls the `create2Account` method of the `ContractDeployer` contract.
/// @dev This function accepts the same parameters as the `create2Account` function of the ContractDeployer system contract,
/// so that we could efficiently relay the calldata.
function create2Account(
bytes32, // _salt
bytes32, // _bytecodeHash
bytes calldata, // _input
IContractDeployer.AccountAbstractionVersion // _aaVersion
) external payable returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice A single-use vault that allows a designated caller to withdraw all ETH in it.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ext/zksync/SingleUseETHVault.sol)
contract SingleUseETHVault {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Unable to withdraw all.
error WithdrawAllFailed();
/// @dev Not authorized.
error Unauthorized();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* WITHDRAW ALL */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
fallback() external payable virtual {
/// @solidity memory-safe-assembly
assembly {
mstore(0x40, 0) // Optimization trick to remove free memory pointer initialization.
let owner := sload(0)
// Initialization.
if iszero(owner) {
sstore(0, calldataload(0x00)) // Store the owner.
return(0x00, 0x00) // Early return.
}
// Authorization check.
if iszero(eq(caller(), owner)) {
mstore(0x00, 0x82b42900) // `Unauthorized()`.
revert(0x1c, 0x04)
}
let to := calldataload(0x00)
// If the calldata is less than 32 bytes, zero-left-pad it to 32 bytes.
// Then use the rightmost 20 bytes of the word as the `to` address.
// This allows for the calldata to be `abi.encode(to)` or `abi.encodePacked(to)`.
to := shr(mul(lt(calldatasize(), 0x20), shl(3, sub(0x20, calldatasize()))), to)
// If `to` is `address(0)`, set it to `msg.sender`.
to := xor(mul(xor(to, caller()), iszero(to)), to)
// Transfers the whole balance to `to`.
if iszero(call(gas(), to, selfbalance(), 0x00, 0x00, 0x00, 0x00)) {
mstore(0x00, 0x651aee10) // `WithdrawAllFailed()`.
revert(0x1c, 0x04)
}
}
}
}{
"viaIR": false,
"codegen": "yul",
"remappings": [
"@zksync-contracts-0.0.1/=dependencies/@zksync-contracts-0.0.1/",
"forge-std-1.9.6/=dependencies/forge-std-1.9.6/",
"solady-0.1.12/=dependencies/solady-0.1.12/",
"forge-std/=lib/forge-std/src/",
"forge-zksync-std/=dependencies/@zksync-contracts-0.0.1/dependencies/forge-zksync-std-0.0.1/",
"openzeppelin-contracts/=dependencies/@zksync-contracts-0.0.1/dependencies/openzeppelin-contracts-5.2.0/"
],
"evmVersion": "cancun",
"outputSelection": {
"*": {
"*": [
"abi"
]
}
},
"optimizer": {
"enabled": true,
"mode": "3",
"size_fallback": false,
"disable_system_request_memoization": true
},
"metadata": {},
"libraries": {},
"enableEraVMExtensions": false,
"forceEVMLA": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BootloaderCallFailed","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"OnlyAGW","type":"error"},{"inputs":[],"name":"OnlyBootloader","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnauthorizedCall","type":"error"},{"inputs":[],"name":"WithdrawalFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"AGW_REGISTRY","outputs":[{"internalType":"contract IAGWRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_context","type":"bytes"},{"components":[{"internalType":"uint256","name":"txType","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"gasPerPubdataByteLimit","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"paymaster","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256[4]","name":"reserved","type":"uint256[4]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32[]","name":"factoryDeps","type":"bytes32[]"},{"internalType":"bytes","name":"paymasterInput","type":"bytes"},{"internalType":"bytes","name":"reservedDynamic","type":"bytes"}],"internalType":"struct Transaction","name":"_transaction","type":"tuple"},{"internalType":"bytes32","name":"_txHash","type":"bytes32"},{"internalType":"bytes32","name":"_suggestedSignedHash","type":"bytes32"},{"internalType":"enum ExecutionResult","name":"_txResult","type":"uint8"},{"internalType":"uint256","name":"_maxRefundedGas","type":"uint256"}],"name":"postTransaction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isApprovalTarget","type":"bool"}],"name":"setApprovalTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"bool","name":"authorized","type":"bool"}],"name":"setAuthorizedCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"isPaymentToken","type":"bool"}],"name":"setPaymentToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes32","name":"","type":"bytes32"},{"components":[{"internalType":"uint256","name":"txType","type":"uint256"},{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"gasPerPubdataByteLimit","type":"uint256"},{"internalType":"uint256","name":"maxFeePerGas","type":"uint256"},{"internalType":"uint256","name":"maxPriorityFeePerGas","type":"uint256"},{"internalType":"uint256","name":"paymaster","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256[4]","name":"reserved","type":"uint256[4]"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32[]","name":"factoryDeps","type":"bytes32[]"},{"internalType":"bytes","name":"paymasterInput","type":"bytes"},{"internalType":"bytes","name":"reservedDynamic","type":"bytes"}],"internalType":"struct Transaction","name":"_transaction","type":"tuple"}],"name":"validateAndPayForPaymasterTransaction","outputs":[{"internalType":"bytes4","name":"magic","type":"bytes4"},{"internalType":"bytes","name":"context","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawPartial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
9c4d535b000000000000000000000000000000000000000000000000000000000000000001000155f97e678847cb3bf14ef132a90131a18616f2d396ac6573c50520299600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000be7cfa9c97342ca6c689b9fe3f3001c90f2895fd
Deployed Bytecode
0x00020000000000020006000000000002000100000001035500000060031002700000010d0030019d0000010d0330019700000001002001900000002c0000c13d0000008002000039000000400020043f000000040030008c000000680000413d000000000201043b000000e002200270000001160020009c0000006c0000213d000001220020009c0000007a0000213d000001280020009c000000cd0000213d0000012b0020009c000001440000613d0000012c0020009c0000025e0000c13d000000240030008c0000025e0000413d0000000002000416000000000002004b0000025e0000c13d0000011202000041000000000402041a0000000002000411000000000042004b0000026c0000c13d0000000401100370000000000301043b00000000010004140000010d0010009c0000010d01008041000000c001100210000000000003004b000002700000c13d0000000002040019000000ef0000013d0000000002000416000000000002004b0000025e0000c13d0000001f023000390000010e02200197000000a002200039000000400020043f0000001f0430018f0000010f05300198000000a0025000390000003d0000613d000000a006000039000000000701034f000000007807043c0000000006860436000000000026004b000000390000c13d000000000004004b0000004a0000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000200030008c0000025e0000413d000000a00600043d000001100060009c0000025e0000213d0000011101000041000000800010043f0000011201000041000000000061041b00000000010004140000010d0010009c0000010d01008041000000c00110021000000113011001c70000800d02000039000000030300003900000114040000410000000005000019043004260000040f00000001002001900000025e0000613d000000800100043d0000014000000443000001600010044300000020010000390000010000100443000000010100003900000120001004430000011501000041000004310001042e000000000003004b0000025e0000c13d0000000001000019000004310001042e000001170020009c000000980000213d0000011d0020009c000000f00000213d000001200020009c000001a10000613d000001210020009c0000025e0000c13d0000000001000416000000000001004b0000025e0000c13d0000011201000041000000000101041a000001290000013d000001230020009c000001180000213d000001260020009c000001c10000613d000001270020009c0000025e0000c13d0000012d010000410000000c0010043f0000000001000411000000000010043f00000000010004140000010d0010009c0000010d01008041000000c00110021000000131011001c700008010020000390430042b0000040f00000001002001900000025e0000613d000000000101043b000000000001041b00000000010004140000010d0010009c0000010d01008041000000c00110021000000113011001c70000800d0200003900000002030000390000013b04000041000002130000013d000001180020009c0000012d0000213d0000011b0020009c000001d20000613d0000011c0020009c0000025e0000c13d000000240030008c0000025e0000413d0000000401100370000000000101043b000400000001001d000001100010009c0000025e0000213d0000011201000041000000000101041a0000000002000411000000000012004b0000026c0000c13d0000012d010000410000000c0010043f0000000401000029000000000010043f00000000010004140000010d0010009c0000010d01008041000000c00110021000000131011001c700008010020000390430042b0000040f00000001002001900000025e0000613d000000000101043b000200000001001d000000000101041a000300000001001d0000013201000041000000000010044300000000010004140000010d0010009c0000010d01008041000000c00110021000000133011001c70000800b020000390430042b0000040f0000000100200190000002600000613d000000000101043b000000030010006c000002820000a13d0000013401000041000000000010043f00000130010000410000043200010430000001290020009c000001ed0000613d0000012a0020009c0000025e0000c13d0000000001000416000000000001004b0000025e0000c13d0000011201000041000000000201041a0000000001000411000000000021004b0000026c0000c13d000400000002001d0000013c0100004100000000001004430000000001000410000000040010044300000000010004140000010d0010009c0000010d01008041000000c0011002100000013d011001c70000800a020000390430042b0000040f0000000100200190000002600000613d000000000301043b00000000010004140000010d0010009c0000010d01008041000000c001100210000000000003004b000002730000c13d0000000402000029000002770000013d0000011e0020009c000002180000613d0000011f0020009c0000025e0000c13d000000440030008c0000025e0000413d0000000002000416000000000002004b0000025e0000c13d0000000401100370000000000101043b000400000001001d000001100010009c0000025e0000213d043003ca0000040f0000000402000029000000000020043f000000200000043f000400000001001d00000040020000390000000001000019043003f30000040f00000004020000290000013502200197000000000020043f000000200010043f00000000010000190000004002000039043003f30000040f000000000101041a000000ff001001900000000001000039000000010100c039000000400200043d00000000001204350000010d0020009c0000010d02008041000000400120021000000136011001c7000004310001042e000001240020009c000002430000613d000001250020009c0000025e0000c13d0000000001000416000000000001004b0000025e0000c13d0000000001000412000600000001001d000500000000003d000080050100003900000044030000390000000004000415000000060440008a00000005044002100000013a02000041043004080000040f0000011001100197000000800010043f0000012e01000041000004310001042e000001190020009c000002580000613d0000011a0020009c0000025e0000c13d000000240030008c0000025e0000413d0000000002000416000000000002004b0000025e0000c13d0000000401100370000000000101043b000001100010009c0000025e0000213d0000012d020000410000000c0020043f000000000010043f0000000c010000390000002002000039043003f30000040f000000000101041a000000800010043f0000012e01000041000004310001042e000000640030008c0000025e0000413d0000004402100370000000000202043b000400000002001d000001380020009c0000025e0000213d000000040230006a000001390020009c0000025e0000213d000002640020008c0000025e0000413d0000000002000411000080010020008c0000027e0000c13d0000014302000041000000800020043f0000000402000029000300240020003d0000000301100360000000000101043b0000011001100197000000840010043f0000013a01000041000000000010044300000000010004120000000400100443000000240000044300000000010004140000010d0010009c0000010d01008041000000c00110021000000144011001c700008005020000390430042b0000040f0000000100200190000002600000613d000000000101043b000000000300041400000110021001970000010d0030009c0000010d03008041000000c00130021000000145011001c70430042b0000040f00000060031002700000010d03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf000000800a000039000001800000613d000000000801034f000000008908043c000000000a9a043600000000005a004b0000017c0000c13d000000000006004b0000018d0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000002880000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c0000025e0000413d000000800100043d000000000001004b0000000002000039000000010200c039000000000021004b0000025e0000c13d000000000001004b000002a60000c13d0000014f01000041000000000010043f00000142010000410000043200010430000000c40030008c0000025e0000413d0000000402100370000000000202043b000001380020009c0000025e0000213d0000002304200039000000000034004b0000025e0000813d0000000404200039000000000441034f000000000404043b000001380040009c0000025e0000213d00000000024200190000002402200039000000000032004b0000025e0000213d0000002402100370000000000202043b000001380020009c0000025e0000213d0000000002230049000001390020009c0000025e0000213d000002640020008c0000025e0000413d0000008401100370000000000101043b000000010010008c0000006a0000a13d0000025e0000013d000000440030008c0000025e0000413d0000000002000416000000000002004b0000025e0000c13d0000000401100370000000000101043b000400000001001d000001100010009c0000025e0000213d043003bf0000040f000300000001001d043003d20000040f0000000401000029000000000010043f0000000101000039000001e20000013d000000440030008c0000025e0000413d0000000002000416000000000002004b0000025e0000c13d0000000401100370000000000101043b000400000001001d000001100010009c0000025e0000213d043003bf0000040f000300000001001d043003d20000040f0000000401000029000000000010043f0000000201000039000000200010043f00000040020000390000000001000019043003f30000040f000000000301041a0000015002300197000000030000006b000000010220c1bf000000000021041b0000000001000019000004310001042e0000012d010000410000000c0010043f0000000001000411000000000010043f0000013201000041000000000010044300000000010004140000010d0010009c0000010d01008041000000c00110021000000133011001c70000800b020000390430042b0000040f0000000100200190000002600000613d000000000101043b000400000001001d00000000010004140000010d0010009c0000010d01008041000000c00110021000000131011001c700008010020000390430042b0000040f00000001002001900000025e0000613d000000000101043b00000004020000290000013e0220009a000000000021041b00000000010004140000010d0010009c0000010d01008041000000c00110021000000113011001c70000800d0200003900000002030000390000013f040000410000000005000411043004260000040f00000001002001900000006a0000c13d0000025e0000013d000000640030008c0000025e0000413d0000000002000416000000000002004b0000025e0000c13d0000000402100370000000000202043b000400000002001d000001100020009c0000025e0000213d0000002402100370000000000202043b000300000002001d00000137002001980000025e0000c13d0000004401100370000000000201043b000000000002004b0000000001000039000000010100c039000200000002001d000000000012004b0000025e0000c13d043003d20000040f0000000401000029000000000010043f000000200000043f00000040020000390000000001000019043003f30000040f00000003020000290000013502200197000000000020043f000000200010043f00000000010000190000004002000039043003f30000040f000000000301041a000001500230019700000002022001af000000000021041b0000000001000019000004310001042e0000011201000041000000000501041a0000000001000411000000000051004b0000026c0000c13d00000000010004140000010d0010009c0000010d01008041000000c00110021000000113011001c70000800d02000039000000030300003900000114040000410000000006000019043004260000040f00000001002001900000025e0000613d0000011201000041000000000001041b0000000001000019000004310001042e000000240030008c0000025e0000413d0000000401100370000000000101043b000001100010009c000002610000a13d00000000010000190000043200010430000000000001042f0000011202000041000000000202041a0000000003000411000000000023004b0000026c0000c13d000000000001004b000002850000c13d0000012f01000041000000000010043f000001300100004100000432000104300000014001000041000000000010043f0000013001000041000004320001043000000113011001c70000800902000039000002760000013d00000113011001c7000080090200003900000004040000290000000005000019043004260000040f00000001002001900000006a0000c13d0000014c01000041000000000010043f000001300100004100000432000104300000014101000041000000000010043f000001420100004100000432000104300000000201000029000000000001041b0000000401000029043003dc0000040f0000000001000019000004310001042e0000001f0530018f0000010f06300198000000400200043d0000000004620019000002930000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000028f0000c13d000000000005004b000002a00000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500000060013002100000010d0020009c0000010d020080410000004002200210000000000112019f00000432000104300000000308000029000201a00080003d00000001010003670000000202100360000000000402043b0000000003000031000000040230006a000000230220008a00000146052001970000014606400197000000000756013f000000000056004b00000000050000190000014605004041000000000024004b00000000020000190000014602008041000001460070009c000000000502c0190000002002800039000000000221034f000000000202043b000000000005004b0000025e0000c13d0000000405000029000300040050003d0000000305400029000000000451034f000000000404043b000001380040009c0000025e0000213d0000000006430049000000200350003900000146056001970000014607300197000000000857013f000000000057004b00000000050000190000014605004041000000000063004b00000000060000190000014606002041000001460080009c000000000506c019000000000005004b0000025e0000c13d000000000004004b000002da0000c13d0000014e01000041000000000010043f00000142010000410000043200010430000000040040008c0000025e0000413d0000011002200197000000000131034f000000000101043b000000000020043f0000013501100197000100000001001d000001470010009c000003290000c13d0000000101000039000000200010043f00000000010004140000010d0010009c0000010d01008041000000c00110021000000148011001c700008010020000390430042b0000040f00000001002001900000025e0000613d000000000101043b000000000101041a000000ff00100190000002d60000613d00000001010003670000000202100360000000000202043b0000000003000031000000040430006a000000230440008a00000146054001970000014606200197000000000756013f000000000056004b00000000050000190000014605004041000000000042004b00000000040000190000014604008041000001460070009c000000000504c019000000000005004b0000025e0000c13d0000000302200029000000000421034f000000000404043b000001380040009c0000025e0000213d000000040040008c0000025e0000413d00000000034300490000002005200039000000000035004b0000000006000019000001460600204100000146033001970000014605500197000000000735013f000000000035004b00000000030000190000014603004041000001460070009c000000000306c019000000000003004b0000025e0000c13d000000040340008a000000400030008c0000025e0000413d0000002402200039000000000121034f000000000101043b000001100010009c0000025e0000213d000000000010043f0000000201000039000000200010043f0000000001000414000003380000013d000000200000043f00000000010004140000010d0010009c0000010d01008041000000c00110021000000148011001c700008010020000390430042b0000040f00000001002001900000025e0000613d000000000101043b0000000102000029000000000020043f000000200010043f00000000010004140000010d0010009c0000010d01008041000000c00110021000000148011001c700008010020000390430042b0000040f00000001002001900000025e0000613d000000000101043b000000000101041a000000ff00100190000002d60000613d000000400100043d000400000001001d000001490010009c0000034e0000a13d0000014a01000041000000000010043f0000004101000039000000040010043f0000014b01000041000004320001043000000004020000290000002001200039000300000001001d000000400010043f00000000000204350000000204000029000001600140008a0000000103100367000001200140008a0000000101100367000000000101043b000000000203043b000000000002004b000003830000c13d00000000010004140000010d0010009c0000010d01008041000000c0011002100000800102000039043004260000040f00000001002001900000027a0000613d000000400100043d0000002002100039000000400300003900000000003204350000014d020000410000000000210435000000040200002900000000020204330000004003100039000000000023043500000151062001970000001f0520018f0000006004100039000000030040006b0000039b0000813d000000000006004b0000037f0000613d00000003085000290000000007540019000000200770008a000000200880008a0000000009670019000000000a680019000000000a0a04330000000000a90435000000200660008c000003790000c13d000000000005004b000003b20000613d0000000007040019000003a70000013d00000000032100a900000000022300d9000000000021004b000003950000c13d0000000001000414000000000003004b0000035d0000613d0000010d0010009c0000010d01008041000000c00110021000000113011001c7000080090200003900008001040000390000000005000019043004260000040f00000001002001900000027a0000613d000003640000013d0000014a01000041000000000010043f0000001101000039000000040010043f0000014b0100004100000432000104300000000007640019000000000006004b000003a40000613d00000003080000290000000009040019000000008a0804340000000009a90436000000000079004b000003a00000c13d000000000005004b000003b20000613d000300030060002d0000000305500210000000000607043300000000065601cf000000000656022f000000030800002900000000080804330000010005500089000000000858022f00000000055801cf000000000565019f00000000005704350000001f0520003900000151035001970000000002420019000000000002043500000060023000390000010d0020009c0000010d0200804100000060022002100000010d0010009c0000010d010080410000004001100210000000000112019f000004310001042e00000024010000390000000101100367000000000101043b000000000001004b0000000002000039000000010200c039000000000021004b000003c80000c13d000000000001042d0000000001000019000004320001043000000024010000390000000101100367000000000101043b0000013700100198000003d00000c13d000000000001042d000000000100001900000432000104300000011201000041000000000101041a0000000002000411000000000012004b000003d80000c13d000000000001042d0000014001000041000000000010043f0000013001000041000004320001043000010000000000020000011202000041000000000502041a000000000200041400000110061001970000010d0020009c0000010d02008041000000c00120021000000113011001c70000800d0200003900000003030000390000011404000041000100000006001d043004260000040f0000000100200190000003f00000613d00000112010000410000000102000029000000000021041b000000000001042d00000000010000190000043200010430000000000001042f0000010d0010009c0000010d0100804100000040011002100000010d0020009c0000010d020080410000006002200210000000000112019f00000000020004140000010d0020009c0000010d02008041000000c002200210000000000112019f00000113011001c700008010020000390430042b0000040f0000000100200190000004060000613d000000000101043b000000000001042d0000000001000019000004320001043000000000050100190000000000200443000000050030008c000004160000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b0000040e0000413d0000010d0030009c0000010d03008041000000600130021000000000020004140000010d0020009c0000010d02008041000000c002200210000000000112019f00000152011001c700000000020500190430042b0000040f0000000100200190000004250000613d000000000101043b000000000001042d000000000001042f00000429002104210000000102000039000000000001042d0000000002000019000000000001042d0000042e002104230000000102000039000000000001042d0000000002000019000000000001042d0000043000000432000004310001042e0000043200010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000d5e3efda6bb5ab545cc2358796e96d9033496ddaffffffffffffffffffffffffffffffffffffffffffffffffffffffff7487392702000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000817b17ef00000000000000000000000000000000000000000000000000000000e55ff36500000000000000000000000000000000000000000000000000000000f2fde38a00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000fee81cf400000000000000000000000000000000000000000000000000000000e55ff36600000000000000000000000000000000000000000000000000000000f04e283e00000000000000000000000000000000000000000000000000000000b66d348b00000000000000000000000000000000000000000000000000000000b66d348c00000000000000000000000000000000000000000000000000000000d9972b9600000000000000000000000000000000000000000000000000000000817b17f0000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000430884ce00000000000000000000000000000000000000000000000000000000715018a500000000000000000000000000000000000000000000000000000000715018a600000000000000000000000000000000000000000000000000000000739d755600000000000000000000000000000000000000000000000000000000430884cf0000000000000000000000000000000000000000000000000000000054d1f13d00000000000000000000000000000000000000000000000000000000256929610000000000000000000000000000000000000000000000000000000025692962000000000000000000000000000000000000000000000000000000003ccfd60b00000000000000000000000000000000000000000000000000000000038a24bc000000000000000000000000000000000000000000000000000000001211540c00000000000000000000000000000000000000000000000000000000389a75e10000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000007448fbae00000000000000000000000000000000000000040000001c000000000000000002000000000000000000000000000000000000200000000c0000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d955391320200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000006f5e8818ffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32efa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c929cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f390200000200000000000000000000000000000024000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d00dbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d0000000000000000000000000000000000000000000000000000000082b42900e38026aa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000932bdb4700000000000000000000000000000000000000000000000000000000020000020000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000240000008000000000000000008000000000000000000000000000000000000000000000000000000000000000095ea7b3000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf4e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000b12d13eb038a24bc000000000000000000000000000000000000000000000000000000007bf6a16f000000000000000000000000000000000000000000000000000000003ded360c00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00200000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080d48bff695bc9b903dca1a7a3e7682aef3f48ab711ae55354680e95de67d93b
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000be7cfa9c97342ca6c689b9fe3f3001c90f2895fd
-----Decoded View---------------
Arg [0] : _owner (address): 0xbe7cFA9C97342CA6c689b9fe3F3001c90f2895fd
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000be7cfa9c97342ca6c689b9fe3f3001c90f2895fd
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.