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

feat(protocol): add TaikoGovernor and improve TaikoToken #13711

Merged
merged 8 commits into from
May 8, 2023
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
4 changes: 4 additions & 0 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pragma solidity ^0.8.18;
import {AddressResolver} from "../common/AddressResolver.sol";
import {EssentialContract} from "../common/EssentialContract.sol";
import {ICrossChainSync} from "../common/ICrossChainSync.sol";
import {Proxied} from "../common/Proxied.sol";
import {LibEthDepositing} from "./libs/LibEthDepositing.sol";
import {LibTokenomics} from "./libs/LibTokenomics.sol";
import {LibProposing} from "./libs/LibProposing.sol";
Expand All @@ -20,6 +21,7 @@ import {TaikoErrors} from "./TaikoErrors.sol";
import {TaikoData} from "./TaikoData.sol";
import {TaikoEvents} from "./TaikoEvents.sol";

/// @custom:security-contact hello@taiko.xyz
contract TaikoL1 is
EssentialContract,
ICrossChainSync,
Expand Down Expand Up @@ -248,3 +250,5 @@ contract TaikoL1 is
return LibUtils.getVerifierName(id);
}
}

contract ProxiedTaikoL1 is Proxied, TaikoL1 {}
167 changes: 102 additions & 65 deletions packages/protocol/contracts/L1/TaikoToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,74 +7,98 @@
pragma solidity ^0.8.18;

import {
ERC20Upgradeable,
IERC20Upgradeable
} from "../thirdparty/ERC20Upgradeable.sol";
import {EssentialContract} from "../common/EssentialContract.sol";
import {IMintableERC20} from "../common/IMintableERC20.sol";
import {LibMath} from "../libs/LibMath.sol";
ERC20Upgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {
SafeCastUpgradeable
} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";

/// @dev This is Taiko's governance and fee token.
contract TaikoToken is EssentialContract, ERC20Upgradeable, IMintableERC20 {
using LibMath for uint256;
using SafeCastUpgradeable for uint256;
ERC20BurnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import {
ERC20SnapshotUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol";
import {
PausableUpgradeable
} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";

/*********************
* State Variables *
*********************/
import {
ERC20PermitUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";
import {
ERC20VotesUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import {EssentialContract} from "../common/EssentialContract.sol";
import {Proxied} from "../common/Proxied.sol";

uint256[50] private __gap;
library LibTaikoTokenConfig {
uint8 public constant DECIMALS = uint8(8);
}

/*********************
* Events and Errors *
*********************/
/// @custom:security-contact hello@taiko.xyz
contract TaikoToken is
EssentialContract,
ERC20Upgradeable,
ERC20BurnableUpgradeable,
ERC20SnapshotUpgradeable,
PausableUpgradeable,
ERC20PermitUpgradeable,
ERC20VotesUpgradeable
{
event Mint(address account, uint256 amount);
event Burn(address account, uint256 amount);

error TKO_INVALID_ADDR();
error TKO_INVALID_PREMINT_PARAMS();
error TKO_MINT_DISALLOWED();

/*********************
* External Functions*
*********************/

/// @dev Initializer to be called after being deployed behind a proxy.
/// Based on our simulation in simulate/tokenomics/index.js, both
/// amountMintToDAO and amountMintToDev shall be set to ~150,000,000.
function init(
address _addressManager,
string calldata _name,
string calldata _symbol,
address[] calldata _premintRecipients,
uint256[] calldata _premintAmounts
) external initializer {
if (_premintRecipients.length != _premintAmounts.length)
revert TKO_INVALID_PREMINT_PARAMS();

) public initializer {
EssentialContract._init(_addressManager);
ERC20Upgradeable.__ERC20_init({
name_: _name,
symbol_: _symbol,
decimals_: 8
});
__ERC20_init(_name, _symbol);
__ERC20Burnable_init();
__ERC20Snapshot_init();
__Pausable_init();
__ERC20Permit_init(_name);
__ERC20Votes_init();

for (uint256 i = 0; i < _premintRecipients.length; ++i) {
_mint(_premintRecipients[i], _premintAmounts[i]);
}
}

/*********************
* Public Functions *
*********************/
function snapshot() public onlyOwner {
_snapshot();
}

function pause() public onlyOwner {
_pause();
}

function unpause() public onlyOwner {
_unpause();
}

function mint(
address to,
uint256 amount
) public onlyFromNamed("proto_broker") {
_mint(to, amount);
}

function burn(
address from,
uint256 amount
) public onlyFromNamed("proto_broker") {
_burn(from, amount);
}

function transfer(
address to,
uint256 amount
) public override(ERC20Upgradeable, IERC20Upgradeable) returns (bool) {
) public override returns (bool) {
if (to == address(this)) revert TKO_INVALID_ADDR();
return ERC20Upgradeable.transfer(to, amount);
}
Expand All @@ -83,41 +107,54 @@ contract TaikoToken is EssentialContract, ERC20Upgradeable, IMintableERC20 {
address from,
address to,
uint256 amount
) public override(ERC20Upgradeable, IERC20Upgradeable) returns (bool) {
) public override returns (bool) {
if (to == address(this)) revert TKO_INVALID_ADDR();
return ERC20Upgradeable.transferFrom(from, to, amount);
}

/**
* @dev Mints tokens to the given address's balance. This will increase
* the circulating supply.
* @param account The address to receive the tokens.
* @param amount The amount of tokens to mint.
*/
function mint(
address account,
function decimals() public pure override returns (uint8) {
return LibTaikoTokenConfig.DECIMALS;
}

function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) public onlyFromNamed("proto_broker") {
_mint(account, amount);
emit Mint(account, amount);
)
internal
override(ERC20Upgradeable, ERC20SnapshotUpgradeable)
whenNotPaused
{
super._beforeTokenTransfer(from, to, amount);
}

/**
* @dev Burn tokens from the given address's balance. This will decrease
* the circulating supply.
* @param account The address to burn the tokens from.
* @param amount The amount of tokens to burn.
*/
function burn(
address account,
// The following functions are overrides required by Solidity.
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) public onlyFromNamed("proto_broker") {
_burn(account, amount);
emit Burn(account, amount);
) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {
super._afterTokenTransfer(from, to, amount);
}

function _mint(address account, uint256 amount) internal override {
ERC20Upgradeable._mint(account, amount);
function _mint(
address to,
uint256 amount
) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {
super._mint(to, amount);

// TODO: do we need the following check at all?
if (totalSupply() > type(uint64).max) revert TKO_MINT_DISALLOWED();
emit Mint(to, amount);
}

function _burn(
address from,
uint256 amount
) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) {
super._burn(from, amount);
emit Burn(from, amount);
}
}

contract ProxiedTaikoToken is Proxied, TaikoToken {}
4 changes: 4 additions & 0 deletions packages/protocol/contracts/L2/TaikoL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
pragma solidity ^0.8.18;

import {EssentialContract} from "../common/EssentialContract.sol";
import {Proxied} from "../common/Proxied.sol";
import {ICrossChainSync} from "../common/ICrossChainSync.sol";
import {LibL2Consts} from "./LibL2Consts.sol";
import {LibMath} from "../libs/LibMath.sol";
Expand All @@ -16,6 +17,7 @@ import {
SafeCastUpgradeable
} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";

/// @custom:security-contact hello@taiko.xyz
contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync {
using SafeCastUpgradeable for uint256;
using LibMath for uint256;
Expand Down Expand Up @@ -308,3 +310,5 @@ contract TaikoL2 is EssentialContract, TaikoL2Signer, ICrossChainSync {
}
}
}

contract ProxiedTaikoL2 is Proxied, TaikoL2 {}
4 changes: 4 additions & 0 deletions packages/protocol/contracts/bridge/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pragma solidity ^0.8.18;

import {AddressResolver} from "../common/AddressResolver.sol";
import {EssentialContract} from "../common/EssentialContract.sol";
import {Proxied} from "../common/Proxied.sol";
import {IBridge} from "./IBridge.sol";
import {BridgeErrors} from "./BridgeErrors.sol";
import {LibBridgeData} from "./libs/LibBridgeData.sol";
Expand All @@ -21,6 +22,7 @@ import {LibBridgeStatus} from "./libs/LibBridgeStatus.sol";
* Bridge contract which is deployed on both L1 and L2. Mostly a thin wrapper
* which calls the library implementations. See _IBridge_ for more details.
* @dev The code hash for the same address on L1 and L2 may be different.
* @custom:security-contact hello@taiko.xyz
*/
contract Bridge is EssentialContract, IBridge, BridgeErrors {
using LibBridgeData for Message;
Expand Down Expand Up @@ -184,3 +186,5 @@ contract Bridge is EssentialContract, IBridge, BridgeErrors {
return LibBridgeStatus.getMessageStatusSlot(msgHash);
}
}

contract ProxiedBridge is Proxied, Bridge {}
29 changes: 20 additions & 9 deletions packages/protocol/contracts/bridge/BridgedERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@
pragma solidity ^0.8.18;

import {
IERC20Upgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
IERC20Upgradeable,
ERC20Upgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
// solhint-disable-next-line max-line-length
import {
IERC20MetadataUpgradeable
} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";

import {EssentialContract} from "../common/EssentialContract.sol";
import {ERC20Upgradeable} from "../thirdparty/ERC20Upgradeable.sol";
import {Proxied} from "../common/Proxied.sol";
import {BridgeErrors} from "./BridgeErrors.sol";

/// @custom:security-contact hello@taiko.xyz
contract BridgedERC20 is
EssentialContract,
IERC20Upgradeable,
Expand All @@ -27,7 +29,8 @@ contract BridgedERC20 is
{
address public srcToken;
uint256 public srcChainId;
uint256[48] private __gap;
uint8 private srcDecimals;
uint256[47] private __gap;

event BridgeMint(address indexed account, uint256 amount);
event BridgeBurn(address indexed account, uint256 amount);
Expand All @@ -53,13 +56,10 @@ contract BridgedERC20 is
revert B_INIT_PARAM_ERROR();
}
EssentialContract._init(_addressManager);
ERC20Upgradeable.__ERC20_init({
name_: _name,
symbol_: _symbol,
decimals_: _decimals
});
ERC20Upgradeable.__ERC20_init({name_: _name, symbol_: _symbol});
srcToken = _srcToken;
srcChainId = _srcChainId;
srcDecimals = _decimals;
}

/// @dev only a TokenVault can call this function
Expand Down Expand Up @@ -106,9 +106,20 @@ contract BridgedERC20 is
return ERC20Upgradeable.transferFrom(from, to, amount);
}

function decimals()
public
view
override(ERC20Upgradeable, IERC20MetadataUpgradeable)
returns (uint8)
{
return srcDecimals;
}

/// @dev returns the srcToken being bridged and the srcChainId
// of the tokens being bridged
function source() public view returns (address, uint256) {
return (srcToken, srcChainId);
}
}

contract ProxiedBridgedERC20 is Proxied, BridgedERC20 {}
4 changes: 4 additions & 0 deletions packages/protocol/contracts/bridge/EtherVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import {
} from "@openzeppelin/contracts-upgradeable/utils/Create2Upgradeable.sol";

import {EssentialContract} from "../common/EssentialContract.sol";
import {Proxied} from "../common/Proxied.sol";
import {LibAddress} from "../libs/LibAddress.sol";
import {BridgeErrors} from "./BridgeErrors.sol";

/**
* @custom:security-contact hello@taiko.xyz
* EtherVault is a special vault contract that:
* - Is initialized with 2^128 Ether.
* - Allows the contract owner to authorize addresses.
Expand Down Expand Up @@ -120,3 +122,5 @@ contract EtherVault is EssentialContract, BridgeErrors {
return _authorizedAddrs[addr];
}
}

contract ProxiedEtherVault is Proxied, EtherVault {}
Loading