Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion contracts/v0.7/bridge/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# LINK Token Bridge v0.7

- `./LinkTokenChild.sol`: A mintable & burnable child LinkToken contract to be used on child networks.
- `./utils/OpUnsafe.sol`: Contract module that used to mark and check safe/unsafe calls to a function.

## Optimism L2 bridge

Expand Down
4 changes: 4 additions & 0 deletions contracts/v0.7/bridge/optimism/OVM_EOACodeHashSet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ abstract contract OVM_EOACodeHashSet is /* Initializable ,*/ OwnableUpgradeable
// Declare the genesis OVM_ProxyEOA.sol EXTCODEHASH
bytes32 constant OVM_EOA_CODE_HASH_V0 = 0x93bb081a7dd92bde63b4d0aa9b8612352b2ec585176a80efc0a2a277ecfc010e;
bytes32 constant OVM_EOA_CODE_HASH_V1 = 0x8b4ea2cb36c232a7bab9d385b7054ff04752ec4c0fad5dc2ed4b1c18d982154c;
bytes32 constant OVM_EOA_CODE_HASH_V2 = 0xb6268ee2707994607682cc0e3b288cdd71acc63df8de0e6baa39a31a2b91d0ad;
bytes32 constant OVM_EOA_CODE_HASH_V3 = 0x93fae832274ff6aa942fa0c287fc0d8fe180f26b36c92e83d9be7e39309d3464;

function __OVM_EOACodeHashSet_init()
internal
Expand All @@ -46,6 +48,8 @@ abstract contract OVM_EOACodeHashSet is /* Initializable ,*/ OwnableUpgradeable
{
s_codeHasheSet.add(OVM_EOA_CODE_HASH_V0);
s_codeHasheSet.add(OVM_EOA_CODE_HASH_V1);
s_codeHasheSet.add(OVM_EOA_CODE_HASH_V2);
s_codeHasheSet.add(OVM_EOA_CODE_HASH_V3);
}

/// @notice Reverts if called by anyone other than whitelisted EOA contracts.
Expand Down
50 changes: 38 additions & 12 deletions contracts/v0.7/bridge/optimism/OVM_L1ERC20Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol";
/* Contract Imports */
import { Initializable } from "@openzeppelin/contracts/proxy/Initializable.sol";
import { Abs_L1TokenGateway } from "@eth-optimism/contracts/OVM/bridge/tokens/Abs_L1TokenGateway.sol";
import { OpUnsafe } from "../utils/OpUnsafe.sol";

/**
* @title OVM_L1ERC20Gateway
Expand All @@ -29,7 +28,7 @@ import { OpUnsafe } from "../utils/OpUnsafe.sol";
* Compiler used: solc
* Runtime target: EVM
*/
contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, OpUnsafe, Abs_L1TokenGateway {
contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, Abs_L1TokenGateway {
// L1 token we are bridging to L2
IERC20 public s_l1ERC20;

Expand Down Expand Up @@ -79,12 +78,6 @@ contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, OpUnsafe, Abs_L1To
l2DepositedToken = l2ERC20Gateway;
messenger = l1Messenger;

// Default gas value which should be modified if more complex logic runs on L2.
// NOTICE: this is not a constant, but a storage var, so we need to explicitly
// init here if using the contract in a delegatecall context.
DEFAULT_FINALIZE_DEPOSIT_L2_GAS = 1200000;


__OVM_L1ERC20Gateway_init_unchained(l1ERC20);
}

Expand All @@ -107,6 +100,13 @@ contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, OpUnsafe, Abs_L1To
_;
}

/// @dev Modifier requiring sender to be EOA
modifier onlyEOA(address acc) {
// Used to stop withdrawals to contracts (avoid accidentally lost tokens)
require(!Address.isContract(acc), "Account not EOA");
_;
}

/// @dev Returns L2 ERC20 Gateway address (AKA l2DepositedToken).
function l2ERC20Gateway()
public
Expand All @@ -132,11 +132,41 @@ contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, OpUnsafe, Abs_L1To
)
external
override
onlyEOA(_sender)
{
require(msg.sender == address(s_l1ERC20), "onTokenTransfer sender not valid");
_initiateDeposit(_sender, _sender, _value);
}

/**
* @notice Only accessible by EOA sender.
* @inheritdoc Abs_L1TokenGateway
*/
function deposit(
uint _amount
)
external
override
onlyEOA(msg.sender)
{
_initiateDeposit(msg.sender, msg.sender, _amount);
}

/**
* @notice Recipient account must be EOA.
* @inheritdoc Abs_L1TokenGateway
*/
function depositTo(
address _to,
uint _amount
)
external
override
onlyEOA(_to)
{
_initiateDeposit(msg.sender, _to, _amount);
}

/**
* @dev deposit an amount of ERC20 to a recipients's balance on L2
* WARNING: This is a potentially unsafe operation that could end up with lost tokens,
Expand All @@ -150,7 +180,6 @@ contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, OpUnsafe, Abs_L1To
uint _amount
)
external
unsafe()
{
_initiateDeposit(msg.sender, _to, _amount);
}
Expand All @@ -172,9 +201,6 @@ contract OVM_L1ERC20Gateway is ERC677Receiver, Initializable, OpUnsafe, Abs_L1To
override
onlyInitialized()
{
// Unless explicitly unsafe op, stop deposits to contracts (avoid accidentally lost tokens)
require(_isUnsafe() || !Address.isContract(_to), "Unsafe deposit to contract");

// Funds already transfered via trasferAndCall (skipping)
if (msg.sender == address(s_l1ERC20)) return;

Expand Down
44 changes: 38 additions & 6 deletions contracts/v0.7/bridge/optimism/OVM_L2ERC20Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/Initializable.sol";
import { iOVM_L1TokenGateway } from "@eth-optimism/contracts/iOVM/bridge/tokens/iOVM_L1TokenGateway.sol";
import { Abs_L2DepositedToken } from "@eth-optimism/contracts/OVM/bridge/tokens/Abs_L2DepositedToken.sol";
import { OpUnsafe } from "../utils/OpUnsafe.sol";
import { OVM_EOACodeHashSet } from "./OVM_EOACodeHashSet.sol";

/**
Expand All @@ -25,7 +24,7 @@ import { OVM_EOACodeHashSet } from "./OVM_EOACodeHashSet.sol";
* Compiler used: optimistic-solc
* Runtime target: OVM
*/
contract OVM_L2ERC20Gateway is ERC677Receiver, /* Initializable ,*/ OpUnsafe, OVM_EOACodeHashSet, Abs_L2DepositedToken {
contract OVM_L2ERC20Gateway is ERC677Receiver, /* Initializable ,*/ OVM_EOACodeHashSet, Abs_L2DepositedToken {
// Bridged L2 token
IERC20Child public s_l2ERC20;

Expand Down Expand Up @@ -95,6 +94,13 @@ contract OVM_L2ERC20Gateway is ERC677Receiver, /* Initializable ,*/ OpUnsafe, OV
s_l2ERC20 = IERC20Child(l2ERC20);
}

/// @dev Modifier requiring sender to be EOA
modifier onlyEOA(address acc) {
// Used to stop withdrawals to contracts (avoid accidentally lost tokens)
require(!Address.isContract(acc) || _isEOAContract(acc), "Account not EOA");
_;
}

/**
* @dev Hook on successful token transfer that initializes withdrawal
* @notice Avoids two step approve/transferFrom, only accessible by EOA sender via ERC677 transferAndCall.
Expand All @@ -107,11 +113,41 @@ contract OVM_L2ERC20Gateway is ERC677Receiver, /* Initializable ,*/ OpUnsafe, OV
)
external
override
onlyEOA(_sender)
{
require(msg.sender == address(s_l2ERC20), "onTokenTransfer sender not valid");
_initiateWithdrawal(_sender, _value);
}

/**
* @notice Only accessible by EOA sender.
* @inheritdoc Abs_L2DepositedToken
*/
function withdraw(
uint _amount
)
external
override
onlyEOA(msg.sender)
{
_initiateWithdrawal(msg.sender, _amount);
}

/**
* @notice Recipient account must be EOA.
* @inheritdoc Abs_L2DepositedToken
*/
function withdrawTo(
address _to,
uint _amount
)
external
override
onlyEOA(_to)
{
_initiateWithdrawal(_to, _amount);
}

/**
* @dev initiate a withdraw of some token to a recipient's account on L1
* WARNING: This is a potentially unsafe operation that could end up with lost tokens,
Expand All @@ -125,7 +161,6 @@ contract OVM_L2ERC20Gateway is ERC677Receiver, /* Initializable ,*/ OpUnsafe, OV
uint _amount
)
external
unsafe()
{
_initiateWithdrawal(_to, _amount);
}
Expand All @@ -142,9 +177,6 @@ contract OVM_L2ERC20Gateway is ERC677Receiver, /* Initializable ,*/ OpUnsafe, OV
override
onlyInitialized()
{
// Unless explicitly unsafe op, stop withdrawals to contracts (avoid accidentally lost tokens)
require(_isUnsafe() || !Address.isContract(_to) || _isEOAContract(_to), "Unsafe withdraw to contract");

// Check if funds already transfered via trasferAndCall (skipping)
if (msg.sender != address(s_l2ERC20)) {
// Take the newly deposited funds (must be approved)
Expand Down
49 changes: 0 additions & 49 deletions contracts/v0.7/bridge/utils/OpUnsafe.sol

This file was deleted.

11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"contracts/*"
],
"scripts": {
"clean": "tsc -b --clean tsconfig.json && rm -rf build/",
"prepack": "yarn setup",
"clean": "tsc -b --clean tsconfig.json && rm -rf build/",
"setup": "yarn build:contracts && yarn build",
"lint": "echo \"Please set up linter\"",
"build": "tsc -p tsconfig.json",
Expand All @@ -37,11 +37,13 @@
"dependencies": {
"@chainlink/contracts": "^0.1.6",
"@chainlink/optimism-utils": "https://github.com/smartcontractkit/optimism-utils.git",
"@eth-optimism/contracts": "^0.2.4",
"@eth-optimism/contracts": "^0.2.7",
"@ethersproject/bignumber": "^5.1.1",
"@ethersproject/units": "^5.1.0",
"@openzeppelin/contracts": "3.4.0",
"@openzeppelin/contracts-upgradeable": "3.4.0",
"dotenv": "^8.2.0",
"ethers": "^5.1.0",
"ethers": "^5.1.3",
"glob": "^7.1.6",
"hardhat": "^2.2.0",
"lodash": "^4.17.21",
Expand All @@ -67,8 +69,5 @@
"ts-node": "^9.1.1",
"typechain": "^4.0.3",
"typescript": "^4.2.3"
},
"resolutions": {
"@eth-optimism/core-utils": "^0.2.3"
}
}
5 changes: 3 additions & 2 deletions scripts/deposit-withdraw.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Wallet, Contract, BigNumberish } from 'ethers'
import { Wallet, Contract } from 'ethers'
import { BigNumberish } from '@ethersproject/bignumber'
import { parseEther } from '@ethersproject/units'
import { Direction, waitForXDomainTransaction } from '@chainlink/optimism-utils/dist/watcher-utils'
import { argv, getContractFactory, deploy, optimism, Targets, Versions } from '../src'
Expand Down Expand Up @@ -206,7 +207,7 @@ const _run = async () => {
const targetNetwork = (argv.network as string) || 'local'
const oe = await optimism.loadEnv(targetNetwork)
// Fund L2 wallet
await oe.depositL2(parseEther('1'))
await oe.depositL2(parseEther('1') as BigNumberish)
// Start scripts
await depositAndWithdraw(
oe,
Expand Down
2 changes: 1 addition & 1 deletion src/optimism/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const loadEnv = async (envName: string = 'local'): Promise<optimism.env.O
}

// TODO: Fix ERROR { "reason":"cannot estimate gas; transaction may fail or may require manual gas limit","code":"UNPREDICTABLE_GAS_LIMIT" }
export const TX_OVERRIDES_OE_BUG = {
export const TX_OVERRIDES_OE_BUG: any = {
gasPrice: utils.parseUnits('1', 'gwei'),
gasLimit: 2_000_000,
}
Expand Down
6 changes: 2 additions & 4 deletions test/v0.7/bridge/optimism/OVM_L1ERC20Gateway.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ describe(`OVM_L1ERC20Gateway ${Versions.v0_7}`, () => {
const contractAddr = l1Token.address
const amount = totalAmount

await expect(l1Gateway.depositTo(contractAddr, amount)).to.be.revertedWith(
'Unsafe deposit to contract',
)
await expect(l1Gateway.depositTo(contractAddr, amount)).to.be.revertedWith('Account not EOA')
})

it('can depositToUnsafe contract', async () => {
Expand Down Expand Up @@ -123,7 +121,7 @@ describe(`OVM_L1ERC20Gateway ${Versions.v0_7}`, () => {
// Mock contract tries (fails) to transferAndCall to L1 Gateway
const payload = [l1Token.address, l1Gateway.address, amount, Buffer.from('')]
await expect(erc677CallerMock.callTransferAndCall(...payload)).to.be.revertedWith(
'Unsafe deposit to contract',
'Account not EOA',
)
})

Expand Down
8 changes: 4 additions & 4 deletions test/v0.7/bridge/optimism/OVM_L2ERC20Gateway.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from 'chai'
import { Wallet, Contract } from 'ethers'
import { Wallet, Contract, BigNumberish } from 'ethers'
import { getContractFactory, deploy, Targets, Versions, optimism } from '../../../../src'
import * as h from '../../../helpers'

Expand All @@ -19,7 +19,7 @@ describe(`OVM_L2ERC20Gateway ${Versions.v0_7}`, () => {

// Load the configuration from environment
oe = await optimism.loadEnv()
await oe.depositL2(parseEther('1'))
await oe.depositL2(parseEther('1') as BigNumberish)

// Deploy LinkTokenChild contract
l2Token = await deploy(
Expand Down Expand Up @@ -111,7 +111,7 @@ describe(`OVM_L2ERC20Gateway ${Versions.v0_7}`, () => {
)

// TODO: fetch revert reason
// revert: Unsafe withdraw to contract
// revert: Account not EOA
await h.txRevert(withdrawToTx.wait())
}).timeout(10000)

Expand Down Expand Up @@ -171,7 +171,7 @@ describe(`OVM_L2ERC20Gateway ${Versions.v0_7}`, () => {
)

// TODO: fetch revert reason
// revert: Unsafe deposit to contract
// revert: Account not EOA
await h.txRevert(callTransferAndCallTx.wait())
})
}).timeout(10000)
Expand Down
3 changes: 2 additions & 1 deletion test/v0.7/bridge/optimism/deposit-withdraw.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { BigNumberish } from '@ethersproject/bignumber'
import { parseEther } from '@ethersproject/units'
import { expect } from 'chai'
import { depositAndWithdraw, CheckBalances } from '../../../../scripts/deposit-withdraw'
Expand All @@ -14,7 +15,7 @@ import * as h from '../../../helpers'
// Load the configuration from environment
oe = await optimism.loadEnv()
// Fund L2 wallet
await oe.depositL2(parseEther('1'))
await oe.depositL2(parseEther('1') as BigNumberish)
})

const checkBalances = (step = 0): CheckBalances => async (
Expand Down
Loading