Contract Address Details

0x89dafE43083bEb3296373Aa8deB7f5bA354AD7cD

Contract Name
EAssetToken_3
Creator
0x30e081–55b5f1 at 0x7e258b–a2f055
Balance
0.00 NRG
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
1107525
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
EAssetToken_3




Optimization enabled
true
Compiler version
v0.5.16+commit.9c3226ce




Optimization runs
200
EVM Version
petersburg




Verified at
2021-09-25 18:36:56.786237Z

Constructor Arguments

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030500000000000000000000000079f10487a8c0ed4e09045841160d01a7ecb9624400000000000000000000000030e081eb19625f4de1cae76d7dd1ac9bcd55b5f100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000f43657274694b204020456e657267690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000343544b0000000000000000000000000000000000000000000000000000000000

Arg [0] (address) : 0x0000000000000000000000000000000000000000
Arg [1] (address) : 0x0000000000000000000000000000000000000305
Arg [2] (address) : 0x79f10487a8c0ed4e09045841160d01a7ecb96244
Arg [3] (address) : 0x30e081eb19625f4de1cae76d7dd1ac9bcd55b5f1
Arg [4] (string) : CertiK @ Energi
Arg [5] (string) : CTK
Arg [6] (uint8) : 18

              

Contract source code

pragma solidity 0.5.16;
// File: interfaces/IGovernedContract.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Genesis version of GovernedContract interface.
*
* Base Consensus interface for upgradable contracts.
* Unlike common approach, the implementation is NOT expected to be
* called through delegatecall() to minimize risks of shared storage.
*
* NOTE: it MUST NOT change after blockchain launch!
*/
interface IGovernedContract {
// Return actual proxy address for secure validation
function proxy() external returns(address);
// It must check that the caller is the proxy
// and copy all required data from the old address.
function migrate(IGovernedContract _oldImpl) external;
// It must check that the caller is the proxy
// and self destruct to the new address.
function destroy(IGovernedContract _newImpl) external;
// function () external payable; // This line (from original Energi IGovernedContract) is commented because it
// makes truffle migrations fail
}
// File: StorageBase.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Base for contract storage (SC-14).
*
* NOTE: it MUST NOT change after blockchain launch!
*/
contract StorageBase {
address payable internal owner;
modifier requireOwner {
require(msg.sender == address(owner), "Not owner!");
_;
}
constructor() public {
owner = msg.sender;
}
function setOwner(IGovernedContract _newOwner) external requireOwner {
owner = address(uint160(address(_newOwner)));
}
function kill() external requireOwner {
selfdestruct(msg.sender);
}
}
// File: Context.sol
// Copyright (C) 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _txOrigin() internal view returns (address payable) {
return tx.origin;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: interfaces/IGovernedERC20.sol
// Copyright (C) 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IGovernedERC20 {
function governedERC20Proxy() external view returns(address _governedERC20Proxy);
function erc20Storage() external view returns(address _erc20Storage);
function name() external view returns(string memory _name);
function symbol() external view returns(string memory _symbol);
function decimals() external view returns(uint8 _decimals);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function transfer(address sender, address recipient, uint256 amount) external returns (bool);
function approve(address owner, address spender, uint256 amount) external returns (bool);
function transferFrom(address spender, address sender, address recipient, uint256 amount) external returns (bool);
function increaseAllowance(address sender, address spender, uint256 addedValue) external returns (bool);
function decreaseAllowance(address sender, address spender, uint256 subtractedValue) external returns (bool);
}
// File: interfaces/IGovernedERC20Storage.sol
// Copyright (C) 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
interface IGovernedERC20Storage {
function setBalance(address _owner, uint256 _amount) external;
function setAllowance(address _owner, address _spender, uint256 _amount) external;
function setTotalSupply(uint256 _amount) external;
function getBalance(address _account) external view returns(uint256 balance);
function getAllowance(address _owner, address _spender) external view returns(uint256 allowance);
function getTotalSupply() external view returns(uint256 totalSupply);
}
// File: libraries/SafeMath.sol
// Copyright (C) 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// File: GovernedERC20.sol
// Copyright (C) 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/**
* Permanent storage of GovernedERC20 data.
*/
contract GovernedERC20Storage is StorageBase, IGovernedERC20Storage {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
function setBalance(address _owner, uint256 _amount) external requireOwner {
_balances[_owner] = _amount;
}
function setAllowance(address _owner, address _spender, uint256 _amount) external requireOwner {
_allowances[_owner][_spender] = _amount;
}
function setTotalSupply(uint256 _amount) external requireOwner {
_totalSupply = _amount;
}
function getBalance(address _account) external view returns(uint256 balance) {
balance = _balances[_account];
}
function getAllowance(address _owner, address _spender) external view returns(uint256 allowance) {
allowance = _allowances[_owner][_spender];
}
function getTotalSupply() external view returns(uint256 totalSupply){
totalSupply = _totalSupply;
}
}
contract GovernedERC20 is Context, IGovernedERC20 {
using SafeMath for uint256;
// Data for migration
//---------------------------------
GovernedERC20Storage public erc20Storage;
//---------------------------------
address public governedERC20Proxy;
modifier onlyProxy {
require(_msgSender() == governedERC20Proxy, 'EAssetToken: FORBIDDEN - Not proxy!');
_;
}
constructor() public {
erc20Storage = new GovernedERC20Storage();
}
function setProxy(address _proxy) internal {
governedERC20Proxy = _proxy;
}
// IGovernedContract
//---------------------------------
// This function would be called by GovernedProxy on an old implementation to be replaced by a new one
function _destroyERC20(IGovernedContract _newImpl) internal {
erc20Storage.setOwner(_newImpl);
}
//---------------------------------
// ERC20
//---------------------------------
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() external view returns (uint256) {
return erc20Storage.getTotalSupply();
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) external view returns (uint256) {
return erc20Storage.getBalance(account);
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) external view returns (uint256) {
return erc20Storage.getAllowance(owner, spender);
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address sender, address recipient, uint256 amount) external onlyProxy returns (bool) {
_transfer(sender, recipient, amount);
return true;
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address owner, address spender, uint256 amount) external onlyProxy returns (bool) {
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20};
*
* Requirements:
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for `sender`'s tokens of at least
* `amount`.
*/
function transferFrom(address spender, address sender, address recipient, uint256 amount) external onlyProxy returns (bool) {
_transfer(sender, recipient, amount);
uint approveAmount = erc20Storage.getAllowance(sender, spender).sub(amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, spender, approveAmount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address owner, address spender, uint256 addedValue) external onlyProxy returns (bool) {
uint approveAmount = erc20Storage.getAllowance(owner, spender).add(addedValue);
_approve(owner, spender, approveAmount);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address owner, address spender, uint256 subtractedValue) external onlyProxy returns (bool) {
uint approveAmount = erc20Storage.getAllowance(owner, spender).sub(subtractedValue, "ERC20: decreased allowance below zero");
_approve(owner, spender, approveAmount);
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
erc20Storage.setBalance(sender, erc20Storage.getBalance(sender).sub(amount, "ERC20: transfer amount exceeds balance"));
erc20Storage.setBalance(recipient, erc20Storage.getBalance(recipient).add(amount));
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
erc20Storage.setTotalSupply(erc20Storage.getTotalSupply().add(amount));
erc20Storage.setBalance(account, erc20Storage.getBalance(account).add(amount));
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
erc20Storage.setBalance(account, erc20Storage.getBalance(account).sub(amount, "ERC20: burn amount exceeds balance"));
erc20Storage.setTotalSupply(erc20Storage.getTotalSupply().sub(amount));
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
*
* This is internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
erc20Storage.setAllowance(owner, spender, amount);
}
}
// File: interfaces/IProposal.sol
// Copyright 2019 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface IProposal {
function parent() external view returns(address);
function created_block() external view returns(uint);
function deadline() external view returns(uint);
function fee_payer() external view returns(address payable);
function fee_amount() external view returns(uint);
function accepted_weight() external view returns(uint);
function rejected_weight() external view returns(uint);
function total_weight() external view returns(uint);
function quorum_weight() external view returns(uint);
function isFinished() external view returns(bool);
function isAccepted() external view returns(bool);
function withdraw() external;
function destroy() external;
function collect() external;
function voteAccept() external;
function voteReject() external;
function setFee() external payable;
function canVote(address owner) external view returns(bool);
}
// File: interfaces/IUpgradeProposal.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Interface of UpgradeProposal
*/
contract IUpgradeProposal is IProposal {
function impl() external view returns(IGovernedContract);
}
// File: interfaces/IGovernedProxy.sol
// Copyright 2019 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
//pragma experimental SMTChecker;
/**
* Genesis version of IGovernedProxy interface.
*
* Base Consensus interface for upgradable contracts proxy.
* Unlike common approach, the implementation is NOT expected to be
* called through delegatecall() to minimize risks of shared storage.
*
* NOTE: it MUST NOT change after blockchain launch!
*/
interface IGovernedProxy {
event UpgradeProposal(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
event Upgraded(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
function impl() external view returns(IGovernedContract);
function proposeUpgrade(IGovernedContract _newImpl, uint _period)
external payable returns(IUpgradeProposal);
function upgrade(IUpgradeProposal _proposal) external;
function upgradeProposalImpl(IUpgradeProposal _proposal) external view returns(IGovernedContract new_impl);
function listUpgradeProposals() external view returns(IUpgradeProposal[] memory proposals);
function collectUpgradeProposal(IUpgradeProposal _proposal) external;
function () external payable;
}
// File: interfaces/IEAssetToken_3.sol
// Copyright 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface IEAssetToken_3 {
function eAssetTokenStorage() external view returns(address _eAssetTokenStorage);
function name() external view returns(string memory _name);
function symbol() external view returns(string memory _symbol);
function decimals() external view returns(uint8 _decimals);
function owner() external view returns(address _owner);
function minter() external view returns(address _minter);
function setName(string calldata _name) external;
function setSymbol(string calldata _name) external;
function setDecimals(uint8 _decimals) external;
function setOwner(address _eAssetTokenOwner) external;
function setMinter(address _eAssetTokenMinter) external;
function mint(address recipient, uint amount) external;
function burn(address recipient, uint amount) external;
}
// File: interfaces/IEAssetTokenStorage_3.sol
// Copyright 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface IEAssetTokenStorage_3 {
function getName() external view returns(string memory _name);
function getSymbol() external view returns(string memory _symbol);
function getDecimals() external view returns(uint8 _decimals);
function getEAssetTokenOwner() external view returns(address _owner);
function getEAssetTokenMinter() external view returns(address _minter);
function setName(string calldata _name) external;
function setSymbol(string calldata _symbol) external;
function setDecimals(uint8 _decimals) external;
function setEAssetTokenOwner(address _eAssetTokenOwner) external;
function setEAssetTokenMinter(address _eAssetTokenMinter) external;
}
// File: GovernedContract.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Genesis version of GovernedContract common base.
*
* Base Consensus interface for upgradable contracts.
* Unlike common approach, the implementation is NOT expected to be
* called through delegatecall() to minimize risks of shared storage.
*
* NOTE: it MUST NOT change after blockchain launch!
*/
contract GovernedContract is IGovernedContract {
address public proxy;
constructor(address _proxy) public {
proxy = _proxy;
}
modifier requireProxy {
require(msg.sender == proxy, "EAssetToken: FORBIDDEN - Not proxy!");
_;
}
function migrate(IGovernedContract _oldImpl) external requireProxy {
_migrate(_oldImpl);
}
function destroy(IGovernedContract _newImpl) external requireProxy {
_destroy(_newImpl);
selfdestruct(address(uint160(address(_newImpl))));
}
// solium-disable-next-line no-empty-blocks
function _migrate(IGovernedContract) internal {}
// solium-disable-next-line no-empty-blocks
function _destroy(IGovernedContract) internal {}
function _callerAddress()
internal view
returns (address payable)
{
if (msg.sender == proxy) {
// This is guarantee of the GovernedProxy
// solium-disable-next-line security/no-tx-origin
return tx.origin;
} else {
return msg.sender;
}
}
}
// File: interfaces/IGovernedERC20Proxy.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Genesis version of IGovernedProxy interface.
*
* Base Consensus interface for upgradable contracts proxy.
* Unlike common approach, the implementation is NOT expected to be
* called through delegatecall() to minimize risks of shared storage.
*
* NOTE: it MUST NOT change after blockchain launch!
*/
interface IGovernedERC20Proxy {
event UpgradeProposal(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
event Upgraded(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
// ERC20 standard interface
function name() external view returns(string memory _name);
function symbol() external view returns(string memory _symbol);
function decimals() external view returns(uint _decimals);
function balanceOf(address account) external view returns(uint _balance);
function allowance(address owner, address spender) external view returns(uint _allowance);
function totalSupply() external view returns(uint _totalSupply);
function approve(address spender, uint value) external returns (bool result);
function transfer(address to, uint value) external returns (bool result);
function transferFrom(address from, address to, uint value) external returns (bool result);
function increaseAllowance(address spender, uint256 addedValue) external returns (bool result);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool result);
// Energi governance interface
function impl() external view returns(IGovernedContract);
function proposeUpgrade(IGovernedContract _newImpl, uint _period) external payable returns(IUpgradeProposal);
function upgrade(IUpgradeProposal _proposal) external;
function upgradeProposalImpl(IUpgradeProposal _proposal) external view returns(IGovernedContract new_impl);
function listUpgradeProposals() external view returns(IUpgradeProposal[] memory proposals);
function collectUpgradeProposal(IUpgradeProposal _proposal) external;
function () external payable;
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed _owner, address indexed spender, uint256 value);
}
// File: interfaces/ISporkRegistry.sol
// Copyright 2019 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface ISporkRegistry {
function createUpgradeProposal(
IGovernedContract _impl,
uint _period,
address payable _fee_payer
)
external payable
returns (IUpgradeProposal);
function consensusGasLimits()
external view
returns(uint callGas, uint xferGas);
}
// File: NonReentrant.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* A little helper to protect contract from being re-entrant in state
* modifying functions.
*/
contract NonReentrant {
uint private entry_guard;
modifier noReentry {
require(entry_guard == 0, "Reentry");
entry_guard = 1;
_;
entry_guard = 0;
}
}
// File: interfaces/IOwnedERC20.sol
interface IOwnedERC20 {
function owner() external view returns(address _owner);
function mint(address recipient, uint amount) external;
function burn(address recipient, uint amount) external;
function setOwner(address _owner) external;
}
// File: GovernedERC20Proxy.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* SC-9: This contract has no chance of being updated. It must be stupid simple.
*
* If another upgrade logic is required in the future - it can be done as proxy stage II.
*/
contract GovernedERC20Proxy is IGovernedERC20Proxy, NonReentrant {
using SafeMath for uint;
IGovernedContract public impl;
IGovernedProxy public spork_proxy;
mapping(address => IGovernedContract) public upgrade_proposals;
IUpgradeProposal[] public upgrade_proposal_list;
modifier senderOrigin {
// Internal calls are expected to use impl directly.
// That's due to use of call() instead of delegatecall() on purpose.
// solium-disable-next-line security/no-tx-origin
require(tx.origin == msg.sender, "Only direct calls are allowed!");
_;
}
modifier onlyImpl {
require(msg.sender == address(impl), "Only calls from impl are allowed!");
_;
}
constructor(IGovernedContract _impl, IGovernedProxy _sporkProxy) public {
impl = _impl;
spork_proxy = _sporkProxy;
}
// ERC20 standard functions
function name() external view returns(string memory _name) {
_name = IGovernedERC20(address(uint160(address(impl)))).name();
}
function symbol() external view returns(string memory _symbol) {
_symbol = IGovernedERC20(address(uint160(address(impl)))).symbol();
}
function decimals() external view returns(uint _decimals) {
_decimals = IGovernedERC20(address(uint160(address(impl)))).decimals();
}
function balanceOf(address account) external view returns(uint _balance) {
_balance = IGovernedERC20(address(uint160(address(impl)))).balanceOf(account);
}
function allowance(address owner, address spender) external view returns(uint _allowance) {
_allowance = IGovernedERC20(address(uint160(address(impl)))).allowance(owner, spender);
}
function totalSupply() external view returns(uint _totalSupply) {
_totalSupply = IGovernedERC20(address(uint160(address(impl)))).totalSupply();
}
function approve(address spender, uint value) external returns (bool result) {
result = IGovernedERC20(address(uint160(address(impl)))).approve(msg.sender, spender, value);
emit Approval(msg.sender, spender, value);
}
function transfer(address to, uint value) external returns (bool result) {
result = IGovernedERC20(address(uint160(address(impl)))).transfer(msg.sender, to, value);
emit Transfer(msg.sender, to, value);
}
function transferFrom(address from, address to, uint value) external returns (bool result) {
result = IGovernedERC20(address(uint160(address(impl)))).transferFrom(msg.sender, from, to, value);
emit Transfer(from, to, value);
uint newApproveAmount = IGovernedERC20(address(uint160(address(impl)))).allowance(from, msg.sender);
emit Approval(from, msg.sender, newApproveAmount);
}
function increaseAllowance(address spender, uint256 addedValue) external returns (bool result) {
result = IGovernedERC20(address(uint160(address(impl)))).increaseAllowance(msg.sender, spender, addedValue);
uint newApproveAmount = IGovernedERC20(address(uint160(address(impl)))).allowance(msg.sender, spender);
emit Approval(msg.sender, spender, newApproveAmount);
}
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool result) {
result = IGovernedERC20(address(uint160(address(impl)))).decreaseAllowance(msg.sender, spender, subtractedValue);
uint newApproveAmount = IGovernedERC20(address(uint160(address(impl)))).allowance(msg.sender, spender);
emit Approval(msg.sender, spender, newApproveAmount);
}
// OwnedERC20 funtions
function mint(address recipient, uint amount) external {
IOwnedERC20(address(uint160(address(impl)))).mint(recipient, amount);
emit Transfer(address(0), recipient, amount);
}
function burn(address recipient, uint amount) external {
IOwnedERC20(address(uint160(address(impl)))).burn(recipient, amount);
emit Transfer(recipient, address(0), amount);
}
// Governance functions
/**
* Pre-create a new contract first.
* Then propose upgrade based on that.
*/
function proposeUpgrade(IGovernedContract _newImpl, uint _period)
external payable
senderOrigin
noReentry
returns(IUpgradeProposal)
{
require(_newImpl != impl, "Already active!");
require(_newImpl.proxy() == address(this), "Wrong proxy!");
ISporkRegistry spork_reg = ISporkRegistry(address(spork_proxy.impl()));
IUpgradeProposal proposal = spork_reg.createUpgradeProposal.value(msg.value)(_newImpl, _period, msg.sender);
upgrade_proposals[address(proposal)] = _newImpl;
upgrade_proposal_list.push(proposal);
emit UpgradeProposal(_newImpl, proposal);
return proposal;
}
/**
* Once proposal is accepted, anyone can activate that.
*/
function upgrade(IUpgradeProposal _proposal)
external
noReentry
{
IGovernedContract new_impl = upgrade_proposals[address(_proposal)];
require(new_impl != impl, "Already active!"); // in case it changes in the flight
require(address(new_impl) != address(0), "Not registered!");
require(_proposal.isAccepted(), "Not accepted!");
IGovernedContract old_impl = impl;
new_impl.migrate(old_impl);
impl = new_impl;
old_impl.destroy(new_impl);
// SECURITY: prevent downgrade attack
_cleanupProposal(_proposal);
// Return fee ASAP
_proposal.destroy();
emit Upgraded(new_impl, _proposal);
}
/**
* Map proposal to implementation
*/
function upgradeProposalImpl(IUpgradeProposal _proposal)
external view
returns(IGovernedContract new_impl)
{
new_impl = upgrade_proposals[address(_proposal)];
}
/**
* Lists all available upgrades
*/
function listUpgradeProposals()
external view
returns(IUpgradeProposal[] memory proposals)
{
uint len = upgrade_proposal_list.length;
proposals = new IUpgradeProposal[](len);
for (uint i = 0; i < len; ++i) {
proposals[i] = upgrade_proposal_list[i];
}
return proposals;
}
/**
* Once proposal is reject, anyone can start collect procedure.
*/
function collectUpgradeProposal(IUpgradeProposal _proposal)
external
noReentry
{
IGovernedContract new_impl = upgrade_proposals[address(_proposal)];
require(address(new_impl) != address(0), "Not registered!");
_proposal.collect();
delete upgrade_proposals[address(_proposal)];
_cleanupProposal(_proposal);
}
function _cleanupProposal(IUpgradeProposal _proposal) internal {
delete upgrade_proposals[address(_proposal)];
uint len = upgrade_proposal_list.length;
for (uint i = 0; i < len; ++i) {
if (upgrade_proposal_list[i] == _proposal) {
upgrade_proposal_list[i] = upgrade_proposal_list[len - 1];
upgrade_proposal_list.pop();
break;
}
}
}
/**
* Related to above
*/
function proxy() external view returns (address) {
return address(this);
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function migrate(IGovernedContract) external pure {
revert("Good try");
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function destroy(IGovernedContract) external pure {
revert("Good try");
}
/**
* Proxy all other calls to implementation.
*/
function ()
external payable
senderOrigin
{
// SECURITY: senderOrigin() modifier is mandatory
IGovernedContract impl_m = impl;
// solium-disable-next-line security/no-inline-assembly
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize)
let res := call(sub(gas, 10000), impl_m, callvalue, ptr, calldatasize, 0, 0)
// NOTE: returndatasize should allow repeatable calls
// what should save one opcode.
returndatacopy(ptr, 0, returndatasize)
switch res
case 0 {
revert(ptr, returndatasize)
}
default {
return(ptr, returndatasize)
}
}
}
}
// File: GovernedEAssetTokenAutoProxy.sol
// Copyright (C) 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
contract GovernedEAssetTokenAutoProxy is GovernedContract {
constructor (
address _proxy,
IGovernedProxy _sporkProxy,
IGovernedContract _impl
) public GovernedContract(_proxy) {
if(_proxy == address(0)){
_proxy = address(new GovernedERC20Proxy(_impl, _sporkProxy));
}
proxy = _proxy;
}
}
// File: eAssetToken_3.sol
// Copyright 2021 Energi Core
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Permanent storage of Masternode Token V1 data.
*/
contract EAssetTokenStorage_3 is StorageBase, IEAssetTokenStorage_3 {
address private eAssetTokenOwner; // can mint and burn
// can also set: name, symbol, decimals, new owner, and new minter
address private eAssetTokenMinter; // can mint and burn only
string private name;
string private symbol;
uint8 private decimals;
constructor(
address _eAssetTokenOwner,
address _eAssetTokenMinter,
string memory _name,
string memory _symbol,
uint8 _decimals
) public {
eAssetTokenOwner = _eAssetTokenOwner;
eAssetTokenMinter = _eAssetTokenMinter;
name = _name;
symbol = _symbol;
decimals = _decimals;
}
function getName() external view returns(string memory _name) {
_name = name;
}
function getSymbol() external view returns(string memory _symbol) {
_symbol = symbol;
}
function getDecimals() external view returns(uint8 _decimals) {
_decimals = decimals;
}
function getEAssetTokenOwner() external view returns(address _owner) {
_owner = eAssetTokenOwner;
}
function getEAssetTokenMinter() external view returns(address _minter) {
_minter = eAssetTokenMinter;
}
function setName(string calldata _name) external requireOwner {
name = _name;
}
function setSymbol(string calldata _symbol) external requireOwner {
symbol = _symbol;
}
function setDecimals(uint8 _decimals) external requireOwner {
decimals = _decimals;
}
function setEAssetTokenOwner(address _eAssetTokenOwner) external requireOwner {
eAssetTokenOwner = _eAssetTokenOwner;
}
function setEAssetTokenMinter(address _eAssetTokenMinter) external requireOwner {
eAssetTokenMinter = _eAssetTokenMinter;
}
}
contract EAssetToken_3 is GovernedEAssetTokenAutoProxy, GovernedERC20, IEAssetToken_3 {
// Data for migration
//---------------------------------
EAssetTokenStorage_3 public eAssetTokenStorage;
//---------------------------------
modifier onlyEAssetTokenOwner {
require(_txOrigin() == eAssetTokenStorage.getEAssetTokenOwner(), 'EAssetToken: FORBIDDEN');
_;
}
modifier onlyEAssetTokenOwnerOrMinter {
require(
_txOrigin() == eAssetTokenStorage.getEAssetTokenOwner()
|| _txOrigin() == eAssetTokenStorage.getEAssetTokenMinter(),
'EAssetToken: FORBIDDEN'
);
_;
}
constructor(
address _proxy, // If set to address(0), GovernedProxy will be deployed by GovernedContractAutoProxy
IGovernedProxy _sporkProxy,
address _eAssetTokenOwner,
address _eAssetTokenMinter,
string memory _name,
string memory _symbol,
uint8 _decimals
) public GovernedEAssetTokenAutoProxy(_proxy, _sporkProxy, this) {
eAssetTokenStorage = new EAssetTokenStorage_3(_eAssetTokenOwner, _eAssetTokenMinter, _name, _symbol, _decimals);
setProxy(proxy);
}
function name() external view returns(string memory _name) {
_name = eAssetTokenStorage.getName();
}
function symbol() external view returns(string memory _symbol) {
_symbol = eAssetTokenStorage.getSymbol();
}
function decimals() external view returns(uint8 _decimals) {
_decimals = eAssetTokenStorage.getDecimals();
}
function owner() external view returns(address _owner) {
_owner = eAssetTokenStorage.getEAssetTokenOwner();
}
function minter() external view returns(address _minter) {
_minter = eAssetTokenStorage.getEAssetTokenMinter();
}
function setName(string calldata _name) external onlyEAssetTokenOwner {
eAssetTokenStorage.setName(_name);
}
function setSymbol(string calldata _symbol) external onlyEAssetTokenOwner {
eAssetTokenStorage.setSymbol(_symbol);
}
function setDecimals(uint8 _decimals) external onlyEAssetTokenOwner {
eAssetTokenStorage.setDecimals(_decimals);
}
function setOwner(address _eAssetTokenOwner) external onlyEAssetTokenOwner {
eAssetTokenStorage.setEAssetTokenOwner(_eAssetTokenOwner);
}
function setMinter(address _eAssetTokenMinter) external onlyEAssetTokenOwner {
eAssetTokenStorage.setEAssetTokenMinter(_eAssetTokenMinter);
}
// IGovernedContract
//---------------------------------
function _destroy(IGovernedContract _newImpl) internal {
_destroyERC20(_newImpl);
eAssetTokenStorage.setOwner(_newImpl);
}
//---------------------------------
function mint(address recipient, uint amount) external onlyEAssetTokenOwnerOrMinter {
_mint(recipient, amount);
}
function burn(address recipient, uint amount) external onlyEAssetTokenOwnerOrMinter {
_burn(recipient, amount);
}
}

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[{"type":"address","name":"_proxy","internalType":"address"},{"type":"address","name":"_sporkProxy","internalType":"contract IGovernedProxy"},{"type":"address","name":"_eAssetTokenOwner","internalType":"address"},{"type":"address","name":"_eAssetTokenMinter","internalType":"address"},{"type":"string","name":"_name","internalType":"string"},{"type":"string","name":"_symbol","internalType":"string"},{"type":"uint8","name":"_decimals","internalType":"uint8"}]},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"burn","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":"_decimals","internalType":"uint8"}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"destroy","inputs":[{"type":"address","name":"_newImpl","internalType":"contract IGovernedContract"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract EAssetTokenStorage_3"}],"name":"eAssetTokenStorage","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract GovernedERC20Storage"}],"name":"erc20Storage","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governedERC20Proxy","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"migrate","inputs":[{"type":"address","name":"_oldImpl","internalType":"contract IGovernedContract"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"mint","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"_minter","internalType":"address"}],"name":"minter","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_name","internalType":"string"}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"_owner","internalType":"address"}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"proxy","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setDecimals","inputs":[{"type":"uint8","name":"_decimals","internalType":"uint8"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setMinter","inputs":[{"type":"address","name":"_eAssetTokenMinter","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setName","inputs":[{"type":"string","name":"_name","internalType":"string"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setOwner","inputs":[{"type":"address","name":"_eAssetTokenOwner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setSymbol","inputs":[{"type":"string","name":"_symbol","internalType":"string"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_symbol","internalType":"string"}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b506004361061018d5760003560e01c80638da5cb5b116100de578063ce5494bb11610097578063e1f21c6711610071578063e1f21c671461059d578063ec556889146105d3578063ec949758146105db578063fca3b5aa146105e35761018d565b8063ce5494bb14610513578063d73b1dc914610539578063dd62ed3e1461056f5761018d565b80638da5cb5b146103c157806395d89b41146103c95780639dc29fac146103d1578063b84c8246146103fd578063beabacc81461046d578063c47f0027146104a35761018d565b806321825e671161014b5780634bc597b9116101255780634bc597b91461033d5780636c43a2ca1461034557806370a082311461037b5780637a1395aa146103a15761018d565b806321825e67146102eb578063313ce567146102f357806340c10f19146103115761018d565b8062f55d9d1461019257806306fdde03146101ba578063075461721461023757806313af40351461025b57806315dacbea1461028157806318160ddd146102d1575b600080fd5b6101b8600480360360208110156101a857600080fd5b50356001600160a01b0316610609565b005b6101c2610667565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101fc5781810151838201526020016101e4565b50505050905090810190601f1680156102295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61023f61079e565b604080516001600160a01b039092168252519081900360200190f35b6101b86004803603602081101561027157600080fd5b50356001600160a01b0316610814565b6102bd6004803603608081101561029757600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135610951565b604080519115158252519081900360200190f35b6102d9610a7e565b60408051918252519081900360200190f35b61023f610ac3565b6102fb610ad2565b6040805160ff9092168252519081900360200190f35b6101b86004803603604081101561032757600080fd5b506001600160a01b038135169060200135610b17565b61023f610c95565b6102bd6004803603606081101561035b57600080fd5b506001600160a01b03813581169160208101359091169060400135610ca4565b6102d96004803603602081101561039157600080fd5b50356001600160a01b0316610dad565b6101b8600480360360208110156103b757600080fd5b503560ff16610e30565b61023f610f53565b6101c2610f98565b6101b8600480360360408110156103e757600080fd5b506001600160a01b038135169060200135610fdd565b6101b86004803603602081101561041357600080fd5b81019060208101813564010000000081111561042e57600080fd5b82018360208201111561044057600080fd5b8035906020019184600183028401116401000000008311171561046257600080fd5b509092509050611157565b6102bd6004803603606081101561048357600080fd5b506001600160a01b038135811691602081013590911690604001356112be565b6101b8600480360360208110156104b957600080fd5b8101906020810181356401000000008111156104d457600080fd5b8201836020820111156104e657600080fd5b8035906020019184600183028401116401000000008311171561050857600080fd5b50909250905061132f565b6101b86004803603602081101561052957600080fd5b50356001600160a01b031661147a565b6102bd6004803603606081101561054f57600080fd5b506001600160a01b038135811691602081013590911690604001356114cb565b6102d96004803603604081101561058557600080fd5b506001600160a01b038135811691602001351661159b565b6102bd600480360360608110156105b357600080fd5b506001600160a01b03813581169160208101359091169060400135611627565b61023f61168e565b61023f61169d565b6101b8600480360360208110156105f957600080fd5b50356001600160a01b03166116ac565b6000546001600160a01b031633146106525760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b61065b816117ce565b806001600160a01b0316ff5b600354604080516305f5f79f60e21b815290516060926001600160a01b0316916317d7de7c916004808301926000929190829003018186803b1580156106ac57600080fd5b505afa1580156106c0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156106e957600080fd5b810190808051604051939291908464010000000082111561070957600080fd5b90830190602082018581111561071e57600080fd5b825164010000000081118282018810171561073857600080fd5b82525081516020918201929091019080838360005b8381101561076557818101518382015260200161074d565b50505050905090810190601f1680156107925780820380516001836020036101000a031916815260200191505b50604052505050905090565b600354604080516301ea063d60e31b815290516000926001600160a01b031691630f5031e8916004808301926020929190829003018186803b1580156107e357600080fd5b505afa1580156107f7573d6000803e3d6000fd5b505050506040513d602081101561080d57600080fd5b5051919050565b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b15801561086257600080fd5b505afa158015610876573d6000803e3d6000fd5b505050506040513d602081101561088c57600080fd5b50516001600160a01b031661089f611825565b6001600160a01b0316146108e8576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b6003546040805163dc1085ff60e01b81526001600160a01b0384811660048301529151919092169163dc1085ff91602480830192600092919082900301818387803b15801561093657600080fd5b505af115801561094a573d6000803e3d6000fd5b5050505050565b6002546000906001600160a01b0316610968611829565b6001600160a01b0316146109ad5760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b6109b884848461182d565b6000610a65836040518060600160405280602881526020016121426028913960015460408051630af4187d60e01b81526001600160a01b038b811660048301528c8116602483015291519190921691630af4187d916044808301926020929190829003018186803b158015610a2c57600080fd5b505afa158015610a40573d6000803e3d6000fd5b505050506040513d6020811015610a5657600080fd5b5051919063ffffffff611a6a16565b9050610a72858783611b01565b50600195945050505050565b600154604080516362720d9160e11b815290516000926001600160a01b03169163c4e41b22916004808301926020929190829003018186803b1580156107e357600080fd5b6002546001600160a01b031681565b60035460408051633c05076160e21b815290516000926001600160a01b03169163f0141d84916004808301926020929190829003018186803b1580156107e357600080fd5b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b158015610b6557600080fd5b505afa158015610b79573d6000803e3d6000fd5b505050506040513d6020811015610b8f57600080fd5b50516001600160a01b0316610ba2611825565b6001600160a01b03161480610c485750600360009054906101000a90046001600160a01b03166001600160a01b0316630f5031e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d6020811015610c2a57600080fd5b50516001600160a01b0316610c3d611825565b6001600160a01b0316145b610c87576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b610c918282611be8565b5050565b6001546001600160a01b031681565b6002546000906001600160a01b0316610cbb611829565b6001600160a01b031614610d005760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b60015460408051630af4187d60e01b81526001600160a01b03878116600483015286811660248301529151600093610d95938793911691630af4187d91604480820192602092909190829003018186803b158015610d5d57600080fd5b505afa158015610d71573d6000803e3d6000fd5b505050506040513d6020811015610d8757600080fd5b50519063ffffffff611d9116565b9050610da2858583611b01565b506001949350505050565b6001546040805163f8b2cb4f60e01b81526001600160a01b0384811660048301529151600093929092169163f8b2cb4f91602480820192602092909190829003018186803b158015610dfe57600080fd5b505afa158015610e12573d6000803e3d6000fd5b505050506040513d6020811015610e2857600080fd5b505192915050565b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b158015610e7e57600080fd5b505afa158015610e92573d6000803e3d6000fd5b505050506040513d6020811015610ea857600080fd5b50516001600160a01b0316610ebb611825565b6001600160a01b031614610f04576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b60035460408051633d09cad560e11b815260ff8416600482015290516001600160a01b0390921691637a1395aa9160248082019260009290919082900301818387803b15801561093657600080fd5b6003546040805163fc8a8cc160e01b815290516000926001600160a01b03169163fc8a8cc1916004808301926020929190829003018186803b1580156107e357600080fd5b60035460408051631507040160e01b815290516060926001600160a01b0316916315070401916004808301926000929190829003018186803b1580156106ac57600080fd5b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b15801561102b57600080fd5b505afa15801561103f573d6000803e3d6000fd5b505050506040513d602081101561105557600080fd5b50516001600160a01b0316611068611825565b6001600160a01b0316148061110e5750600360009054906101000a90046001600160a01b03166001600160a01b0316630f5031e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156110c657600080fd5b505afa1580156110da573d6000803e3d6000fd5b505050506040513d60208110156110f057600080fd5b50516001600160a01b0316611103611825565b6001600160a01b0316145b61114d576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b610c918282611df2565b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b50516001600160a01b03166111e2611825565b6001600160a01b03161461122b576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b600354604051635c26412360e11b8152602060048201908152602482018490526001600160a01b039092169163b84c824691859185918190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b1580156112a257600080fd5b505af11580156112b6573d6000803e3d6000fd5b505050505050565b6002546000906001600160a01b03166112d5611829565b6001600160a01b03161461131a5760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b61132584848461182d565b5060019392505050565b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b15801561137d57600080fd5b505afa158015611391573d6000803e3d6000fd5b505050506040513d60208110156113a757600080fd5b50516001600160a01b03166113ba611825565b6001600160a01b031614611403576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b60035460405163c47f002760e01b8152602060048201908152602482018490526001600160a01b039092169163c47f002791859185918190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b1580156112a257600080fd5b6000546001600160a01b031633146114c35760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b6114c8815b50565b6002546000906001600160a01b03166114e2611829565b6001600160a01b0316146115275760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b6000610d95836040518060600160405280602581526020016121d46025913960015460408051630af4187d60e01b81526001600160a01b038b811660048301528a8116602483015291519190921691630af4187d916044808301926020929190829003018186803b158015610a2c57600080fd5b60015460408051630af4187d60e01b81526001600160a01b038581166004830152848116602483015291516000939290921691630af4187d91604480820192602092909190829003018186803b1580156115f457600080fd5b505afa158015611608573d6000803e3d6000fd5b505050506040513d602081101561161e57600080fd5b50519392505050565b6002546000906001600160a01b031661163e611829565b6001600160a01b0316146116835760405162461bcd60e51b81526004018080602001828103825260238152602001806120d96023913960400191505060405180910390fd5b611325848484611b01565b6000546001600160a01b031681565b6003546001600160a01b031681565b600360009054906101000a90046001600160a01b03166001600160a01b031663fc8a8cc16040518163ffffffff1660e01b815260040160206040518083038186803b1580156116fa57600080fd5b505afa15801561170e573d6000803e3d6000fd5b505050506040513d602081101561172457600080fd5b50516001600160a01b0316611737611825565b6001600160a01b031614611780576040805162461bcd60e51b815260206004820152601660248201526000805160206120fc833981519152604482015290519081900360640190fd5b6003546040805163c2bd4b5f60e01b81526001600160a01b0384811660048301529151919092169163c2bd4b5f91602480830192600092919082900301818387803b15801561093657600080fd5b6117d781611fe1565b600354604080516313af403560e01b81526001600160a01b038481166004830152915191909216916313af403591602480830192600092919082900301818387803b15801561093657600080fd5b3290565b3390565b6001600160a01b0383166118725760405162461bcd60e51b815260040180806020018281038252602581526020018061218b6025913960400191505060405180910390fd5b6001600160a01b0382166118b75760405162461bcd60e51b81526004018080602001828103825260238152602001806120726023913960400191505060405180910390fd5b600154604080516060810190915260268082526001600160a01b039092169163e30443bc91869161193991869161211c60208301396001546040805163f8b2cb4f60e01b81526001600160a01b038c811660048301529151919092169163f8b2cb4f916024808301926020929190829003018186803b158015610a2c57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561198857600080fd5b505af115801561199c573d6000803e3d6000fd5b50506001546040805163f8b2cb4f60e01b81526001600160a01b038781166004830152915191909216935063e30443bc925085916119fe918691869163f8b2cb4f91602480820192602092909190829003018186803b158015610d5d57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a4d57600080fd5b505af1158015611a61573d6000803e3d6000fd5b50505050505050565b60008184841115611af95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611abe578181015183820152602001611aa6565b50505050905090810190601f168015611aeb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b038316611b465760405162461bcd60e51b81526004018080602001828103825260248152602001806121b06024913960400191505060405180910390fd5b6001600160a01b038216611b8b5760405162461bcd60e51b81526004018080602001828103825260228152602001806120b76022913960400191505060405180910390fd5b60015460408051633691826360e21b81526001600160a01b0386811660048301528581166024830152604482018590529151919092169163da46098c91606480830192600092919082900301818387803b158015611a4d57600080fd5b6001600160a01b038216611c43576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600154604080516362720d9160e11b815290516001600160a01b039092169163f7ea7a3d91611c96918591859163c4e41b2291600480820192602092909190829003018186803b158015610d5d57600080fd5b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611ccc57600080fd5b505af1158015611ce0573d6000803e3d6000fd5b50506001546040805163f8b2cb4f60e01b81526001600160a01b038781166004830152915191909216935063e30443bc92508591611d42918691869163f8b2cb4f91602480820192602092909190829003018186803b158015610d5d57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156112a257600080fd5b600082820183811015611deb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216611e375760405162461bcd60e51b815260040180806020018281038252602181526020018061216a6021913960400191505060405180910390fd5b600154604080516060810190915260228082526001600160a01b039092169163e30443bc918591611eb991869161209560208301396001546040805163f8b2cb4f60e01b81526001600160a01b038b811660048301529151919092169163f8b2cb4f916024808301926020929190829003018186803b158015610a2c57600080fd5b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611f0857600080fd5b505af1158015611f1c573d6000803e3d6000fd5b5050600154604080516362720d9160e11b815290516001600160a01b03909216935063f7ea7a3d9250611fab918591859163c4e41b2291600480820192602092909190829003018186803b158015611f7357600080fd5b505afa158015611f87573d6000803e3d6000fd5b505050506040513d6020811015611f9d57600080fd5b50519063ffffffff61202f16565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156112a257600080fd5b600154604080516313af403560e01b81526001600160a01b038481166004830152915191909216916313af403591602480830192600092919082900301818387803b15801561093657600080fd5b6000611deb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611a6a56fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f2061646472657373454173736574546f6b656e3a20464f5242494444454e202d204e6f742070726f787921454173736574546f6b656e3a20464f5242494444454e0000000000000000000045524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a72315820fc49b74cbe28206bfe60ffc62d908288b364ff06c34f0d54e5b36f06c862dbac64736f6c63430005100032