Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(contracts): OZ-L2-M02 WETH9 Approval Can Be Front-Run #632

Merged
merged 5 commits into from
Jul 24, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 17 additions & 60 deletions contracts/src/L2/predeploys/WETH9.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,86 +17,43 @@

pragma solidity ^0.8.0;

// solhint-disable reason-string
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract WETH9 {
string public name = "Wrapped Ether";
string public symbol = "WETH";
uint8 public decimals = 18;
// solhint-disable reason-string
// solhint-disable no-empty-blocks

event Approval(address indexed src, address indexed guy, uint256 wad);
event Transfer(address indexed src, address indexed dst, uint256 wad);
contract WETH9 is ERC20Permit {
HAOYUatHZ marked this conversation as resolved.
Show resolved Hide resolved
/// @notice Emitted when user deposits Ether to this contract.
/// @param dst The address of depositor.
/// @param wad The amount of Ether in wei deposited.
event Deposit(address indexed dst, uint256 wad);

/// @notice Emitted when user withdraws some Ether from this contract.
/// @param src The address of caller.
/// @param wad The amount of Ether in wei withdrawn.
event Withdrawal(address indexed src, uint256 wad);

mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
constructor() ERC20Permit("Wrapped Ether") ERC20("Wrapped Ether", "WETH") {}

receive() external payable {
deposit();
}

function deposit() public payable {
unchecked {
balanceOf[msg.sender] += msg.value;
}
_mint(msg.sender, msg.value);

emit Deposit(msg.sender, msg.value);
}

function withdraw(uint256 wad) public {
require(balanceOf[msg.sender] >= wad);
function withdraw(uint256 wad) external {
_burn(msg.sender, wad);

unchecked {
balanceOf[msg.sender] -= wad;
}

(bool success, ) = msg.sender.call{value:wad}("");
(bool success, ) = msg.sender.call{value: wad}("");
require(success, "withdraw ETH failed");

emit Withdrawal(msg.sender, wad);
}

function totalSupply() public view returns (uint256) {
return address(this).balance;
}

function approve(address guy, uint256 wad) public returns (bool) {
allowance[msg.sender][guy] = wad;

emit Approval(msg.sender, guy, wad);

return true;
}

function transfer(address dst, uint256 wad) public returns (bool) {
return transferFrom(msg.sender, dst, wad);
}

function transferFrom(
address src,
address dst,
uint256 wad
) public returns (bool) {
require(balanceOf[src] >= wad);

if (src != msg.sender && allowance[src][msg.sender] != type(uint256).max) {
require(allowance[src][msg.sender] >= wad);

unchecked {
allowance[src][msg.sender] -= wad;
}
}

unchecked {
balanceOf[src] -= wad;
balanceOf[dst] += wad;
}

emit Transfer(src, dst, wad);

return true;
}
}

/*
Expand Down