Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 2,090 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mint | 23531575 | 3 mins ago | IN | 0.08804276 ETH | 0.00015063 | ||||
Mint | 23531271 | 1 hr ago | IN | 0.10758246 ETH | 0.00014747 | ||||
Mint | 23530802 | 2 hrs ago | IN | 0.03422543 ETH | 0.00001016 | ||||
Mint | 23529611 | 6 hrs ago | IN | 0.0593704 ETH | 0.00001761 | ||||
Mint | 23529133 | 8 hrs ago | IN | 0.15118968 ETH | 0.00014451 | ||||
Mint | 23529130 | 8 hrs ago | IN | 0.25165973 ETH | 0.00001035 | ||||
Mint | 23528968 | 8 hrs ago | IN | 0.56771704 ETH | 0.00007592 | ||||
Mint | 23528894 | 9 hrs ago | IN | 0.379005 ETH | 0.00010529 | ||||
Mint | 23528834 | 9 hrs ago | IN | 0.45454131 ETH | 0.00018512 | ||||
Mint | 23528806 | 9 hrs ago | IN | 0.18921709 ETH | 0.00013506 | ||||
Mint | 23528769 | 9 hrs ago | IN | 0.48189871 ETH | 0.00002208 | ||||
Mint | 23528751 | 9 hrs ago | IN | 5.28487992 ETH | 0.00018157 | ||||
Mint | 23528661 | 9 hrs ago | IN | 5.6239719 ETH | 0.0001927 | ||||
Mint | 23528645 | 9 hrs ago | IN | 3.72441879 ETH | 0.00073868 | ||||
Mint | 23528601 | 10 hrs ago | IN | 1.11204136 ETH | 0.00013551 | ||||
Mint | 23528582 | 10 hrs ago | IN | 0.29994518 ETH | 0.00016037 | ||||
Mint | 23528561 | 10 hrs ago | IN | 0.09069854 ETH | 0.0001614 | ||||
Mint | 23528510 | 10 hrs ago | IN | 0.04802167 ETH | 0.0000353 | ||||
Mint | 23528504 | 10 hrs ago | IN | 0.06796341 ETH | 0.00004226 | ||||
Mint | 23528500 | 10 hrs ago | IN | 6.10394153 ETH | 0.00005409 | ||||
Mint | 23528488 | 10 hrs ago | IN | 7.27995682 ETH | 0.00003564 | ||||
Mint | 23528478 | 10 hrs ago | IN | 7.19821154 ETH | 0.00004669 | ||||
Mint | 23528401 | 10 hrs ago | IN | 0.35737216 ETH | 0.00016048 | ||||
Mint | 23528374 | 10 hrs ago | IN | 7.10662206 ETH | 0.00073868 | ||||
Mint | 23528355 | 10 hrs ago | IN | 3.14264884 ETH | 0.00018956 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Transfer | 23531575 | 3 mins ago | 0.00043802 ETH | ||||
Mint | 23531575 | 3 mins ago | 0.08760474 ETH | ||||
Transfer | 23531271 | 1 hr ago | 0.00053523 ETH | ||||
Mint | 23531271 | 1 hr ago | 0.10704722 ETH | ||||
Transfer | 23531035 | 1 hr ago | 753.38321164 ETH | ||||
Mint | 23531035 | 1 hr ago | 46.61678835 ETH | ||||
Mint | 23531035 | 1 hr ago | 800 ETH | ||||
Transfer | 23530802 | 2 hrs ago | 0.0002589 ETH | ||||
Mint | 23530802 | 2 hrs ago | 0.03396653 ETH | ||||
Transfer | 23529611 | 6 hrs ago | 0.00029537 ETH | ||||
Mint | 23529611 | 6 hrs ago | 0.05907502 ETH | ||||
Transfer | 23529133 | 8 hrs ago | 0.00075218 ETH | ||||
Mint | 23529133 | 8 hrs ago | 0.15043749 ETH | ||||
Transfer | 23529130 | 8 hrs ago | 0.00125203 ETH | ||||
Mint | 23529130 | 8 hrs ago | 0.25040769 ETH | ||||
Transfer | 23528968 | 8 hrs ago | 0.00282446 ETH | ||||
Mint | 23528968 | 8 hrs ago | 0.56489257 ETH | ||||
Transfer | 23528894 | 9 hrs ago | 0.00188559 ETH | ||||
Mint | 23528894 | 9 hrs ago | 0.3771194 ETH | ||||
Transfer | 23528834 | 9 hrs ago | 0.00226139 ETH | ||||
Mint | 23528834 | 9 hrs ago | 0.45227991 ETH | ||||
Transfer | 23528806 | 9 hrs ago | 0.00088322 ETH | ||||
Mint | 23528806 | 9 hrs ago | 0.18833386 ETH | ||||
Transfer | 23528769 | 9 hrs ago | 0.0023975 ETH | ||||
Mint | 23528769 | 9 hrs ago | 0.4795012 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MintRouter
Compiler Version
v0.8.30+commit.73712a01
Optimization Enabled:
Yes with 1000 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.30; import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol"; import {IMintableToken} from "./interfaces/IMintableToken.sol"; contract MintRouter { IMintableToken public token; constructor(address _token) { token = IMintableToken(_token); } // @dev Mint tokens and refund the remaining ETH (so we can handle slippage) function mint(uint256 amount, address receiver) external payable { uint256 price = token.previewMint(amount); require(msg.value >= price, "Insufficient ETH"); token.mint{value: price}(amount, receiver); // Refund the remaining ETH SafeTransferLib.safeTransferETH(msg.sender, msg.value - price); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @author Permit2 operations from (https://github.com/Uniswap/permit2/blob/main/src/libraries/Permit2Lib.sol) /// /// @dev Note: /// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection. library SafeTransferLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* 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(); /// @dev The Permit2 operation has failed. error Permit2Failed(); /// @dev The Permit2 amount must be less than `2**160 - 1`. error Permit2AmountOverflow(); /// @dev The Permit2 approve operation has failed. error Permit2ApproveFailed(); /// @dev The Permit2 lockdown operation has failed. error Permit2LockdownFailed(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes. uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300; /// @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 = 100000; /// @dev The unique EIP-712 domain separator for the DAI token contract. bytes32 internal constant DAI_DOMAIN_SEPARATOR = 0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7; /// @dev The address for the WETH9 contract on Ethereum mainnet. address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; /// @dev The canonical Permit2 address. /// [Github](https://github.com/Uniswap/permit2) /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3; /// @dev The canonical address of the `SELFDESTRUCT` ETH mover. /// See: https://gist.github.com/Vectorized/1cb8ad4cf393b1378e08f23f79bd99fa /// [Etherscan](https://etherscan.io/address/0x00000000000073c48c8055bD43D1A53799176f0D) address internal constant ETH_MOVER = 0x00000000000073c48c8055bD43D1A53799176f0D; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* 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, codesize(), 0x00, codesize(), 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(), codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`. function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal { /// @solidity memory-safe-assembly assembly { if lt(selfbalance(), amount) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. } } } /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`. function forceSafeTransferAllETH(address to, uint256 gasStipend) internal { /// @solidity memory-safe-assembly assembly { if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. } } } /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`. function forceSafeTransferETH(address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { if lt(selfbalance(), amount) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. } } } /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`. function forceSafeTransferAllETH(address to) internal { /// @solidity memory-safe-assembly assembly { // forgefmt: disable-next-item if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, to) // Store the address in scratch space. mstore8(0x0b, 0x73) // Opcode `PUSH20`. mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`. if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation. } } } /// @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, codesize(), 0x00, codesize(), 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(), codesize(), 0x00, codesize(), 0x00) } } /// @dev Force transfers ETH to `to`, without triggering the fallback (if any). /// This method attempts to use a separate contract to send via `SELFDESTRUCT`, /// and upon failure, deploys a minimal vault to accrue the ETH. function safeMoveETH(address to, uint256 amount) internal returns (address vault) { /// @solidity memory-safe-assembly assembly { to := shr(96, shl(96, to)) // Clean upper 96 bits. for { let mover := ETH_MOVER } iszero(eq(to, address())) {} { let selfBalanceBefore := selfbalance() if or(lt(selfBalanceBefore, amount), eq(to, mover)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } if extcodesize(mover) { let balanceBefore := balance(to) // Check via delta, in case `SELFDESTRUCT` is bricked. mstore(0x00, to) pop(call(gas(), mover, amount, 0x00, 0x20, codesize(), 0x00)) // If `address(to).balance >= amount + balanceBefore`, skip vault workflow. if iszero(lt(balance(to), add(amount, balanceBefore))) { break } // Just in case `SELFDESTRUCT` is changed to not revert and do nothing. if lt(selfBalanceBefore, selfbalance()) { invalid() } } let m := mload(0x40) // If the mover is missing or bricked, deploy a minimal vault // that withdraws all ETH to `to` when being called only by `to`. // forgefmt: disable-next-item mstore(add(m, 0x20), 0x33146025575b600160005260206000f35b3d3d3d3d47335af1601a5760003dfd) mstore(m, or(to, shl(160, 0x6035600b3d3960353df3fe73))) // Compute and store the bytecode hash. mstore8(0x00, 0xff) // Write the prefix. mstore(0x35, keccak256(m, 0x40)) mstore(0x01, shl(96, address())) // Deployer. mstore(0x15, 0) // Salt. vault := keccak256(0x00, 0x55) pop(call(gas(), vault, amount, codesize(), 0x00, codesize(), 0x00)) // The vault returns a single word on success. Failure reverts with empty data. if iszero(returndatasize()) { if iszero(create2(0, m, 0x40, 0)) { revert(codesize(), codesize()) } // For gas estimation. } mstore(0x40, m) // Restore the free memory pointer. break } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* 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, codesize(), 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 Performs a `token.balanceOf(account)` check. /// `implemented` denotes whether the `token` does not implement `balanceOf`. /// `amount` is zero if the `token` does not implement `balanceOf`. function checkBalanceOf(address token, address account) internal view returns (bool implemented, uint256 amount) { /// @solidity memory-safe-assembly assembly { mstore(0x14, account) // Store the `account` argument. mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`. implemented := 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) ) amount := mul(mload(0x20), implemented) } } /// @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) } } /// @dev Sends `amount` of ERC20 `token` from `from` to `to`. /// If the initial attempt fails, try to use Permit2 to transfer the token. /// Reverts upon failure. /// /// The `from` account must have at least `amount` approved for the current contract to manage. function safeTransferFrom2(address token, address from, address to, uint256 amount) internal { if (!trySafeTransferFrom(token, from, to, amount)) { permit2TransferFrom(token, from, to, amount); } } /// @dev Sends `amount` of ERC20 `token` from `from` to `to` via Permit2. /// Reverts upon failure. function permit2TransferFrom(address token, address from, address to, uint256 amount) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) mstore(add(m, 0x74), shr(96, shl(96, token))) mstore(add(m, 0x54), amount) mstore(add(m, 0x34), to) mstore(add(m, 0x20), shl(96, from)) // `transferFrom(address,address,uint160,address)`. mstore(m, 0x36c78516000000000000000000000000) let p := PERMIT2 let exists := eq(chainid(), 1) if iszero(exists) { exists := iszero(iszero(extcodesize(p))) } if iszero( and( call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), lt(iszero(extcodesize(token)), exists) // Token has code and Permit2 exists. ) ) { mstore(0x00, 0x7939f4248757f0fd) // `TransferFromFailed()` or `Permit2AmountOverflow()`. revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04) } } } /// @dev Permit a user to spend a given amount of /// another user's tokens via native EIP-2612 permit if possible, falling /// back to Permit2 if native permit fails or is not implemented on the token. function permit2( address token, address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { bool success; /// @solidity memory-safe-assembly assembly { for {} shl(96, xor(token, WETH9)) {} { mstore(0x00, 0x3644e515) // `DOMAIN_SEPARATOR()`. if iszero( and( // The arguments of `and` are evaluated from right to left. lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)), // Returns 1 non-zero word. // Gas stipend to limit gas burn for tokens that don't refund gas when // an non-existing function is called. 5K should be enough for a SLOAD. staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20) ) ) { break } // After here, we can be sure that token is a contract. let m := mload(0x40) mstore(add(m, 0x34), spender) mstore(add(m, 0x20), shl(96, owner)) mstore(add(m, 0x74), deadline) if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) { mstore(0x14, owner) mstore(0x00, 0x7ecebe00000000000000000000000000) // `nonces(address)`. mstore( add(m, 0x94), lt(iszero(amount), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20)) ) mstore(m, 0x8fcbaf0c000000000000000000000000) // `IDAIPermit.permit`. // `nonces` is already at `add(m, 0x54)`. // `amount != 0` is already stored at `add(m, 0x94)`. mstore(add(m, 0xb4), and(0xff, v)) mstore(add(m, 0xd4), r) mstore(add(m, 0xf4), s) success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00) break } mstore(m, 0xd505accf000000000000000000000000) // `IERC20Permit.permit`. mstore(add(m, 0x54), amount) mstore(add(m, 0x94), and(0xff, v)) mstore(add(m, 0xb4), r) mstore(add(m, 0xd4), s) success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00) break } } if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s); } /// @dev Simple permit on the Permit2 contract. function simplePermit2( address token, address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) mstore(m, 0x927da105) // `allowance(address,address,address)`. { let addressMask := shr(96, not(0)) mstore(add(m, 0x20), and(addressMask, owner)) mstore(add(m, 0x40), and(addressMask, token)) mstore(add(m, 0x60), and(addressMask, spender)) mstore(add(m, 0xc0), and(addressMask, spender)) } let p := mul(PERMIT2, iszero(shr(160, amount))) if iszero( and( // The arguments of `and` are evaluated from right to left. gt(returndatasize(), 0x5f), // Returns 3 words: `amount`, `expiration`, `nonce`. staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60) ) ) { mstore(0x00, 0x6b836e6b8757f0fd) // `Permit2Failed()` or `Permit2AmountOverflow()`. revert(add(0x18, shl(2, iszero(p))), 0x04) } mstore(m, 0x2b67b570) // `Permit2.permit` (PermitSingle variant). // `owner` is already `add(m, 0x20)`. // `token` is already at `add(m, 0x40)`. mstore(add(m, 0x60), amount) mstore(add(m, 0x80), 0xffffffffffff) // `expiration = type(uint48).max`. // `nonce` is already at `add(m, 0xa0)`. // `spender` is already at `add(m, 0xc0)`. mstore(add(m, 0xe0), deadline) mstore(add(m, 0x100), 0x100) // `signature` offset. mstore(add(m, 0x120), 0x41) // `signature` length. mstore(add(m, 0x140), r) mstore(add(m, 0x160), s) mstore(add(m, 0x180), shl(248, v)) if iszero( // Revert if token does not have code, or if the call fails. mul(extcodesize(token), call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00))) { mstore(0x00, 0x6b836e6b) // `Permit2Failed()`. revert(0x1c, 0x04) } } } /// @dev Approves `spender` to spend `amount` of `token` for `address(this)`. function permit2Approve(address token, address spender, uint160 amount, uint48 expiration) internal { /// @solidity memory-safe-assembly assembly { let addressMask := shr(96, not(0)) let m := mload(0x40) mstore(m, 0x87517c45) // `approve(address,address,uint160,uint48)`. mstore(add(m, 0x20), and(addressMask, token)) mstore(add(m, 0x40), and(addressMask, spender)) mstore(add(m, 0x60), and(addressMask, amount)) mstore(add(m, 0x80), and(0xffffffffffff, expiration)) if iszero(call(gas(), PERMIT2, 0, add(m, 0x1c), 0xa0, codesize(), 0x00)) { mstore(0x00, 0x324f14ae) // `Permit2ApproveFailed()`. revert(0x1c, 0x04) } } } /// @dev Revokes an approval for `token` and `spender` for `address(this)`. function permit2Lockdown(address token, address spender) internal { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) mstore(m, 0xcc53287f) // `Permit2.lockdown`. mstore(add(m, 0x20), 0x20) // Offset of the `approvals`. mstore(add(m, 0x40), 1) // `approvals.length`. mstore(add(m, 0x60), shr(96, shl(96, token))) mstore(add(m, 0x80), shr(96, shl(96, spender))) if iszero(call(gas(), PERMIT2, 0, add(m, 0x1c), 0xa0, codesize(), 0x00)) { mstore(0x00, 0x96b3de23) // `Permit2LockdownFailed()`. revert(0x1c, 0x04) } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.30; interface IMintableToken { function previewMint(uint256 amount) external view returns (uint256); function mint(uint256 amount, address receiver) external payable; }
{ "remappings": [ "forge-std/=lib/forge-std/src/", "solady/=lib/solady/src/" ], "optimizer": { "enabled": true, "runs": 1000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "prague", "viaIR": false }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IMintableToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052348015600e575f5ffd5b5060405161036c38038061036c833981016040819052602b91604e565b5f80546001600160a01b0319166001600160a01b03929092169190911790556079565b5f60208284031215605d575f5ffd5b81516001600160a01b03811681146072575f5ffd5b9392505050565b6102e6806100865f395ff3fe608060405260043610610028575f3560e01c806394bf804d1461002c578063fc0c546a14610041575b5f5ffd5b61003f61003a366004610222565b61007b565b005b34801561004c575f5ffd5b505f5461005f906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b5f80546040517fb3d7f6b9000000000000000000000000000000000000000000000000000000008152600481018590526001600160a01b039091169063b3d7f6b990602401602060405180830381865afa1580156100db573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100ff919061025b565b90508034101561016f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f496e73756666696369656e742045544800000000000000000000000000000000604482015260640160405180910390fd5b5f546040517f94bf804d000000000000000000000000000000000000000000000000000000008152600481018590526001600160a01b038481166024830152909116906394bf804d9083906044015f604051808303818588803b1580156101d4575f5ffd5b505af11580156101e6573d5f5f3e3d5ffd5b50505050506102003382346101fb9190610272565b610205565b505050565b5f385f3884865af161021e5763b12d13eb5f526004601cfd5b5050565b5f5f60408385031215610233575f5ffd5b8235915060208301356001600160a01b0381168114610250575f5ffd5b809150509250929050565b5f6020828403121561026b575f5ffd5b5051919050565b818103818111156102aa577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9291505056fea2646970667358221220ed92ce10455120f8dd09f935b616a99c036687c1d332314bf2b19bb765f1b0ce64736f6c634300081e003300000000000000000000000038778e6d4d0dbe9becef3ae8b938570209efa48b
Deployed Bytecode
0x608060405260043610610028575f3560e01c806394bf804d1461002c578063fc0c546a14610041575b5f5ffd5b61003f61003a366004610222565b61007b565b005b34801561004c575f5ffd5b505f5461005f906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b5f80546040517fb3d7f6b9000000000000000000000000000000000000000000000000000000008152600481018590526001600160a01b039091169063b3d7f6b990602401602060405180830381865afa1580156100db573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100ff919061025b565b90508034101561016f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f496e73756666696369656e742045544800000000000000000000000000000000604482015260640160405180910390fd5b5f546040517f94bf804d000000000000000000000000000000000000000000000000000000008152600481018590526001600160a01b038481166024830152909116906394bf804d9083906044015f604051808303818588803b1580156101d4575f5ffd5b505af11580156101e6573d5f5f3e3d5ffd5b50505050506102003382346101fb9190610272565b610205565b505050565b5f385f3884865af161021e5763b12d13eb5f526004601cfd5b5050565b5f5f60408385031215610233575f5ffd5b8235915060208301356001600160a01b0381168114610250575f5ffd5b809150509250929050565b5f6020828403121561026b575f5ffd5b5051919050565b818103818111156102aa577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9291505056fea2646970667358221220ed92ce10455120f8dd09f935b616a99c036687c1d332314bf2b19bb765f1b0ce64736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000038778e6d4d0dbe9becef3ae8b938570209efa48b
-----Decoded View---------------
Arg [0] : _token (address): 0x38778E6d4d0dbE9bEceF3aE8B938570209efa48B
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000038778e6d4d0dbe9becef3ae8b938570209efa48b
Loading...
Loading
Loading...
Loading

Multichain Portfolio | 34 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.