Skip to content

Commit

Permalink
feat: disable ETH ERC20 features
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcontracts committed Oct 14, 2021
1 parent a7d0fad commit a846d7e
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 135 deletions.
7 changes: 6 additions & 1 deletion integration-tests/test/fee-payment.spec.ts
Expand Up @@ -47,7 +47,12 @@ describe('Fee Payment Integration Tests', async () => {
}

// Transfer the minimum required to withdraw.
await env.ovmEth.transfer(ovmSequencerFeeVault.address, withdrawalAmount)
const tx = await env.l2Wallet.sendTransaction({
to: ovmSequencerFeeVault.address,
value: withdrawalAmount,
gasLimit: 500000,
})
await tx.wait()

const vaultBalance = await env.ovmEth.balanceOf(
ovmSequencerFeeVault.address
Expand Down
78 changes: 4 additions & 74 deletions integration-tests/test/native-eth.spec.ts
Expand Up @@ -55,14 +55,6 @@ describe('Native ETH Integration Tests', async () => {
})

describe('estimateGas', () => {
it('Should estimate gas for ETH transfer', async () => {
const amount = utils.parseEther('0.0000001')
const addr = '0x' + '1234'.repeat(10)
const gas = await env.ovmEth.estimateGas.transfer(addr, amount)
// Expect gas to be less than or equal to the target plus 1%
expectApprox(gas, 6430020, { upperPercentDeviation: 1 })
})

it('Should estimate gas for ETH withdraw', async () => {
const amount = utils.parseEther('0.0000001')
const gas = await env.l2Bridge.estimateGas.withdraw(
Expand Down Expand Up @@ -292,7 +284,10 @@ describe('Native ETH Integration Tests', async () => {

// 2. trnsfer to another address
const other = Wallet.createRandom().connect(env.l2Wallet.provider)
const tx = await env.ovmEth.transfer(other.address, amount)
const tx = await env.l2Wallet.sendTransaction({
to: other.address,
value: amount,
})
await tx.wait()

const l1BalanceBefore = await other
Expand Down Expand Up @@ -325,69 +320,4 @@ describe('Native ETH Integration Tests', async () => {
expect(l1BalanceAfter).to.deep.eq(l1BalanceBefore.add(withdrawnAmount))
expect(l2BalanceAfter).to.deep.eq(amount.sub(withdrawnAmount).sub(fee))
})

describe('WETH9 functionality', async () => {
let initialBalance: BigNumber
const value = 10

beforeEach(async () => {
await fundUser(env.watcher, env.l1Bridge, value, env.l2Wallet.address)
initialBalance = await env.l2Wallet.provider.getBalance(
env.l2Wallet.address
)
})

it('successfully deposits', async () => {
const depositTx = await env.ovmEth.deposit({ value, gasPrice: 0 })
const receipt = await depositTx.wait()

expect(
await env.l2Wallet.provider.getBalance(env.l2Wallet.address)
).to.equal(initialBalance)
expect(receipt.events.length).to.equal(2)

const [transferEvent, depositEvent] = receipt.events

expect(transferEvent.event).to.equal('Transfer')
expect(transferEvent.args.from).to.equal(env.ovmEth.address)
expect(transferEvent.args.to).to.equal(env.l2Wallet.address)
expect(transferEvent.args.value).to.equal(value)

expect(depositEvent.event).to.equal('Deposit')
expect(depositEvent.args.dst).to.equal(env.l2Wallet.address)
expect(depositEvent.args.wad).to.equal(value)
})

it('successfully deposits on fallback', async () => {
const fallbackTx = await env.l2Wallet.sendTransaction({
to: env.ovmEth.address,
value,
gasPrice: 0,
})
const receipt = await fallbackTx.wait()
expect(receipt.status).to.equal(1)
expect(
await env.l2Wallet.provider.getBalance(env.l2Wallet.address)
).to.equal(initialBalance)
})

it('successfully withdraws', async () => {
const withdrawTx = await env.ovmEth.withdraw(value, { gasPrice: 0 })
const receipt = await withdrawTx.wait()
expect(
await env.l2Wallet.provider.getBalance(env.l2Wallet.address)
).to.equal(initialBalance)
expect(receipt.events.length).to.equal(1)

const depositEvent = receipt.events[0]
expect(depositEvent.event).to.equal('Withdrawal')
expect(depositEvent.args.src).to.equal(env.l2Wallet.address)
expect(depositEvent.args.wad).to.equal(value)
})

it('reverts on invalid withdraw', async () => {
await expect(env.ovmEth.withdraw(initialBalance.add(1), { gasPrice: 0 }))
.to.be.reverted
})
})
})
2 changes: 1 addition & 1 deletion l2geth/rollup/dump/constants.go
Expand Up @@ -4,5 +4,5 @@ import (
"github.com/ethereum/go-ethereum/common"
)

var OvmEthAddress = common.HexToAddress("0x4200000000000000000000000000000000000006")
var OvmEthAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000")
var OvmFeeWallet = common.HexToAddress("0x4200000000000000000000000000000000000011")
59 changes: 16 additions & 43 deletions packages/contracts/contracts/L2/predeploys/OVM_ETH.sol
Expand Up @@ -6,7 +6,6 @@ import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployA

/* Contract Imports */
import { L2StandardERC20 } from "../../libraries/standards/L2StandardERC20.sol";
import { IWETH9 } from "../../libraries/standards/IWETH9.sol";

/**
* @title OVM_ETH
Expand All @@ -15,7 +14,7 @@ import { IWETH9 } from "../../libraries/standards/IWETH9.sol";
*
* Runtime target: OVM
*/
contract OVM_ETH is L2StandardERC20, IWETH9 {
contract OVM_ETH is L2StandardERC20 {

/***************
* Constructor *
Expand All @@ -31,52 +30,26 @@ contract OVM_ETH is L2StandardERC20, IWETH9 {
{}


/******************************
* Custom WETH9 Functionality *
******************************/
fallback() external payable {
deposit();
// ETH ERC20 features are disabled until further notice.
// Discussion here: https://github.com/ethereum-optimism/optimism/discussions/1444

function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
revert("OVM_ETH: transfer is disabled pending further community discussion.");
}

/**
* Implements the WETH9 deposit() function as a no-op.
* WARNING: this function does NOT have to do with cross-chain asset bridging. The relevant
* deposit and withdraw functions for that use case can be found at L2StandardBridge.sol.
* This function allows developers to treat OVM_ETH as WETH without any modifications to their
* code.
*/
function deposit()
public
payable
override
{
// Calling deposit() with nonzero value will send the ETH to this contract address.
// Once received here, we transfer it back by sending to the msg.sender.
_transfer(address(this), msg.sender, msg.value);
function approve(address spender, uint256 amount) public virtual override returns (bool) {
revert("OVM_ETH: approve is disabled pending further community discussion.");
}

emit Deposit(msg.sender, msg.value);
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
revert("OVM_ETH: transferFrom is disabled pending further community discussion.");
}

/**
* Implements the WETH9 withdraw() function as a no-op.
* WARNING: this function does NOT have to do with cross-chain asset bridging. The relevant
* deposit and withdraw functions for that use case can be found at L2StandardBridge.sol.
* This function allows developers to treat OVM_ETH as WETH without any modifications to their
* code.
* @param _wad Amount being withdrawn
*/
function withdraw(
uint256 _wad
)
external
override
{
// Calling withdraw() with value exceeding the withdrawer's ovmBALANCE should revert,
// as in WETH9.
require(balanceOf(msg.sender) >= _wad);
function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
revert("OVM_ETH: increaseAllowance is disabled pending further community discussion.");
}

// Other than emitting an event, OVM_ETH already is native ETH, so we don't need to do
// anything else.
emit Withdrawal(msg.sender, _wad);
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual override returns (bool) {
revert("OVM_ETH: decreaseAllowance is disabled pending further community discussion.");
}
}
Expand Up @@ -5,7 +5,6 @@ pragma solidity >0.5.0 <0.8.0;
import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol";

/* Contract Imports */
import { OVM_ETH } from "./OVM_ETH.sol";
import { OVM_L2StandardBridge } from "../messaging/OVM_L2StandardBridge.sol";

/**
Expand Down Expand Up @@ -49,25 +48,30 @@ contract OVM_SequencerFeeVault {
}


/************
* Fallback *
************/

receive() external payable {}


/********************
* Public Functions *
********************/

function withdraw()
public
{
uint256 balance = OVM_ETH(Lib_PredeployAddresses.OVM_ETH).balanceOf(address(this));

require(
balance >= MIN_WITHDRAWAL_AMOUNT,
address(this).balance >= MIN_WITHDRAWAL_AMOUNT,
// solhint-disable-next-line max-line-length
"OVM_SequencerFeeVault: withdrawal amount must be greater than minimum withdrawal amount"
);

OVM_L2StandardBridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE).withdrawTo(
Lib_PredeployAddresses.OVM_ETH,
l1FeeWallet,
balance,
address(this).balance,
0,
bytes("")
);
Expand Down
Expand Up @@ -9,7 +9,7 @@ library Lib_PredeployAddresses {
address internal constant L2_TO_L1_MESSAGE_PASSER = 0x4200000000000000000000000000000000000000;
address internal constant L1_MESSAGE_SENDER = 0x4200000000000000000000000000000000000001;
address internal constant DEPLOYER_WHITELIST = 0x4200000000000000000000000000000000000002;
address payable internal constant OVM_ETH = 0x4200000000000000000000000000000000000006;
address payable internal constant OVM_ETH = 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000;
address internal constant L2_CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;
address internal constant LIB_ADDRESS_MANAGER = 0x4200000000000000000000000000000000000008;
address internal constant PROXY_EOA = 0x4200000000000000000000000000000000000009;
Expand Down
5 changes: 4 additions & 1 deletion packages/contracts/src/predeploys.ts
Expand Up @@ -11,11 +11,14 @@ export const predeploys = {
OVM_L2ToL1MessagePasser: '0x4200000000000000000000000000000000000000',
OVM_L1MessageSender: '0x4200000000000000000000000000000000000001',
OVM_DeployerWhitelist: '0x4200000000000000000000000000000000000002',
OVM_ETH: '0x4200000000000000000000000000000000000006',
OVM_L2CrossDomainMessenger: '0x4200000000000000000000000000000000000007',
OVM_GasPriceOracle: '0x420000000000000000000000000000000000000F',
OVM_L2StandardBridge: '0x4200000000000000000000000000000000000010',
OVM_SequencerFeeVault: '0x4200000000000000000000000000000000000011',
OVM_L2StandardTokenFactory: '0x4200000000000000000000000000000000000012',
OVM_L1BlockNumber: '0x4200000000000000000000000000000000000013',

// We're temporarily disabling OVM_ETH because the jury is still out on whether or not ETH as an
// ERC20 is desirable.
OVM_ETH: '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000',
}
77 changes: 77 additions & 0 deletions packages/contracts/test/contracts/L2/predeploys/OVM_ETH.spec.ts
@@ -0,0 +1,77 @@
import { expect } from '../../../setup'

/* External Imports */
import { ethers } from 'hardhat'
import { ContractFactory, Contract, Signer } from 'ethers'

describe('OVM_ETH', () => {
let signer1: Signer
let signer2: Signer
before(async () => {
;[signer1, signer2] = await ethers.getSigners()
})

let Factory__OVM_ETH: ContractFactory
before(async () => {
Factory__OVM_ETH = await ethers.getContractFactory('OVM_ETH')
})

let OVM_ETH: Contract
beforeEach(async () => {
OVM_ETH = await Factory__OVM_ETH.deploy()
})

describe('transfer', () => {
it('should revert', async () => {
await expect(
OVM_ETH.transfer(await signer2.getAddress(), 100)
).to.be.revertedWith(
'OVM_ETH: transfer is disabled pending further community discussion.'
)
})
})

describe('approve', () => {
it('should revert', async () => {
await expect(
OVM_ETH.approve(await signer2.getAddress(), 100)
).to.be.revertedWith(
'OVM_ETH: approve is disabled pending further community discussion.'
)
})
})

describe('transferFrom', () => {
it('should revert', async () => {
await expect(
OVM_ETH.transferFrom(
await signer1.getAddress(),
await signer2.getAddress(),
100
)
).to.be.revertedWith(
'OVM_ETH: transferFrom is disabled pending further community discussion.'
)
})
})

describe('increaseAllowance', () => {
it('should revert', async () => {
await expect(
OVM_ETH.increaseAllowance(await signer2.getAddress(), 100)
).to.be.revertedWith(
'OVM_ETH: increaseAllowance is disabled pending further community discussion.'
)
})
})

describe('decreaseAllowance', () => {
it('should revert', async () => {
await expect(
OVM_ETH.decreaseAllowance(await signer2.getAddress(), 100)
).to.be.revertedWith(
'OVM_ETH: decreaseAllowance is disabled pending further community discussion.'
)
})
})
})
Expand Up @@ -14,12 +14,8 @@ describe('OVM_SequencerFeeVault', () => {
;[signer1] = await hre.ethers.getSigners()
})

let Mock__OVM_ETH: MockContract
let Mock__OVM_L2StandardBridge: MockContract
before(async () => {
Mock__OVM_ETH = await smockit('OVM_ETH', {
address: predeploys.OVM_ETH,
})
Mock__OVM_L2StandardBridge = await smockit('OVM_L2StandardBridge', {
address: predeploys.OVM_L2StandardBridge,
})
Expand All @@ -33,14 +29,17 @@ describe('OVM_SequencerFeeVault', () => {

describe('withdraw', async () => {
it('should fail if the contract does not have more than the minimum balance', async () => {
Mock__OVM_ETH.smocked.balanceOf.will.return.with(0)

await expect(OVM_SequencerFeeVault.withdraw()).to.be.reverted
})

it('should succeed when the contract has exactly sufficient balance', async () => {
// Send just the balance that the contract needs.
const amount = await OVM_SequencerFeeVault.MIN_WITHDRAWAL_AMOUNT()
Mock__OVM_ETH.smocked.balanceOf.will.return.with(amount)

await signer1.sendTransaction({
to: OVM_SequencerFeeVault.address,
value: amount,
})

await expect(OVM_SequencerFeeVault.withdraw()).to.not.be.reverted

Expand All @@ -56,8 +55,14 @@ describe('OVM_SequencerFeeVault', () => {
})

it('should succeed when the contract has more than sufficient balance', async () => {
const amount = hre.ethers.utils.parseEther('100')
Mock__OVM_ETH.smocked.balanceOf.will.return.with(amount)
// Send just twice the balance that the contract needs.
let amount = await OVM_SequencerFeeVault.MIN_WITHDRAWAL_AMOUNT()
amount = amount.mul(2)

await signer1.sendTransaction({
to: OVM_SequencerFeeVault.address,
value: amount,
})

await expect(OVM_SequencerFeeVault.withdraw()).to.not.be.reverted

Expand Down

0 comments on commit a846d7e

Please sign in to comment.