Skip to content
Merged
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased] - Apr 2021
## [Unreleased] - Jun 2021

### Added

- Access controlled mintable & burnable LinkToken, for use on sidechains and L2 networks.
- Documentation and token implementation for the Optimism bridge v2.
- Added versioning to v0.6 & v0.7 contracts

### Changed
Expand Down
2 changes: 2 additions & 0 deletions contracts/v0.7/bridge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ NOTICE: Current implementation of LinkTokenChild contract requires some addition
gets defined, and once online transfer the ownership (bridge gateway role) to the new bridge.

TODO: Potentially create an upgradeable `LinkTokenChild.sol` and limit gateway support to only one (owner)!

- `./token/optimism/`: Documentation and token implementation for the Optimism bridge v2.
50 changes: 50 additions & 0 deletions contracts/v0.7/bridge/token/optimism/IERC20Optimism.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.6.0 <0.8.0;

/* Interface Imports */
import { IERC20 } from "../../../../../vendor/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import { IERC165 } from "../../../../../vendor/OpenZeppelin/openzeppelin-contracts/contracts/introspection/IERC165.sol";

/// @dev Interface for the bridged ERC20 token expected by the Optimism standard bridge L2 gateway.
interface IERC20Optimism is IERC20, IERC165 {
/// @dev Returns the address of an L1 token contract linked to this L2 token contract
function l1Token()
external
returns (address);

/**
* @dev Creates `_amount` tokens `_to` account.
* @notice Called by L2 gateway to deposit tokens.
* @param _to Address of the recipient.
* @param _amount Number of tokens to mint.
*/
function mint(
address _to,
uint256 _amount
)
external;

/**
* @dev Destroys `_amount` tokens `_from` account.
* @notice Called by L2 gateway to withdraw tokens.
* @param _from Address of the account holding the tokens to be burnt.
* @param _amount Number of tokens to burn.
*/
function burn(
address _from,
uint256 _amount
)
external;

/// @dev Emitted when `_amount` tokens are deposited from L1 to L2.
event Mint(
address indexed _account,
uint256 _amount
);

/// @dev Emitted when `_amount` tokens are withdrawn from L2 to L1.
event Burn(
address indexed _account,
uint256 _amount
);
}
109 changes: 109 additions & 0 deletions contracts/v0.7/bridge/token/optimism/LinkTokenOptimism.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: MIT
pragma solidity >0.6.0 <0.8.0;

/* Interface Imports */
import { IERC165 } from "../../../../../vendor/OpenZeppelin/openzeppelin-contracts/contracts/introspection/IERC165.sol";
import { ITypeAndVersion } from "../../../../v0.6/ITypeAndVersion.sol";
import { IERC20Optimism } from "./IERC20Optimism.sol";

/* Contract Imports */
import { ERC20 } from "../../../../../vendor/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import { LinkToken } from "../../../../v0.6/LinkToken.sol";

/// @dev Access controlled mintable & burnable LinkToken, for use on Optimism L2 network.
contract LinkTokenOptimism is ITypeAndVersion, IERC20Optimism, LinkToken {
/// @dev Returns the address of an L2 bridge contract that has access to mint & burn
address public immutable l2Bridge;
/// @inheritdoc IERC20Optimism
address public immutable override l1Token;

/**
* @dev Creates an L2 token connected to a specific L2 bridge gateway & L1 token
* @param l2BridgeAddr Address of the corresponding L2 bridge gateway.
* @param l1TokenAddr Address of the corresponding L1 token.
*/
constructor(
address l2BridgeAddr,
address l1TokenAddr
) {
l2Bridge = l2BridgeAddr;
l1Token = l1TokenAddr;
}

/**
* @notice versions:
*
* - LinkTokenOptimism 0.0.1: initial release
*
* @inheritdoc ITypeAndVersion
*/
function typeAndVersion()
external
pure
override(ITypeAndVersion, LinkToken)
virtual
returns (string memory)
{
return "LinkTokenOptimism 0.0.1";
}

/// @dev Checks that message sender is the L2 bridge contract (locked access to mint & burn)
modifier onlyL2Bridge {
require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn");
_;
}

/**
* @dev Optimism standard bridge L2 gateway uses ERC165 to confirm the required interface
* @inheritdoc IERC165
*/
function supportsInterface(
bytes4 interfaceId
)
public
override
pure
returns (bool)
{
bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165
bytes4 secondSupportedInterface = IERC20Optimism.l1Token.selector
^ IERC20Optimism.mint.selector
^ IERC20Optimism.burn.selector;
return interfaceId == firstSupportedInterface || interfaceId == secondSupportedInterface;
}

/// @inheritdoc IERC20Optimism
function mint(
address _to,
uint256 _amount
)
public
override
onlyL2Bridge()
{
_mint(_to, _amount);
emit Mint(_to, _amount);
}

/// @inheritdoc IERC20Optimism
function burn(
address _from,
uint256 _amount
)
public
override
onlyL2Bridge()
{
_burn(_from, _amount);
emit Burn(_from, _amount);
}

/**
* @dev Overrides parent contract so no tokens are minted on deployment.
* @inheritdoc LinkToken
*/
function _onCreate()
internal
override
{}
}
13 changes: 13 additions & 0 deletions contracts/v0.7/bridge/token/optimism/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# LINK Token on Optimism

- `./token/IERC20Optimism.sol`: Interface for the bridged ERC20 token expected by the Optimism standard bridge L2 gateway.
- `./token/LinkTokenOptimism.sol`: Access controlled mintable & burnable LinkToken, for use on Optimism L2 network.

`LinkTokenOptimism.sol` is a slightly modified version of Optimism's [`L2StandardERC20.sol`](https://github.com/ethereum-optimism/optimism/blob/master/packages/contracts/contracts/optimistic-ethereum/libraries/standards/L2StandardERC20.sol) and will be connected to the [`OVM_L2StandardBridge.sol`](https://github.com/ethereum-optimism/optimism/blob/master/packages/contracts/contracts/optimistic-ethereum/OVM/bridge/tokens/OVM_L2StandardBridge.sol). Modifications include:

- Contract versioning via `ITypeAndVersion` interface
- ERC677 support by extending the `LinkToken` contract
- Transfers & approves to the contract itself blocked (provided by `LinkToken` contract)
- `l2Bridge` & `l1Token` were changed from storage vars to immutable vars, which provides some gas savings

The [Optimism Gateway](https://gateway.optimism.io) bridge UI can be used to move the tokens between networks.