文件 1 的 1:RenERC20LogicV1.sol
pragma solidity 0.5.16;
contract Initializable {
bool private initialized;
bool private initializing;
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
function isConstructor() private view returns (bool) {
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
uint256[50] private ______gap;
}
contract Context is Initializable {
constructor () internal { }
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
contract Ownable is Initializable, Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function initialize(address sender) public initializer {
_owner = sender;
emit OwnershipTransferred(address(0), _owner);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[50] private ______gap;
}
contract Proxy {
function () payable external {
_fallback();
}
function _implementation() internal view returns (address);
function _delegate(address implementation) internal {
assembly {
calldatacopy(0, 0, calldatasize)
let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
returndatacopy(0, 0, returndatasize)
switch result
case 0 { revert(0, returndatasize) }
default { return(0, returndatasize) }
}
}
function _willFallback() internal {
}
function _fallback() internal {
_willFallback();
_delegate(_implementation());
}
}
library OpenZeppelinUpgradesAddress {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
}
contract BaseUpgradeabilityProxy is Proxy {
event Upgraded(address indexed implementation);
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
function _implementation() internal view returns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
impl := sload(slot)
}
}
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
function _setImplementation(address newImplementation) internal {
require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, newImplementation)
}
}
}
contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
constructor(address _logic, bytes memory _data) public payable {
assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
_setImplementation(_logic);
if(_data.length > 0) {
(bool success,) = _logic.delegatecall(_data);
require(success);
}
}
}
contract BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
event AdminChanged(address previousAdmin, address newAdmin);
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
modifier ifAdmin() {
if (msg.sender == _admin()) {
_;
} else {
_fallback();
}
}
function admin() external ifAdmin returns (address) {
return _admin();
}
function implementation() external ifAdmin returns (address) {
return _implementation();
}
function changeAdmin(address newAdmin) external ifAdmin {
require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address");
emit AdminChanged(_admin(), newAdmin);
_setAdmin(newAdmin);
}
function upgradeTo(address newImplementation) external ifAdmin {
_upgradeTo(newImplementation);
}
function upgradeToAndCall(address newImplementation, bytes calldata data) payable external ifAdmin {
_upgradeTo(newImplementation);
(bool success,) = newImplementation.delegatecall(data);
require(success);
}
function _admin() internal view returns (address adm) {
bytes32 slot = ADMIN_SLOT;
assembly {
adm := sload(slot)
}
}
function _setAdmin(address newAdmin) internal {
bytes32 slot = ADMIN_SLOT;
assembly {
sstore(slot, newAdmin)
}
}
function _willFallback() internal {
require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin");
super._willFallback();
}
}
contract InitializableUpgradeabilityProxy is BaseUpgradeabilityProxy {
function initialize(address _logic, bytes memory _data) public payable {
require(_implementation() == address(0));
assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
_setImplementation(_logic);
if(_data.length > 0) {
(bool success,) = _logic.delegatecall(_data);
require(success);
}
}
}
contract InitializableAdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, InitializableUpgradeabilityProxy {
function initialize(address _logic, address _admin, bytes memory _data) public payable {
require(_implementation() == address(0));
InitializableUpgradeabilityProxy.initialize(_logic, _data);
assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
_setAdmin(_admin);
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
contract ERC20 is Initializable, Context, IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
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");
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal {
require(account != address(0), "ERC20: burn from the zero address");
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
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");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
}
uint256[50] private ______gap;
}
contract ERC20Detailed is Initializable, IERC20 {
string private _name;
string private _symbol;
uint8 private _decimals;
function initialize(string memory name, string memory symbol, uint8 decimals) public initializer {
_name = name;
_symbol = symbol;
_decimals = decimals;
}
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
uint256[50] private ______gap;
}
contract Claimable is Initializable, Ownable {
address public pendingOwner;
function initialize(address _nextOwner) public initializer {
Ownable.initialize(_nextOwner);
}
modifier onlyPendingOwner() {
require(
_msgSender() == pendingOwner,
"Claimable: caller is not the pending owner"
);
_;
}
function transferOwnership(address newOwner) public onlyOwner {
require(
newOwner != owner() && newOwner != pendingOwner,
"Claimable: invalid new owner"
);
pendingOwner = newOwner;
}
function claimOwnership() public onlyPendingOwner {
_transferOwnership(pendingOwner);
delete pendingOwner;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
assembly { codehash := extcodehash(account) }
return (codehash != 0x0 && codehash != accountHash);
}
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function callOptionalReturn(IERC20 token, bytes memory data) private {
require(address(token).isContract(), "SafeERC20: call to non-contract");
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
contract CanReclaimTokens is Claimable {
using SafeERC20 for ERC20;
mapping(address => bool) private recoverableTokensBlacklist;
function initialize(address _nextOwner) public initializer {
Claimable.initialize(_nextOwner);
}
function blacklistRecoverableToken(address _token) public onlyOwner {
recoverableTokensBlacklist[_token] = true;
}
function recoverTokens(address _token) external onlyOwner {
require(
!recoverableTokensBlacklist[_token],
"CanReclaimTokens: token is not recoverable"
);
if (_token == address(0x0)) {
msg.sender.transfer(address(this).balance);
} else {
ERC20(_token).safeTransfer(
msg.sender,
ERC20(_token).balanceOf(address(this))
);
}
}
}
contract ERC20WithRate is Initializable, Ownable, ERC20 {
using SafeMath for uint256;
uint256 public constant _rateScale = 1e18;
uint256 internal _rate;
event LogRateChanged(uint256 indexed _rate);
function initialize(address _nextOwner, uint256 _initialRate)
public
initializer
{
Ownable.initialize(_nextOwner);
_setRate(_initialRate);
}
function setExchangeRate(uint256 _nextRate) public onlyOwner {
_setRate(_nextRate);
}
function exchangeRateCurrent() public view returns (uint256) {
require(_rate != 0, "ERC20WithRate: rate has not been initialized");
return _rate;
}
function _setRate(uint256 _nextRate) internal {
require(_nextRate > 0, "ERC20WithRate: rate must be greater than zero");
_rate = _nextRate;
}
function balanceOfUnderlying(address _account)
public
view
returns (uint256)
{
return toUnderlying(balanceOf(_account));
}
function toUnderlying(uint256 _amount) public view returns (uint256) {
return _amount.mul(_rate).div(_rateScale);
}
function fromUnderlying(uint256 _amountUnderlying)
public
view
returns (uint256)
{
return _amountUnderlying.mul(_rateScale).div(_rate);
}
}
contract ERC20WithPermit is Initializable, ERC20, ERC20Detailed {
using SafeMath for uint256;
mapping(address => uint256) public nonces;
string public version;
bytes32 public DOMAIN_SEPARATOR;
bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;
function initialize(
uint256 _chainId,
string memory _version,
string memory _name,
string memory _symbol,
uint8 _decimals
) public initializer {
ERC20Detailed.initialize(_name, _symbol, _decimals);
version = _version;
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256(bytes(name())),
keccak256(bytes(version)),
_chainId,
address(this)
)
);
}
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(
abi.encode(
PERMIT_TYPEHASH,
holder,
spender,
nonce,
expiry,
allowed
)
)
)
);
require(holder != address(0), "ERC20WithRate: address must not be 0x0");
require(
holder == ecrecover(digest, v, r, s),
"ERC20WithRate: invalid signature"
);
require(
expiry == 0 || now <= expiry,
"ERC20WithRate: permit has expired"
);
require(nonce == nonces[holder]++, "ERC20WithRate: invalid nonce");
uint256 amount = allowed ? uint256(-1) : 0;
_approve(holder, spender, amount);
}
}
contract RenERC20LogicV1 is
Initializable,
ERC20,
ERC20Detailed,
ERC20WithRate,
ERC20WithPermit,
Claimable,
CanReclaimTokens
{
function initialize(
uint256 _chainId,
address _nextOwner,
uint256 _initialRate,
string memory _version,
string memory _name,
string memory _symbol,
uint8 _decimals
) public initializer {
ERC20Detailed.initialize(_name, _symbol, _decimals);
ERC20WithRate.initialize(_nextOwner, _initialRate);
ERC20WithPermit.initialize(
_chainId,
_version,
_name,
_symbol,
_decimals
);
Claimable.initialize(_nextOwner);
CanReclaimTokens.initialize(_nextOwner);
}
function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
}
function burn(address _from, uint256 _amount) public onlyOwner {
_burn(_from, _amount);
}
function transfer(address recipient, uint256 amount) public returns (bool) {
require(
recipient != address(this),
"RenERC20: can't transfer to token address"
);
return super.transfer(recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount)
public
returns (bool)
{
require(
recipient != address(this),
"RenERC20: can't transfer to token address"
);
return super.transferFrom(sender, recipient, amount);
}
}
contract RenBTC is InitializableAdminUpgradeabilityProxy {}
contract RenZEC is InitializableAdminUpgradeabilityProxy {}
contract RenBCH is InitializableAdminUpgradeabilityProxy {}