// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import {ERC20} from "./ERC20.sol"; /// @notice Simple Wrapped Ether implementation. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/WETH.sol) /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/WETH.sol) /// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol) contract WETH is ERC20 { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ETH transfer has failed. error ETHTransferFailed(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Emitted when `amount` is deposited from `from`. event Deposit(address indexed from, uint256 amount); /// @dev Emitted when `amount` is withdrawn to `to`. event Withdrawal(address indexed to, uint256 amount); /// @dev `keccak256(bytes("Deposit(address,uint256)"))`. uint256 private constant _DEPOSIT_EVENT_SIGNATURE = 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c; /// @dev `keccak256(bytes("Withdrawal(address,uint256)"))`. uint256 private constant _WITHDRAWAL_EVENT_SIGNATURE = 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC20 METADATA */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the name of the token. function name() public view virtual override returns (string memory) { return "Wrapped Ether"; } /// @dev Returns the symbol of the token. function symbol() public view virtual override returns (string memory) { return "WETH"; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* WETH */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Deposits `amount` ETH of the caller and mints `amount` WETH to the caller. /// /// Emits a {Deposit} event. function deposit() public payable virtual { _mint(msg.sender, msg.value); /// @solidity memory-safe-assembly assembly { // Emit the {Deposit} event. mstore(0x00, callvalue()) log2(0x00, 0x20, _DEPOSIT_EVENT_SIGNATURE, caller()) } } /// @dev Burns `amount` WETH of the caller and sends `amount` ETH to the caller. /// /// Emits a {Withdrawal} event. function withdraw(uint256 amount) public virtual { _burn(msg.sender, amount); /// @solidity memory-safe-assembly assembly { // Emit the {Withdrawal} event. mstore(0x00, amount) log2(0x00, 0x20, _WITHDRAWAL_EVENT_SIGNATURE, caller()) // Transfer the ETH and check if it succeeded or not. if iszero(call(gas(), caller(), amount, codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } } } /// @dev Equivalent to `deposit()`. receive() external payable virtual { deposit(); } }