Skip to content

Commit

Permalink
feat(protocol): add TaikoGovernor and improve TaikoToken (#13711)
Browse files Browse the repository at this point in the history
Co-authored-by: David <david@taiko.xyz>
  • Loading branch information
dantaik and davidtaikocha committed May 8, 2023
1 parent bd256e2 commit ad75cd5
Show file tree
Hide file tree
Showing 25 changed files with 597 additions and 579 deletions.
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

0 comments on commit ad75cd5

Please sign in to comment.