Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 25 from a total of 3,455,270 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Claim Free | 30654371 | 41 days ago | IN | 0 ETH | 0.00000381 | ||||
| Claim Free | 30654361 | 41 days ago | IN | 0 ETH | 0.00000527 | ||||
| Withdraw Erc20 | 30281517 | 44 days ago | IN | 0 ETH | 0.00000471 | ||||
| Withdraw Erc20 | 30281506 | 44 days ago | IN | 0 ETH | 0.00000472 | ||||
| Withdraw | 30281488 | 44 days ago | IN | 0 ETH | 0.00000526 | ||||
| Mint Paid | 30162806 | 44 days ago | IN | 0.002 ETH | 0.0000081 | ||||
| Mint Paid | 30162557 | 44 days ago | IN | 0.002 ETH | 0.0000081 | ||||
| Mint Paid | 30100663 | 44 days ago | IN | 0.002 ETH | 0.00000522 | ||||
| Mint Paid | 30100637 | 44 days ago | IN | 0.002 ETH | 0.00000835 | ||||
| Mint Paid | 29809512 | 46 days ago | IN | 0 ETH | 0.00000559 | ||||
| Mint Paid | 29809477 | 46 days ago | IN | 0 ETH | 0.00000568 | ||||
| Mint Paid | 29809354 | 46 days ago | IN | 0 ETH | 0.0000089 | ||||
| Mint Paid | 29732695 | 46 days ago | IN | 0.002 ETH | 0.00000523 | ||||
| Mint Paid | 29732648 | 46 days ago | IN | 0.002 ETH | 0.00000523 | ||||
| Mint Paid | 29732566 | 46 days ago | IN | 0.002 ETH | 0.00000547 | ||||
| Mint Paid | 29732524 | 46 days ago | IN | 0.002 ETH | 0.00000757 | ||||
| Mint Paid | 29718243 | 46 days ago | IN | 0.002 ETH | 0.00000807 | ||||
| Mint Paid | 29713711 | 46 days ago | IN | 0.002 ETH | 0.00000854 | ||||
| Mint Paid | 29704640 | 46 days ago | IN | 0.002 ETH | 0.00000527 | ||||
| Mint Paid | 29704581 | 46 days ago | IN | 0.002 ETH | 0.00000693 | ||||
| Mint Paid | 29702778 | 46 days ago | IN | 0.002 ETH | 0.00000846 | ||||
| Mint Paid | 29680449 | 46 days ago | IN | 0.002 ETH | 0.00000523 | ||||
| Mint Paid | 29680400 | 46 days ago | IN | 0.002 ETH | 0.00000811 | ||||
| Mint Paid | 29674031 | 46 days ago | IN | 0.002 ETH | 0.00000811 | ||||
| Mint Paid | 29665649 | 46 days ago | IN | 0.002 ETH | 0.00000785 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 30281488 | 44 days ago | 1.05 ETH | ||||
| 30162806 | 44 days ago | 0.002 ETH | ||||
| 30162557 | 44 days ago | 0.002 ETH | ||||
| 30100663 | 44 days ago | 0.002 ETH | ||||
| 30100637 | 44 days ago | 0.002 ETH | ||||
| 29732695 | 46 days ago | 0.002 ETH | ||||
| 29732648 | 46 days ago | 0.002 ETH | ||||
| 29732566 | 46 days ago | 0.002 ETH | ||||
| 29732524 | 46 days ago | 0.002 ETH | ||||
| 29718243 | 46 days ago | 0.002 ETH | ||||
| 29713711 | 46 days ago | 0.002 ETH | ||||
| 29704640 | 46 days ago | 0.002 ETH | ||||
| 29704581 | 46 days ago | 0.002 ETH | ||||
| 29702778 | 46 days ago | 0.002 ETH | ||||
| 29680449 | 46 days ago | 0.002 ETH | ||||
| 29680400 | 46 days ago | 0.002 ETH | ||||
| 29674031 | 46 days ago | 0.002 ETH | ||||
| 29665649 | 46 days ago | 0.002 ETH | ||||
| 29626919 | 47 days ago | 0.002 ETH | ||||
| 29626891 | 47 days ago | 0.002 ETH | ||||
| 29626849 | 47 days ago | 0.002 ETH | ||||
| 29626098 | 47 days ago | 0.002 ETH | ||||
| 29625272 | 47 days ago | 0.002 ETH | ||||
| 29604527 | 47 days ago | 0.002 ETH | ||||
| 29604497 | 47 days ago | 0.002 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:
StandardCardMint
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.28;
import {IERC721Mintable} from "./interfaces/IERC721Mintable.sol";
import {Ownable} from "solady-0.1.12/src/auth/Ownable.sol";
import {LibBitmap} from "solady-0.1.12/src/utils/LibBitmap.sol";
import {ClaimWindow} from "./Structs.sol";
import {SafeTransferLib} from "solady-0.1.12/src/utils/ext/zksync/SafeTransferLib.sol";
import {ReentrancyGuard} from "solady-0.1.12/src/utils/ReentrancyGuard.sol";
import {IERC20} from "./interfaces/IERC20.sol";
contract StandardCardMint is Ownable, ReentrancyGuard {
using LibBitmap for LibBitmap.Bitmap;
using SafeTransferLib for address;
error ClaimNotActive();
error AlreadyClaimed();
error InvalidAmount();
error InvalidTime();
error InvalidToken();
error IncorrectPayment();
event Claimed(address indexed account, uint256 indexed id);
event Purchased(address indexed account, uint256 indexed id);
address public constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public constant fundAddress = 0x37587A260FBaa3344e0B9Fdbeae2d165007eF914;
mapping(address => bool) public tokenMapping;
IERC721Mintable public immutable token;
mapping(uint256 => ClaimWindow) public claimWindows;
mapping(address => LibBitmap.Bitmap) private _claimedFree;
constructor(address _token, address _owner) {
token = IERC721Mintable(_token);
_initializeOwner(_owner);
tokenMapping[ETH_ADDRESS] = true;
}
function setClaimWindow(
uint256 id,
uint48 priceUSD,
uint80 priceETH,
uint32 freeStart,
uint32 freeEnd,
uint32 paidStart,
uint32 paidEnd
) public onlyOwner {
claimWindows[id] = ClaimWindow({
priceUSD: priceUSD,
priceETH: priceETH,
freeStart: freeStart,
freeEnd: freeEnd,
paidStart: paidStart,
paidEnd: paidEnd
});
}
function claimFree(uint96 id) public nonReentrant {
ClaimWindow memory window = claimWindows[id];
require(window.freeStart <= block.timestamp && window.freeEnd >= block.timestamp, ClaimNotActive());
require(_claimedFree[msg.sender].get(id) == false, AlreadyClaimed());
_claimedFree[msg.sender].set(id);
token.mint(msg.sender, id);
emit Claimed(msg.sender, id);
}
function mintPaid(address to, uint96 id, uint amount, address payToken) public payable nonReentrant {
uint256 quantity = amount;
ClaimWindow memory window = claimWindows[id];
require(tokenMapping[payToken], InvalidToken());
require(window.paidStart <= block.timestamp && window.paidEnd >= block.timestamp, ClaimNotActive());
uint256 unitPrice;
if (payToken == ETH_ADDRESS) {
require(window.priceETH > 0, InvalidAmount());
unitPrice = window.priceETH;
} else {
require(window.priceUSD > 0, InvalidAmount());
unitPrice = window.priceUSD;
}
uint256 totalPrice = unitPrice * quantity;
if (payToken == ETH_ADDRESS) {
require(msg.value == totalPrice, IncorrectPayment());
} else {
require(msg.value == 0, IncorrectPayment());
require(IERC20(payToken).balanceOf(msg.sender) >= totalPrice, InvalidAmount());
payToken.safeTransferFrom(msg.sender, address(this), totalPrice);
}
for(uint i; i < amount; i++){
token.mint(to, id);
emit Purchased(to, id);
}
}
function withdraw() public onlyOwner {
fundAddress.safeTransferAllETH();
}
function withdrawErc20(address tokenX) public onlyOwner {
tokenX.safeTransfer(fundAddress, IERC20(tokenX).balanceOf(address(this)));
}
function setTokens(address[] calldata tokens, bool bools) public onlyOwner{
for(uint i; i < tokens.length; i++){
tokenMapping[tokens[i]] = bools;
}
}
function hasClaimed(address account, uint256 id) public view returns (bool) {
return _claimedFree[account].get(id);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IERC721Mintable {
function mint(address to, uint96 tokenType) external returns (uint256);
function updateTokenType(uint256 tokenId, uint96 tokenType) external;
}// 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 {LibBit} from "./LibBit.sol";
/// @notice Library for storage of packed unsigned booleans.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol)
library LibBitmap {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The constant returned when a bitmap scan does not find a result.
uint256 internal constant NOT_FOUND = type(uint256).max;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STRUCTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev A bitmap in storage.
struct Bitmap {
mapping(uint256 => uint256) map;
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns the boolean value of the bit at `index` in `bitmap`.
function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) {
// It is better to set `isSet` to either 0 or 1, than zero vs non-zero.
// Both cost the same amount of gas, but the former allows the returned value
// to be reused without cleaning the upper bits.
uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1;
/// @solidity memory-safe-assembly
assembly {
isSet := b
}
}
/// @dev Updates the bit at `index` in `bitmap` to true.
function set(Bitmap storage bitmap, uint256 index) internal {
bitmap.map[index >> 8] |= (1 << (index & 0xff));
}
/// @dev Updates the bit at `index` in `bitmap` to false.
function unset(Bitmap storage bitmap, uint256 index) internal {
bitmap.map[index >> 8] &= ~(1 << (index & 0xff));
}
/// @dev Flips the bit at `index` in `bitmap`.
/// Returns the boolean result of the flipped bit.
function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x20, bitmap.slot)
mstore(0x00, shr(8, index))
let storageSlot := keccak256(0x00, 0x40)
let shift := and(index, 0xff)
let storageValue := xor(sload(storageSlot), shl(shift, 1))
// It makes sense to return the `newIsSet`,
// as it allow us to skip an additional warm `sload`,
// and it costs minimal gas (about 15),
// which may be optimized away if the returned value is unused.
newIsSet := and(1, shr(shift, storageValue))
sstore(storageSlot, storageValue)
}
}
/// @dev Updates the bit at `index` in `bitmap` to `shouldSet`.
function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal {
/// @solidity memory-safe-assembly
assembly {
mstore(0x20, bitmap.slot)
mstore(0x00, shr(8, index))
let storageSlot := keccak256(0x00, 0x40)
let storageValue := sload(storageSlot)
let shift := and(index, 0xff)
sstore(
storageSlot,
// Unsets the bit at `shift` via `and`, then sets its new value via `or`.
or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet))))
)
}
}
/// @dev Consecutively sets `amount` of bits starting from the bit at `start`.
function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
let max := not(0)
let shift := and(start, 0xff)
mstore(0x20, bitmap.slot)
mstore(0x00, shr(8, start))
if iszero(lt(add(shift, amount), 257)) {
let storageSlot := keccak256(0x00, 0x40)
sstore(storageSlot, or(sload(storageSlot), shl(shift, max)))
let bucket := add(mload(0x00), 1)
let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
amount := and(add(amount, shift), 0xff)
shift := 0
for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
mstore(0x00, bucket)
sstore(keccak256(0x00, 0x40), max)
}
mstore(0x00, bucket)
}
let storageSlot := keccak256(0x00, 0x40)
sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max))))
}
}
/// @dev Consecutively unsets `amount` of bits starting from the bit at `start`.
function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
/// @solidity memory-safe-assembly
assembly {
let shift := and(start, 0xff)
mstore(0x20, bitmap.slot)
mstore(0x00, shr(8, start))
if iszero(lt(add(shift, amount), 257)) {
let storageSlot := keccak256(0x00, 0x40)
sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0)))))
let bucket := add(mload(0x00), 1)
let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
amount := and(add(amount, shift), 0xff)
shift := 0
for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
mstore(0x00, bucket)
sstore(keccak256(0x00, 0x40), 0)
}
mstore(0x00, bucket)
}
let storageSlot := keccak256(0x00, 0x40)
sstore(
storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0)))))
)
}
}
/// @dev Returns number of set bits within a range by
/// scanning `amount` of bits starting from the bit at `start`.
function popCount(Bitmap storage bitmap, uint256 start, uint256 amount)
internal
view
returns (uint256 count)
{
unchecked {
uint256 bucket = start >> 8;
uint256 shift = start & 0xff;
if (!(amount + shift < 257)) {
count = LibBit.popCount(bitmap.map[bucket] >> shift);
uint256 bucketEnd = bucket + ((amount + shift) >> 8);
amount = (amount + shift) & 0xff;
shift = 0;
for (++bucket; bucket != bucketEnd; ++bucket) {
count += LibBit.popCount(bitmap.map[bucket]);
}
}
count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount));
}
}
/// @dev Returns the index of the most significant set bit in `[0..upTo]`.
/// If no set bit is found, returns `NOT_FOUND`.
function findLastSet(Bitmap storage bitmap, uint256 upTo)
internal
view
returns (uint256 setBitIndex)
{
setBitIndex = NOT_FOUND;
uint256 bucket = upTo >> 8;
uint256 bits;
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, bucket)
mstore(0x20, bitmap.slot)
let offset := and(0xff, not(upTo)) // `256 - (255 & upTo) - 1`.
bits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40))))
if iszero(or(bits, iszero(bucket))) {
for {} 1 {} {
bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`.
mstore(0x00, bucket)
bits := sload(keccak256(0x00, 0x40))
if or(bits, iszero(bucket)) { break }
}
}
}
if (bits != 0) {
setBitIndex = (bucket << 8) | LibBit.fls(bits);
/// @solidity memory-safe-assembly
assembly {
setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, upTo)))
}
}
}
/// @dev Returns the index of the least significant unset bit in `[begin..upTo]`.
/// If no unset bit is found, returns `NOT_FOUND`.
function findFirstUnset(Bitmap storage bitmap, uint256 begin, uint256 upTo)
internal
view
returns (uint256 unsetBitIndex)
{
unsetBitIndex = NOT_FOUND;
uint256 bucket = begin >> 8;
uint256 negBits;
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, bucket)
mstore(0x20, bitmap.slot)
let offset := and(0xff, begin)
negBits := shl(offset, shr(offset, not(sload(keccak256(0x00, 0x40)))))
if iszero(negBits) {
let lastBucket := shr(8, upTo)
for {} 1 {} {
bucket := add(bucket, 1)
mstore(0x00, bucket)
negBits := not(sload(keccak256(0x00, 0x40)))
if or(negBits, gt(bucket, lastBucket)) { break }
}
if gt(bucket, lastBucket) {
negBits := shl(and(0xff, not(upTo)), shr(and(0xff, not(upTo)), negBits))
}
}
}
if (negBits != 0) {
uint256 r = (bucket << 8) | LibBit.ffs(negBits);
/// @solidity memory-safe-assembly
assembly {
unsetBitIndex := or(r, sub(0, or(gt(r, upTo), lt(r, begin))))
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
struct MintRequest {
uint8 cardId;
uint192 tokenId;
bool fulfilled;
}
struct Card {
uint64 silverTokenId;
uint64 goldTokenId;
uint64 goldThreshold;
}
struct ClaimWindow {
uint48 priceUSD; //2.8M usdt
uint80 priceETH; //120w eth
uint32 freeStart;
uint32 freeEnd;
uint32 paidStart;
uint32 paidEnd;
}// 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.4;
/// @notice Reentrancy guard mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Unauthorized reentrant call.
error Reentrancy();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STORAGE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to: `uint72(bytes9(keccak256("_REENTRANCY_GUARD_SLOT")))`.
/// 9 bytes is large enough to avoid collisions with lower slots,
/// but not too large to result in excessive bytecode bloat.
uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* REENTRANCY GUARD */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Guards a function from reentrancy.
modifier nonReentrant() virtual {
/// @solidity memory-safe-assembly
assembly {
if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
mstore(0x00, 0xab143c06) // `Reentrancy()`.
revert(0x1c, 0x04)
}
sstore(_REENTRANCY_GUARD_SLOT, address())
}
_;
/// @solidity memory-safe-assembly
assembly {
sstore(_REENTRANCY_GUARD_SLOT, codesize())
}
}
/// @dev Guards a view function from read-only reentrancy.
modifier nonReadReentrant() virtual {
/// @solidity memory-safe-assembly
assembly {
if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
mstore(0x00, 0xab143c06) // `Reentrancy()`.
revert(0x1c, 0x04)
}
}
_;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface IERC20 {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/// @notice Library for bit twiddling and boolean operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol)
/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html)
library LibBit {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BIT TWIDDLING OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Find last set.
/// Returns the index of the most significant bit of `x`,
/// counting from the least significant bit position.
/// If `x` is zero, returns 256.
function fls(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// forgefmt: disable-next-item
r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020504060203020504030106050205030304010505030400000000))
}
}
/// @dev Count leading zeros.
/// Returns the number of zeros preceding the most significant one bit.
/// If `x` is zero, returns 256.
function clz(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// forgefmt: disable-next-item
r := add(xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff)), iszero(x))
}
}
/// @dev Find first set.
/// Returns the index of the least significant bit of `x`,
/// counting from the least significant bit position.
/// If `x` is zero, returns 256.
/// Equivalent to `ctz` (count trailing zeros), which gives
/// the number of zeros following the least significant one bit.
function ffs(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
// Isolate the least significant bit.
x := and(x, add(not(x), 1))
// For the upper 3 bits of the result, use a De Bruijn-like lookup.
// Credit to adhusson: https://blog.adhusson.com/cheap-find-first-set-evm/
// forgefmt: disable-next-item
r := shl(5, shr(252, shl(shl(2, shr(250, mul(x,
0xb6db6db6ddddddddd34d34d349249249210842108c6318c639ce739cffffffff))),
0x8040405543005266443200005020610674053026020000107506200176117077)))
// For the lower 5 bits of the result, use a De Bruijn lookup.
// forgefmt: disable-next-item
r := or(r, byte(and(div(0xd76453e0, shr(r, x)), 0x1f),
0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405))
}
}
/// @dev Returns the number of set bits in `x`.
function popCount(uint256 x) internal pure returns (uint256 c) {
/// @solidity memory-safe-assembly
assembly {
let max := not(0)
let isMax := eq(x, max)
x := sub(x, and(shr(1, x), div(max, 3)))
x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))
x := and(add(x, shr(4, x)), div(max, 17))
c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))
}
}
/// @dev Returns whether `x` is a power of 2.
function isPo2(uint256 x) internal pure returns (bool result) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `x && !(x & (x - 1))`.
result := iszero(add(and(x, sub(x, 1)), iszero(x)))
}
}
/// @dev Returns `x` reversed at the bit level.
function reverseBits(uint256 x) internal pure returns (uint256 r) {
uint256 m0 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;
uint256 m1 = m0 ^ (m0 << 2);
uint256 m2 = m1 ^ (m1 << 1);
r = reverseBytes(x);
r = (m2 & (r >> 1)) | ((m2 & r) << 1);
r = (m1 & (r >> 2)) | ((m1 & r) << 2);
r = (m0 & (r >> 4)) | ((m0 & r) << 4);
}
/// @dev Returns `x` reversed at the byte level.
function reverseBytes(uint256 x) internal pure returns (uint256 r) {
unchecked {
// Computing masks on-the-fly reduces bytecode size by about 200 bytes.
uint256 m0 = 0x100000000000000000000000000000001 * (~toUint(x == uint256(0)) >> 192);
uint256 m1 = m0 ^ (m0 << 32);
uint256 m2 = m1 ^ (m1 << 16);
uint256 m3 = m2 ^ (m2 << 8);
r = (m3 & (x >> 8)) | ((m3 & x) << 8);
r = (m2 & (r >> 16)) | ((m2 & r) << 16);
r = (m1 & (r >> 32)) | ((m1 & r) << 32);
r = (m0 & (r >> 64)) | ((m0 & r) << 64);
r = (r >> 128) | (r << 128);
}
}
/// @dev Returns the common prefix of `x` and `y` at the bit level.
function commonBitPrefix(uint256 x, uint256 y) internal pure returns (uint256) {
unchecked {
uint256 s = 256 - clz(x ^ y);
return (x >> s) << s;
}
}
/// @dev Returns the common prefix of `x` and `y` at the nibble level.
function commonNibblePrefix(uint256 x, uint256 y) internal pure returns (uint256) {
unchecked {
uint256 s = (64 - (clz(x ^ y) >> 2)) << 2;
return (x >> s) << s;
}
}
/// @dev Returns the common prefix of `x` and `y` at the byte level.
function commonBytePrefix(uint256 x, uint256 y) internal pure returns (uint256) {
unchecked {
uint256 s = (32 - (clz(x ^ y) >> 3)) << 3;
return (x >> s) << s;
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BOOLEAN OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
// A Solidity bool on the stack or memory is represented as a 256-bit word.
// Non-zero values are true, zero is false.
// A clean bool is either 0 (false) or 1 (true) under the hood.
// Usually, if not always, the bool result of a regular Solidity expression,
// or the argument of a public/external function will be a clean bool.
// You can usually use the raw variants for more performance.
// If uncertain, test (best with exact compiler settings).
// Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s).
/// @dev Returns `x & y`. Inputs must be clean.
function rawAnd(bool x, bool y) internal pure returns (bool z) {
/// @solidity memory-safe-assembly
assembly {
z := and(x, y)
}
}
/// @dev Returns `x & y`.
function and(bool x, bool y) internal pure returns (bool z) {
/// @solidity memory-safe-assembly
assembly {
z := and(iszero(iszero(x)), iszero(iszero(y)))
}
}
/// @dev Returns `x | y`. Inputs must be clean.
function rawOr(bool x, bool y) internal pure returns (bool z) {
/// @solidity memory-safe-assembly
assembly {
z := or(x, y)
}
}
/// @dev Returns `x | y`.
function or(bool x, bool y) internal pure returns (bool z) {
/// @solidity memory-safe-assembly
assembly {
z := or(iszero(iszero(x)), iszero(iszero(y)))
}
}
/// @dev Returns 1 if `b` is true, else 0. Input must be clean.
function rawToUint(bool b) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := b
}
}
/// @dev Returns 1 if `b` is true, else 0.
function toUint(bool b) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := iszero(iszero(b))
}
}
}// 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": true,
"codegen": "yul",
"remappings": [
"@zksync-contracts-0.0.1/=dependencies/era-contracts/lib/@matterlabs/zksync-contracts/l2/",
"forge-std-1.9.6/=lib/forge-std/",
"solady-0.1.12/=dependencies/solady/",
"@matterlabs/=dependencies/era-contracts/lib/@matterlabs/",
"ds-test/=dependencies/era-contracts/lib/openzeppelin-contracts-upgradeable-v4/lib/forge-std/lib/ds-test/src/",
"era-contracts/=dependencies/era-contracts/",
"erc4626-tests/=dependencies/era-contracts/lib/openzeppelin-contracts-upgradeable-v4/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"murky/=dependencies/era-contracts/lib/murky/",
"openzeppelin-contracts-upgradeable-v4/=dependencies/era-contracts/lib/openzeppelin-contracts-upgradeable-v4/",
"openzeppelin-contracts-v4/=dependencies/era-contracts/lib/openzeppelin-contracts-v4/",
"openzeppelin-contracts/=dependencies/era-contracts/lib/murky/lib/openzeppelin-contracts/",
"solady/=dependencies/solady/src/"
],
"evmVersion": "cancun",
"outputSelection": {
"*": {
"*": [
"abi"
]
}
},
"optimizer": {
"enabled": true,
"mode": "3",
"fallback_to_optimizing_for_size": 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":"_token","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ClaimNotActive","type":"error"},{"inputs":[],"name":"IncorrectPayment","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidTime","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Claimed","type":"event"},{"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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Purchased","type":"event"},{"inputs":[],"name":"ETH_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint96","name":"id","type":"uint96"}],"name":"claimFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimWindows","outputs":[{"internalType":"uint48","name":"priceUSD","type":"uint48"},{"internalType":"uint80","name":"priceETH","type":"uint80"},{"internalType":"uint32","name":"freeStart","type":"uint32"},{"internalType":"uint32","name":"freeEnd","type":"uint32"},{"internalType":"uint32","name":"paidStart","type":"uint32"},{"internalType":"uint32","name":"paidEnd","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fundAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"hasClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint96","name":"id","type":"uint96"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"payToken","type":"address"}],"name":"mintPaid","outputs":[],"stateMutability":"payable","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":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint48","name":"priceUSD","type":"uint48"},{"internalType":"uint80","name":"priceETH","type":"uint80"},{"internalType":"uint32","name":"freeStart","type":"uint32"},{"internalType":"uint32","name":"freeEnd","type":"uint32"},{"internalType":"uint32","name":"paidStart","type":"uint32"},{"internalType":"uint32","name":"paidEnd","type":"uint32"}],"name":"setClaimWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"bool","name":"bools","type":"bool"}],"name":"setTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC721Mintable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenMapping","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenX","type":"address"}],"name":"withdrawErc20","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010001fbc84c0edd64778ed9fd274fd7f9a58444edfe4cfbb0f94b89b0e1a8af00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a22f3f9154b0f0e6b3266661e86645d00633ec2d00000000000000000000000067d38e2756f1d7f9d23e5822165caf38ed580f8e
Deployed Bytecode
0x0001000000000002000c000000000002000000000001035500000060031002700000019e033001970000000100200190000000410000c13d0000008002000039000000400020043f000000040030008c000005180000413d000000000201043b000000e002200270000001a80020009c000000870000a13d000001a90020009c000000980000213d000001b00020009c000000e00000a13d000001b10020009c000001cf0000613d000001b20020009c0000023f0000613d000001b30020009c000005180000c13d000000240030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000401100370000000000101043b000800000001001d000001cc0010009c000005180000213d000001cd01000041000000000301041a0000000002000410000000000023004b000001ad0000613d0000000803000029000001cc03300197000000000021041b000700000003001d000000000030043f0000000101000039000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000400200043d000001cf0020009c0000038c0000a13d000001f001000041000000000010043f0000004101000039000000040010043f000001ec0100004100000676000104300000000002000416000000000002004b000005180000c13d0000001f023000390000019f02200197000000a002200039000000400020043f0000001f0430018f000001a005300198000000a002500039000000520000613d000000a006000039000000000701034f000000007807043c0000000006860436000000000026004b0000004e0000c13d000000000004004b0000005f0000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000400030008c000005180000413d000000a00100043d000001a10010009c000005180000213d000000c00600043d000001a10060009c000005180000213d000000800010043f000001a201000041000000000061041b00000000010004140000019e0010009c0000019e01008041000000c001100210000001a3011001c70000800d020000390000000303000039000001a40400004100000000050000190674066a0000040f0000000100200190000005180000613d000001a501000041000000000010043f000000200000043f000001a601000041000000000201041a000001f70220019700000001022001bf000000000021041b000000800100043d000001400000044300000160001004430000002001000039000001000010044300000001010000390000012000100443000001a701000041000006750001042e000001b60020009c000000b30000a13d000001b70020009c000000f90000a13d000001b80020009c000002a40000613d000001b90020009c000002aa0000613d000001ba0020009c000005180000c13d0000000001000416000000000001004b000005180000c13d000001a501000041000000800010043f000001c301000041000006750001042e000001aa0020009c000001410000a13d000001ab0020009c000002ca0000613d000001ac0020009c000002db0000613d000001ad0020009c000005180000c13d000000240030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000401100370000000000101043b000001a10010009c000005180000213d000001c2020000410000000c0020043f000000000010043f0000000c010000390000002002000039067406370000040f000000000101041a000000800010043f000001c301000041000006750001042e000001bd0020009c000001740000213d000001c00020009c000001950000613d000001c10020009c000005180000c13d000001c2010000410000000c0010043f0000000001000411000000000010043f000001c801000041000000000010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001c9011001c70000800b020000390674066f0000040f0000000100200190000005e30000613d000000000101043b000800000001001d00000000010004140000019e0010009c0000019e01008041000000c001100210000001c7011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b0000000802000029000001ea0220009a000000000021041b00000000010004140000019e0010009c0000019e01008041000000c001100210000001a3011001c70000800d020000390000000203000039000001eb040000410000018f0000013d000001b40020009c000002ec0000613d000001b50020009c000005180000c13d000000240030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000401100370000000000101043b000001a10010009c000005180000213d000000000010043f000000200000043f00000040020000390000000001000019067406370000040f000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f000001c301000041000006750001042e000001bb0020009c0000030a0000613d000001bc0020009c000005180000c13d000000440030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000402100370000000000202043b000001d70020009c000005180000213d0000002304200039000000000034004b000005180000813d0000000404200039000000000441034f000000000404043b000700000004001d000001d70040009c000005180000213d000600240020003d000000070200002900000005022002100000000602200029000000000032004b000005180000213d0000002401100370000000000201043b000000000002004b0000000001000039000000010100c039000500000002001d000000000012004b000005180000c13d000001a201000041000000000101041a0000000002000411000000000012004b0000031f0000c13d000000070000006b000001930000613d0000000004000019000000050140021000000006011000290000000001100367000000000101043b000001a10010009c000005180000213d000000000010043f000000200000043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c70000801002000039000800000004001d0674066f0000040f00000008040000290000000100200190000005180000613d000000000101043b000000000201041a000001f70220019700000005022001af000000000021041b0000000104400039000000070040006c000001250000413d000001930000013d000001ae0020009c000003230000613d000001af0020009c000005180000c13d000000240030008c000005180000413d0000000401100370000000000101043b000800000001001d000001a10010009c000005180000213d000001a201000041000000000101041a0000000002000411000000000012004b0000031f0000c13d000001c2010000410000000c0010043f0000000801000029000000000010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001c7011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b000600000001001d000000000101041a000700000001001d000001c801000041000000000010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001c9011001c70000800b020000390674066f0000040f0000000100200190000005e30000613d000000000101043b000000070010006c0000045d0000a13d000001ca01000041000000000010043f000001c6010000410000067600010430000001be0020009c000001b10000613d000001bf0020009c000005180000c13d000001c2010000410000000c0010043f0000000001000411000000000010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001c7011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b000000000001041b00000000010004140000019e0010009c0000019e01008041000000c001100210000001a3011001c70000800d020000390000000203000039000001e60400004100000000050004110674066a0000040f0000000100200190000005180000613d0000000001000019000006750001042e000000840030008c000005180000413d0000000402100370000000000202043b000800000002001d000001a10020009c000005180000213d0000002402100370000000000202043b000001cc0020009c000005180000213d0000004403100370000000000303043b000400000003001d0000006401100370000000000101043b000600000001001d000001a10010009c000005180000213d000001cd01000041000000000301041a0000000004000410000000000043004b000003530000c13d000001f601000041000000000010043f000001c60100004100000676000104300000000001000416000000000001004b000005180000c13d000001a201000041000000000101041a0000000002000411000000000012004b0000031f0000c13d000001e80100004100000000001004430000000001000410000000040010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001e2011001c70000800a020000390674066f0000040f0000000100200190000005e30000613d000000000301043b00000000010004140000019e0010009c0000019e01008041000000c001100210000000000003004b0000032a0000c13d000001cb020000410000032e0000013d000000240030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000401100370000000000101043b000800000001001d000001a10010009c000005180000213d000001a201000041000000000101041a0000000002000411000000000012004b0000031f0000c13d000001de01000041000000800010043f0000000001000410000000840010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001df011001c700000008020000290674066f0000040f000000800a00003900000060031002700000019e03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf000001f80000613d000000000801034f000000008908043c000000000a9a043600000000005a004b000001f40000c13d000000000006004b000002050000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000003350000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c000005180000413d000000800100043d000001cb02000041000000140020043f000000340010043f000001e001000041000000000010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001e1011001c700000008020000290674066a0000040f00000060031002700000019e07300197000000200070008c000000200400003900000000040740190000001f0340018f0000002008400190000002280000613d000000000401034f0000000005000019000000004604043c0000000005650436000000000085004b000002240000c13d000000000003004b000002350000613d000000000181034f0000000303300210000000000408043300000000043401cf000000000434022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000141019f0000000000180435000000000100043d000000010010008c00000000010000390000000101006039000000000112016f0000000100100190000004630000613d000000340000043f0000000001000019000006750001042e000000e40030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000002402100370000000000202043b000800000002001d000001d10020009c000005180000213d0000004402100370000000000202043b000700000002001d000001d00020009c000005180000213d0000006402100370000000000202043b000600000002001d0000019e0020009c000005180000213d0000008402100370000000000202043b000500000002001d0000019e0020009c000005180000213d000000a402100370000000000202043b000400000002001d0000019e0020009c000005180000213d000000c401100370000000000101043b000300000001001d0000019e0010009c000005180000213d067405ff0000040f000000400100043d000200000001001d067405f40000040f0000000203000029000000a001300039000100000001001d000000030200002900000000002104350000008001300039000300000001001d000000040200002900000000002104350000006002300039000400000002001d000000050100002900000000001204350000004002300039000500000002001d000000060100002900000000001204350000002002300039000600000002001d000000070100002900000000001204350000000801000029000000000013043500000004010000390000000001100367000000000101043b000000000010043f0000000101000039000000200010043f00000040020000390000000001000019067406370000040f00000002020000290000000002020433000001d102200197000000060300002900000000030304330000003003300210000001da03300197000000000223019f000000050300002900000000030304330000008003300210000001db03300197000000000232019f00000004030000290000000003030433000000a003300210000001dc03300197000000000232019f00000003030000290000000003030433000000c003300210000001dd03300197000000000232019f00000001030000290000000003030433000000e003300210000000000232019f000000000021041b0000000001000019000006750001042e0000000001000416000000000001004b000005180000c13d000001a201000041000000000101041a000002e80000013d000000240030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000401100370000000000101043b000000000010043f0000000101000039000000200010043f00000040020000390000000001000019067406370000040f000000000101041a000001d102100197000000800020043f0000003002100270000001d002200197000000a00020043f00000080021002700000019e02200197000000c00020043f000000a0021002700000019e02200197000000e00020043f000000c0021002700000019e02200197000001000020043f000000e001100270000001200010043f000001e501000041000006750001042e000000240030008c000005180000413d0000000401100370000000000101043b000001a10010009c000005180000213d000001a202000041000000000202041a0000000003000411000000000023004b0000031f0000c13d000000000001004b000004600000c13d000001c501000041000000000010043f000001c60100004100000676000104300000000001000416000000000001004b000005180000c13d0000000001000412000a00000001001d000900000000003d0000800501000039000000440300003900000000040004150000000a0440008a0000000504400210000001c4020000410674064c0000040f000001a101100197000000800010043f000001c301000041000006750001042e000000440030008c000005180000413d0000000002000416000000000002004b000005180000c13d0000000402100370000000000202043b000001a10020009c000005180000213d000000000020043f0000000202000039000000200020043f0000002401100370000000000101043b000800000001001d00000040020000390000000001000019067406370000040f00000008020000290674061f0000040f000000000001004b0000000001000039000000010100c039000000400200043d00000000001204350000019e0020009c0000019e020080410000004001200210000001e4011001c7000006750001042e000001a201000041000000000501041a0000000001000411000000000051004b0000031f0000c13d00000000010004140000019e0010009c0000019e01008041000000c001100210000001a3011001c70000800d020000390000000303000039000001a40400004100000000060000190674066a0000040f0000000100200190000005180000613d000001a201000041000000000001041b0000000001000019000006750001042e000001e701000041000000000010043f000001c60100004100000676000104300000000001000416000000000001004b000005180000c13d000001cb01000041000000800010043f000001c301000041000006750001042e000001a3011001c70000800902000039000001cb0400004100000000050000190674066a0000040f0000000100200190000001930000c13d000001e901000041000000000010043f000001c60100004100000676000104300000001f0530018f000001a006300198000000400200043d0000000004620019000003400000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000033c0000c13d000000000005004b0000034d0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500000060013002100000019e0020009c0000019e020080410000004002200210000000000112019f0000067600010430000001cc02200197000000000041041b000700000002001d000000000020043f0000000101000039000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d0000000602000029000001a103200197000000000101043b0000014002000039000000400020043f000000000101041a000001d102100197000000800020043f0000003002100270000001d002200197000000a00020043f00000080021002700000019e02200197000000c00020043f000000a0021002700000019e02200197000000e00020043f000000c0021002700000019e02200197000001000020043f000000e001100270000001200010043f000500000003001d000000000030043f000000200000043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b000000000101041a000000ff00100190000004800000c13d000001f501000041000000000010043f000001d3010000410000067600010430000000000101043b000000c003200039000000400030043f000000000101041a000000a003200039000000e0041002700000000000430435000000c0031002700000019e03300197000000800420003900000000003404350000003003100270000001d00330019700000020042000390000000000340435000001d1031001970000000000320435000000a0031002700000019e043001970000006003200039000500000004001d0000000000430435000000400220003900000080011002700000019e01100197000600000001001d0000000000120435000001c801000041000000000010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001c9011001c70000800b020000390674066f0000040f0000000100200190000005e30000613d000000000101043b000000060010006b000004960000213d000000050010006b000004960000413d0000000001000411000000000010043f0000000201000039000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b00000007020000290000000802200270000000000020043f000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d0000000802000029000000ff0220018f0006000100200217000000000101043b000000000101041a00000006001001800000049a0000c13d0000000001000411000000000010043f0000000201000039000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b00000008020000290000000802200270000000000020043f000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000005180000613d000000000101043b000000000201041a00000006022001af000000000021041b000000400300043d000000240130003900000007020000290000000000210435000001d40100004100000000001304350000000001000411000001a101100197000800000003001d00000004023000390000000000120435000001c401000041000000000010044300000000010004120000000400100443000000240000044300000000010004140000019e0010009c0000019e01008041000000c001100210000001d5011001c700008005020000390674066f0000040f0000000100200190000005e30000613d000000000201043b00000008010000290000019e0010009c0000019e01008041000000400110021000000000030004140000019e0030009c0000019e03008041000000c003300210000000000113019f000001d6011001c7000001a1022001970674066a0000040f00000060031002700000019e03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000008057000290000042d0000613d000000000801034f0000000809000029000000008a08043c0000000009a90436000000000059004b000004290000c13d000000000006004b0000043a0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000005240000613d0000001f01400039000000600210018f0000000801200029000000000021004b00000000020000390000000102004039000001d70010009c0000003b0000213d00000001002001900000003b0000c13d000000400010043f000000200030008c000005180000413d00000000010004140000019e0010009c0000019e01008041000000c001100210000001a3011001c70000800d020000390000000303000039000001d804000041000000000500041100000007060000290674066a0000040f0000000100200190000005180000613d0000000001000412000b00000001001d0000800201000039000000240300003900000000040004150000000b0440008a000004c20000013d0000000601000029000000000001041b0000000801000029067406090000040f0000000001000019000006750001042e000600000002001d000700000007001d000001d90100004100000000001004430000000801000029000000040010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001e2011001c700008002020000390674066f0000040f0000000100200190000005e30000613d000000010200008a000000060220014f000000000101043b000000000001004b0000000001000039000000010100603900000007001001b0000000010220c1bf00000001002001900000023c0000613d000001e301000041000000000010043f000001c6010000410000067600010430000001000100043d000300000001001d000001c801000041000000000010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001c9011001c70000800b020000390674066f0000040f0000000100200190000005e30000613d000000000101043b00000003020000290000019e02200197000000000012004b000004960000213d000001200200043d0000019e02200197000000000012004b0000049e0000813d000001f401000041000000000010043f000001d3010000410000067600010430000001d201000041000000000010043f000001d30100004100000676000104300000000501000029000001a50010009c000004c90000c13d000000a00100043d000001d002100198000004cc0000613d00000004012000b900000000022100d9000000040020006b0000051a0000c13d0000000002000416000000000012004b000005200000c13d000001c401000041000000000010044300000000010004120000000400100443000000240000044300000000010004140000019e0010009c0000019e01008041000000c001100210000001d5011001c700008005020000390674066f0000040f0000000100200190000005e30000613d000000000101043b000000040000006b0000053c0000c13d0000000001000412000c00000001001d0000800201000039000000240300003900000000040004150000000c0440008a0000000504400210000001d9020000410674064c0000040f000001cd02000041000000000012041b0000000001000019000006750001042e000000800100043d000001d101100198000004d00000c13d000001f301000041000000000010043f000001d301000041000006760001043000030004001000bd00000003011000f9000000040010006b0000051a0000c13d0000000001000416000000000001004b000005200000c13d000000400300043d000200000003001d000001de0100004100000000001304350000000401300039000000000200041100000000002104350000019e0030009c0000019e010000410000000001034019000000400110021000000000020004140000019e0020009c0000019e02008041000000c002200210000000000112019f000001ec011001c700000005020000290674066f0000040f00000060031002700000019e03300197000000200030008c000000200400003900000000040340190000001f0640018f0000002007400190000000020b0000290000000205700029000004fa0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000004f60000c13d000000000006004b000005070000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000005300000613d0000001f01400039000000600110018f0000000002b10019000000000012004b00000000010000390000000101004039000500000002001d000001d70020009c0000003b0000213d00000001001001900000003b0000c13d0000000501000029000000400010043f000000200030008c000005920000813d00000000010000190000067600010430000001f001000041000000000010043f0000001101000039000000040010043f000001ec010000410000067600010430000001f101000041000000000010043f000001d30100004100000676000104300000001f0530018f000001a006300198000000400200043d0000000004620019000003400000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000052b0000c13d000003400000013d0000001f0530018f000001a006300198000000400200043d0000000004620019000003400000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000005370000c13d000003400000013d000301a10010019b000500000000001d000000400300043d000600000003001d000000240130003900000007020000290000000000210435000001d40100004100000000001304350000000401300039000000080200002900000000002104350000019e0030009c0000019e010000410000000001034019000000400110021000000000020004140000019e0020009c0000019e02008041000000c002200210000000000112019f000001d6011001c700000003020000290674066a0000040f000000060a00002900000060031002700000019e03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000005630000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b0000055f0000c13d0000001f07400190000005700000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f00000000006504350000000100200190000005e40000613d0000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000001d70010009c0000003b0000213d00000001002001900000003b0000c13d000000400010043f000000200030008c000005180000413d00000000010004140000019e0010009c0000019e01008041000000c001100210000001a3011001c70000800d020000390000000303000039000001f204000041000000080500002900000007060000290674066a0000040f0000000100200190000005180000613d00000005020000290000000102200039000500000002001d000000040020006c0000053e0000413d000004bc0000013d00000000010b0433000000030010006c000004cc0000413d0000000301000029000000600010043f0000000001000410000000400010043f000000000100041100000060011002100000002c0010043f000001ed010000410000000c0010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ee011001c700000006020000290674066a0000040f000300000002001d00000060021002700000019e02200197000000200020008c000200000002001d00000020020080390000001f0320018f0000002002200190000005b40000613d000000000401034f0000000005000019000000004604043c0000000005650436000000000025004b000005b00000c13d000000000003004b000005c10000613d000000000121034f0000000303300210000000000402043300000000043401cf000000000434022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000141019f0000000000120435000000000100043d000000010010008c00000000010000390000000101006039000000030110017f0000000100100190000005df0000c13d000001d90100004100000000001004430000000601000029000000040010044300000000010004140000019e0010009c0000019e01008041000000c001100210000001e2011001c700008002020000390674066f0000040f0000000100200190000005e30000613d000000010200008a000000030220014f000000000101043b000000000001004b0000000001000039000000010100603900000002001001b0000000010220c1bf0000000100200190000005f00000c13d000000600000043f0000000501000029000000400010043f000004ab0000013d000000000001042f0000001f0530018f000001a006300198000000400200043d0000000004620019000003400000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000005eb0000c13d000003400000013d000001ef01000041000000000010043f000001c6010000410000067600010430000001f80010009c000005f90000813d000000c001100039000000400010043f000000000001042d000001f001000041000000000010043f0000004101000039000000040010043f000001ec010000410000067600010430000001a201000041000000000101041a0000000002000411000000000012004b000006050000c13d000000000001042d000001e701000041000000000010043f000001c60100004100000676000104300001000000000002000001a202000041000000000502041a0000000002000414000001a1061001970000019e0020009c0000019e02008041000000c001200210000001a3011001c70000800d020000390000000303000039000001a404000041000100000006001d0674066a0000040f00000001002001900000061d0000613d000001a2010000410000000102000029000000000021041b000000000001042d000000000100001900000676000104300001000000000002000100000002001d0000000802200270000000000020043f000000200010043f00000000010004140000019e0010009c0000019e01008041000000c001100210000001ce011001c700008010020000390674066f0000040f0000000100200190000006340000613d0000000102000029000000ff0220018f000000000101043b000000000101041a000000000121022f000000010110018f000000000001042d00000000010000190000067600010430000000000001042f0000019e0010009c0000019e0100804100000040011002100000019e0020009c0000019e020080410000006002200210000000000112019f00000000020004140000019e0020009c0000019e02008041000000c002200210000000000112019f000001a3011001c700008010020000390674066f0000040f00000001002001900000064a0000613d000000000101043b000000000001042d0000000001000019000006760001043000000000050100190000000000200443000000050030008c0000065a0000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b000006520000413d0000019e0030009c0000019e03008041000000600130021000000000020004140000019e0020009c0000019e02008041000000c002200210000000000112019f000001f9011001c700000000020500190674066f0000040f0000000100200190000006690000613d000000000101043b000000000001042d000000000001042f0000066d002104210000000102000039000000000001042d0000000002000019000000000001042d00000672002104230000000102000039000000000001042d0000000002000019000000000001042d0000067400000432000006750001042e0000067600010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7487392702000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed0d045a07f9a74a2c48a464add9b06f25f501dbdf5bd4dd5a7489f86f449adda000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000b293109500000000000000000000000000000000000000000000000000000000e82bef2800000000000000000000000000000000000000000000000000000000f2fde38a00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000fc0c546a00000000000000000000000000000000000000000000000000000000fee81cf400000000000000000000000000000000000000000000000000000000e82bef2900000000000000000000000000000000000000000000000000000000f04e283e00000000000000000000000000000000000000000000000000000000c7e42b1a00000000000000000000000000000000000000000000000000000000c7e42b1b00000000000000000000000000000000000000000000000000000000c8fd804f00000000000000000000000000000000000000000000000000000000db5398de00000000000000000000000000000000000000000000000000000000b293109600000000000000000000000000000000000000000000000000000000ba27f50b00000000000000000000000000000000000000000000000000000000715018a5000000000000000000000000000000000000000000000000000000008da5cb5a000000000000000000000000000000000000000000000000000000008da5cb5b000000000000000000000000000000000000000000000000000000009063670900000000000000000000000000000000000000000000000000000000a734f06e00000000000000000000000000000000000000000000000000000000715018a600000000000000000000000000000000000000000000000000000000719bce20000000000000000000000000000000000000000000000000000000003ccfd60a000000000000000000000000000000000000000000000000000000003ccfd60b0000000000000000000000000000000000000000000000000000000054d1f13d000000000000000000000000000000000000000000000000000000001a08d4eb000000000000000000000000000000000000000000000000000000002569296200000000000000000000000000000000000000000000000000000000389a75e10000000000000000000000000000000000000020000000800000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e000000000000000000000000000000000000000000000000000000007448fbae00000000000000000000000000000000000000040000001c000000000000000002000000000000000000000000000000000000200000000c0000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d955391320200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000006f5e881800000000000000000000000037587a260fbaa3344e0b9fdbeae2d165007ef9140000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000929eee149b4bd212680200000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff3f00000000000000000000000000000000000000000000ffffffffffffffffffff0000000000000000000000000000000000000000000000000000ffffffffffff646cf5580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000001b025a400000000000000000000000000000000000000000000000000000000002000002000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b8300000000000000000000000000000000ffffffffffffffffffff000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000070a0823100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000080000000000000000000000000000000000000000000000000a9059cbb000000000000000000000000000000000000000000000000000000000000004400000010000000000000000002000002000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000000000000000000000090b8ec18000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000800000000000000000fa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c920000000000000000000000000000000000000000000000000000000082b429009cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f3900000000000000000000000000000000000000000000000000000000b12d13ebfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d00dbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d00000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000000000640000001c0000000000000000000000000000000000000000000000000000000000000000000000007939f4244e487b7100000000000000000000000000000000000000000000000000000000569e8c1100000000000000000000000000000000000000000000000000000000a512fb2532ca8587f236380171326ebb69670e86a2ba0c4412a3fcca4c3ada9b2c5211c60000000000000000000000000000000000000000000000000000000024fbaa9000000000000000000000000000000000000000000000000000000000c1ab6dc10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab143c06ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000ffffffffffffff400200000200000000000000000000000000000000000000000000000000000000e8d4b817ee73bee5f08869ee1b9a46322b88137aafbe3fbd207ecfe8ee3382a2
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a22f3f9154b0f0e6b3266661e86645d00633ec2d00000000000000000000000067d38e2756f1d7f9d23e5822165caf38ed580f8e
-----Decoded View---------------
Arg [0] : _token (address): 0xA22F3F9154b0f0e6b3266661E86645D00633EC2d
Arg [1] : _owner (address): 0x67d38e2756f1d7F9D23e5822165caF38eD580f8e
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a22f3f9154b0f0e6b3266661e86645d00633ec2d
Arg [1] : 00000000000000000000000067d38e2756f1d7f9d23e5822165caf38ed580f8e
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$29.33
Net Worth in ETH
0.010011
Token Allocations
ETH
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $2,930.6 | 0.01 | $29.33 |
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.