Contract Address Details

0xA55F26319462355474A9F2c8790860776a329aA4

Token
Wrapped NRG (WNRG)
Creator
0x5c2811–2dc8b3 at 0xe526ed–b065fd
Implementation
0x7a86173daa4fda903c9a4c0517735a7d34b9ec39
Balance
12.36M NRG
Tokens
Fetching tokens...
Transactions
2,319 Transactions
Transfers
0 Transfers
Gas Used
81,482,098
Last Balance Update
2516807
Contract name:
WNRGGovernedERC20Proxy




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




Optimization runs
200
EVM Version
petersburg




Verified at
2021-09-28 10:34:10.287169Z

Constructor Arguments

0000000000000000000000005c2811c7bb5729d682fe084a13b0d4566e2dc8b30000000000000000000000000000000000000000000000000000000000000305

Arg [0] (address) : 0x5c2811c7bb5729d682fe084a13b0d4566e2dc8b3
Arg [1] (address) : 0x0000000000000000000000000000000000000305

              

Contract source code

pragma solidity 0.5.16;
// File: interfaces/IGovernedContract.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.
/**
* 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: 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 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 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/IWNRGGovernedERC20Proxy.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.
/**
* 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 IWNRGGovernedERC20Proxy {
event UpgradeProposal(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
event Upgraded(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
// WNRG interface
function deposit() external payable;
function withdraw(uint amount) external;
// 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 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.
/**
* 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/IWrappedEnergi.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 IWrappedEnergi {
function name() external view returns(string memory _name);
function symbol() external view returns(string memory _symbol);
function decimals() external view returns(uint8 _decimals);
function mint(address account, uint value) external;
function burn(address account, uint value) external;
}
// File: Context.sol
// Copyright (C) 2020 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 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: libraries/SafeMath.sol
// Copyright (C) 2020 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: WNRGGovernedERC20Proxy.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.
/**
* 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 WNRGGovernedERC20Proxy is IWNRGGovernedERC20Proxy, NonReentrant, Context {
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!");
_;
}
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed _owner, address indexed spender, uint256 value);
constructor(IGovernedContract _impl, IGovernedProxy _sporkProxy) public {
impl = _impl;
spork_proxy = _sporkProxy;
}
// WNRG functions
// Proxy contract holds deposited funds
function deposit() external payable {
IWrappedEnergi(address(impl)).mint(_msgSender(), msg.value);
}
function withdraw(uint amount) external {
(bool success,) = _msgSender().call.value(amount)(new bytes(0));
require(success, "WNRG: withdrawal failed");
IWrappedEnergi(address(impl)).burn(_msgSender(), amount);
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function mint(address, uint) external pure {
revert("Good try");
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function burn(address, uint) external pure {
revert("Good try");
}
// 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);
}
// 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)
}
}
}
}

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[{"type":"address","name":"_impl","internalType":"contract IGovernedContract"},{"type":"address","name":"_sporkProxy","internalType":"contract IGovernedProxy"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"_owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"UpgradeProposal","inputs":[{"type":"address","name":"impl","internalType":"contract IGovernedContract","indexed":true},{"type":"address","name":"proposal","internalType":"contract IUpgradeProposal","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"impl","internalType":"contract IGovernedContract","indexed":true},{"type":"address","name":"proposal","internalType":"contract IUpgradeProposal","indexed":false}],"anonymous":false},{"type":"fallback","stateMutability":"payable","payable":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_allowance","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":"result","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_balance","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[],"name":"burn","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"collectUpgradeProposal","inputs":[{"type":"address","name":"_proposal","internalType":"contract IUpgradeProposal"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_decimals","internalType":"uint256"}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"result","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"deposit","inputs":[],"constant":false},{"type":"function","stateMutability":"pure","payable":false,"outputs":[],"name":"destroy","inputs":[{"type":"address","name":"","internalType":"contract IGovernedContract"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract IGovernedContract"}],"name":"impl","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"result","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":"proposals","internalType":"contract IUpgradeProposal[]"}],"name":"listUpgradeProposals","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[],"name":"migrate","inputs":[{"type":"address","name":"","internalType":"contract IGovernedContract"}],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[],"name":"mint","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"_name","internalType":"string"}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"payable","payable":true,"outputs":[{"type":"address","name":"","internalType":"contract IUpgradeProposal"}],"name":"proposeUpgrade","inputs":[{"type":"address","name":"_newImpl","internalType":"contract IGovernedContract"},{"type":"uint256","name":"_period","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"proxy","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract IGovernedProxy"}],"name":"spork_proxy","inputs":[],"constant":true},{"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":"_totalSupply","internalType":"uint256"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"result","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"result","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"upgrade","inputs":[{"type":"address","name":"_proposal","internalType":"contract IUpgradeProposal"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"new_impl","internalType":"contract IGovernedContract"}],"name":"upgradeProposalImpl","inputs":[{"type":"address","name":"_proposal","internalType":"contract IUpgradeProposal"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract IUpgradeProposal"}],"name":"upgrade_proposal_list","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract IGovernedContract"}],"name":"upgrade_proposals","inputs":[{"type":"address","name":"","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"constant":false}]
            

Deployed ByteCode

0x60806040526004361061019b5760003560e01c80636fa09ab0116100ec578063a9059cbb1161008a578063d0e30db011610064578063d0e30db0146106c0578063dd62ed3e146106c8578063dd6a851d14610703578063ec556889146107185761019b565b8063a9059cbb14610622578063b364595e1461065b578063ce5494bb146102275761019b565b806395d89b41116100c657806395d89b41146105a15780639dc29fac14610497578063a1b0e476146105b6578063a457c2d7146105e95761019b565b80636fa09ab01461052f57806370a08231146105595780638abf60771461058c5761019b565b80632e1a7d4d116101595780633950935111610133578063395093511461045e57806340c10f19146104975780635b6dee4c146104d05780636d5b6c44146104fc5761019b565b80632e1a7d4d146103d0578063313ce567146103fa57806332e3a9051461040f5761019b565b8062f55d9d1461022757806306fdde031461025c5780630900f010146102e6578063095ea7b31461031957806318160ddd1461036657806323b872dd1461038d575b3233146101ef576040805162461bcd60e51b815260206004820152601e60248201527f4f6e6c79206469726563742063616c6c732061726520616c6c6f776564210000604482015290519081900360640190fd5b6001546040516001600160a01b03909116903660008237600080368334866127105a03f13d6000833e808015610223573d83f35b3d83fd5b34801561023357600080fd5b5061025a6004803603602081101561024a57600080fd5b50356001600160a01b031661072d565b005b34801561026857600080fd5b50610271610765565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ab578181015183820152602001610293565b50505050905090810190601f1680156102d85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102f257600080fd5b5061025a6004803603602081101561030957600080fd5b50356001600160a01b031661089c565b34801561032557600080fd5b506103526004803603604081101561033c57600080fd5b506001600160a01b038135169060200135610bc0565b604080519115158252519081900360200190f35b34801561037257600080fd5b5061037b610c95565b60408051918252519081900360200190f35b34801561039957600080fd5b50610352600480360360608110156103b057600080fd5b506001600160a01b03813581169160208101359091169060400135610d0b565b3480156103dc57600080fd5b5061025a600480360360208110156103f357600080fd5b5035610eb4565b34801561040657600080fd5b5061037b611049565b34801561041b57600080fd5b506104426004803603602081101561043257600080fd5b50356001600160a01b03166110c2565b604080516001600160a01b039092168252519081900360200190f35b34801561046a57600080fd5b506103526004803603604081101561048157600080fd5b506001600160a01b0381351690602001356110dd565b3480156104a357600080fd5b5061025a600480360360408110156104ba57600080fd5b506001600160a01b03813516906020013561072d565b610442600480360360408110156104e657600080fd5b506001600160a01b038135169060200135611238565b34801561050857600080fd5b506104426004803603602081101561051f57600080fd5b50356001600160a01b031661158d565b34801561053b57600080fd5b506104426004803603602081101561055257600080fd5b50356115ab565b34801561056557600080fd5b5061037b6004803603602081101561057c57600080fd5b50356001600160a01b03166115d2565b34801561059857600080fd5b50610442611655565b3480156105ad57600080fd5b50610271611664565b3480156105c257600080fd5b5061025a600480360360208110156105d957600080fd5b50356001600160a01b03166116a9565b3480156105f557600080fd5b506103526004803603604081101561060c57600080fd5b506001600160a01b0381351690602001356117d6565b34801561062e57600080fd5b506103526004803603604081101561064557600080fd5b506001600160a01b038135169060200135611835565b34801561066757600080fd5b5061067061190a565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ac578181015183820152602001610694565b505050509050019250505060405180910390f35b61025a6119a4565b3480156106d457600080fd5b5061037b600480360360408110156106eb57600080fd5b506001600160a01b0381358116916020013516611a27565b34801561070f57600080fd5b50610442611ab3565b34801561072457600080fd5b50610442611ac2565b6040805162461bcd60e51b8152602060048201526008602482015267476f6f642074727960c01b604482015290519081900360640190fd5b600154604080516306fdde0360e01b815290516060926001600160a01b0316916306fdde03916004808301926000929190829003018186803b1580156107aa57600080fd5b505afa1580156107be573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156107e757600080fd5b810190808051604051939291908464010000000082111561080757600080fd5b90830190602082018581111561081c57600080fd5b825164010000000081118282018810171561083657600080fd5b82525081516020918201929091019080838360005b8381101561086357818101518382015260200161084b565b50505050905090810190601f1680156108905780820380516001836020036101000a031916815260200191505b50604052505050905090565b600054156108db576040805162461bcd60e51b81526020600482015260076024820152665265656e74727960c81b604482015290519081900360640190fd5b600160008181556001600160a01b038084168252600360205260409091205491549181169116811415610947576040805162461bcd60e51b815260206004820152600f60248201526e416c7265616479206163746976652160881b604482015290519081900360640190fd5b6001600160a01b038116610994576040805162461bcd60e51b815260206004820152600f60248201526e4e6f7420726567697374657265642160881b604482015290519081900360640190fd5b816001600160a01b0316635051a5ec6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109cd57600080fd5b505afa1580156109e1573d6000803e3d6000fd5b505050506040513d60208110156109f757600080fd5b5051610a3a576040805162461bcd60e51b815260206004820152600d60248201526c4e6f742061636365707465642160981b604482015290519081900360640190fd5b6001546040805163ce5494bb60e01b81526001600160a01b03928316600482018190529151919284169163ce5494bb9160248082019260009290919082900301818387803b158015610a8b57600080fd5b505af1158015610a9f573d6000803e3d6000fd5b5050600180546001600160a01b0319166001600160a01b038681169182179092556040805162f55d9d60e01b8152600481019290925251918516935062f55d9d925060248082019260009290919082900301818387803b158015610b0257600080fd5b505af1158015610b16573d6000803e3d6000fd5b50505050610b2383611ac6565b826001600160a01b03166383197ef06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b5e57600080fd5b505af1158015610b72573d6000803e3d6000fd5b5050604080516001600160a01b038781168252915191861693507f5d611f318680d00598bb735d61bacf0c514c6b50e1e5ad30040a4df2b12791c7925081900360200190a250506000805550565b6001546040805163e1f21c6760e01b81523360048201526001600160a01b038581166024830152604482018590529151600093929092169163e1f21c679160648082019260209290919082900301818787803b158015610c1f57600080fd5b505af1158015610c33573d6000803e3d6000fd5b505050506040513d6020811015610c4957600080fd5b50516040805184815290519192506001600160a01b0385169133917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925919081900360200190a392915050565b600154604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b158015610cda57600080fd5b505afa158015610cee573d6000803e3d6000fd5b505050506040513d6020811015610d0457600080fd5b5051919050565b60015460408051630aed65f560e11b81523360048201526001600160a01b038681166024830152858116604483015260648201859052915160009392909216916315dacbea9160848082019260209290919082900301818787803b158015610d7257600080fd5b505af1158015610d86573d6000803e3d6000fd5b505050506040513d6020811015610d9c57600080fd5b50516040805184815290519192506001600160a01b0380861692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a360015460408051636eb1769f60e11b81526001600160a01b0387811660048301523360248301529151600093929092169163dd62ed3e91604480820192602092909190829003018186803b158015610e3c57600080fd5b505afa158015610e50573d6000803e3d6000fd5b505050506040513d6020811015610e6657600080fd5b505160408051828152905191925033916001600160a01b038816917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925919081900360200190a3509392505050565b6000610ebe611bce565b6040805160008152602081019182905280516001600160a01b039390931692859290819081908082805b60208310610f075780518252601f199092019160209182019101610ee8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114610f69576040519150601f19603f3d011682016040523d82523d6000602084013e610f6e565b606091505b5050905080610fc4576040805162461bcd60e51b815260206004820152601760248201527f574e52473a207769746864726177616c206661696c6564000000000000000000604482015290519081900360640190fd5b6001546001600160a01b0316639dc29fac610fdd611bce565b846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561102d57600080fd5b505af1158015611041573d6000803e3d6000fd5b505050505050565b6001546040805163313ce56760e01b815290516000926001600160a01b03169163313ce567916004808301926020929190829003018186803b15801561108e57600080fd5b505afa1580156110a2573d6000803e3d6000fd5b505050506040513d60208110156110b857600080fd5b505160ff16919050565b6003602052600090815260409020546001600160a01b031681565b60015460408051633621d16560e11b81523360048201526001600160a01b0385811660248301526044820185905291516000939290921691636c43a2ca9160648082019260209290919082900301818787803b15801561113c57600080fd5b505af1158015611150573d6000803e3d6000fd5b505050506040513d602081101561116657600080fd5b505160015460408051636eb1769f60e11b81523360048201526001600160a01b0387811660248301529151939450600093919092169163dd62ed3e916044808301926020929190829003018186803b1580156111c157600080fd5b505afa1580156111d5573d6000803e3d6000fd5b505050506040513d60208110156111eb57600080fd5b50516040805182815290519192506001600160a01b0386169133917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925919081900360200190a35092915050565b600032331461128e576040805162461bcd60e51b815260206004820152601e60248201527f4f6e6c79206469726563742063616c6c732061726520616c6c6f776564210000604482015290519081900360640190fd5b600054156112cd576040805162461bcd60e51b81526020600482015260076024820152665265656e74727960c81b604482015290519081900360640190fd5b60016000819055546001600160a01b0384811691161415611327576040805162461bcd60e51b815260206004820152600f60248201526e416c7265616479206163746976652160881b604482015290519081900360640190fd5b306001600160a01b0316836001600160a01b031663ec5568896040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561136c57600080fd5b505af1158015611380573d6000803e3d6000fd5b505050506040513d602081101561139657600080fd5b50516001600160a01b0316146113e2576040805162461bcd60e51b815260206004820152600c60248201526b57726f6e672070726f78792160a01b604482015290519081900360640190fd5b60025460408051638abf607760e01b815290516000926001600160a01b031691638abf6077916004808301926020929190829003018186803b15801561142757600080fd5b505afa15801561143b573d6000803e3d6000fd5b505050506040513d602081101561145157600080fd5b5051604080516362877ccd60e01b81526001600160a01b038781166004830152602482018790523360448301529151929350600092918416916362877ccd913491606480830192602092919082900301818588803b1580156114b257600080fd5b505af11580156114c6573d6000803e3d6000fd5b50505050506040513d60208110156114dd57600080fd5b50516001600160a01b0380821660008181526003602090815260408083208054958c166001600160a01b031996871681179091556004805460018101825594527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9093018054909516841790945583519283529251939450927f812eb2689eecf94cfb55caf4a123ea76c6d93eef07dd54a5273b7a4949f7d763929181900390910190a260008055949350505050565b6001600160a01b039081166000908152600360205260409020541690565b600481815481106115b857fe5b6000918252602090912001546001600160a01b0316905081565b600154604080516370a0823160e01b81526001600160a01b038481166004830152915160009392909216916370a0823191602480820192602092909190829003018186803b15801561162357600080fd5b505afa158015611637573d6000803e3d6000fd5b505050506040513d602081101561164d57600080fd5b505192915050565b6001546001600160a01b031681565b600154604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301926000929190829003018186803b1580156107aa57600080fd5b600054156116e8576040805162461bcd60e51b81526020600482015260076024820152665265656e74727960c81b604482015290519081900360640190fd5b600160009081556001600160a01b0380831682526003602052604090912054168061174c576040805162461bcd60e51b815260206004820152600f60248201526e4e6f7420726567697374657265642160881b604482015290519081900360640190fd5b816001600160a01b031663e52253816040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561178757600080fd5b505af115801561179b573d6000803e3d6000fd5b5050506001600160a01b038316600090815260036020526040902080546001600160a01b0319169055506117ce82611ac6565b505060008055565b6001546040805163d73b1dc960e01b81523360048201526001600160a01b038581166024830152604482018590529151600093929092169163d73b1dc99160648082019260209290919082900301818787803b15801561113c57600080fd5b600154604080516317d5759960e31b81523360048201526001600160a01b038581166024830152604482018590529151600093929092169163beabacc89160648082019260209290919082900301818787803b15801561189457600080fd5b505af11580156118a8573d6000803e3d6000fd5b505050506040513d60208110156118be57600080fd5b50516040805184815290519192506001600160a01b0385169133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef919081900360200190a392915050565b6004546040805182815260208084028201019091526060919081801561193a578160200160208202803883390190505b50915060005b8181101561199f576004818154811061195557fe5b9060005260206000200160009054906101000a90046001600160a01b031683828151811061197f57fe5b6001600160a01b0390921660209283029190910190910152600101611940565b505090565b6001546001600160a01b03166340c10f196119bd611bce565b346040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a0d57600080fd5b505af1158015611a21573d6000803e3d6000fd5b50505050565b60015460408051636eb1769f60e11b81526001600160a01b03858116600483015284811660248301529151600093929092169163dd62ed3e91604480820192602092909190829003018186803b158015611a8057600080fd5b505afa158015611a94573d6000803e3d6000fd5b505050506040513d6020811015611aaa57600080fd5b50519392505050565b6002546001600160a01b031681565b3090565b6001600160a01b038116600090815260036020526040812080546001600160a01b0319169055600454905b81811015611bc957826001600160a01b031660048281548110611b1057fe5b6000918252602090912001546001600160a01b03161415611bc15760046001830381548110611b3b57fe5b600091825260209091200154600480546001600160a01b039092169183908110611b6157fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480611b9a57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055611bc9565b600101611af1565b505050565b339056fea265627a7a72315820529718a88e1918eab961995dc9525a322bef4959866a75f1b1a2381f95ab1ff164736f6c63430005100032