pragma solidity 0.5.16;
// File: ../Ownable.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.
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner, "Ownable: Not owner");
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "Ownable: Zero address not allowed");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
// File: ../interfaces/IGovernedContract.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.
/**
* 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 view 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: ../GovernedContract.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.
/**
* 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, "Governed Contract: Not proxy");
_;
}
function getProxy() internal view returns (address _proxy) {
_proxy = proxy;
}
// Function overridden in child contract
function migrate(IGovernedContract _oldImpl) external requireProxy {
_migrate(_oldImpl);
}
// Function overridden in child contract
function destroy(IGovernedContract _newImpl) external requireProxy {
_destroy(_newImpl);
}
// solium-disable-next-line no-empty-blocks
function _migrate(IGovernedContract) internal {}
function _destroy(IGovernedContract _newImpl) internal {
selfdestruct(address(uint160(address(_newImpl))));
}
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: ../NonReentrant.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.
/**
* A little helper to protect contract from being re-entrant in state
* modifying functions.
*/
contract NonReentrant {
uint256 private entry_guard;
modifier noReentry {
require(entry_guard == 0, "NonReentrant: Reentry");
entry_guard = 1;
_;
entry_guard = 0;
}
}
// File: ../interfaces/IProposal.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 IProposal {
function parent() external view returns (address);
function created_block() external view returns (uint256);
function deadline() external view returns (uint256);
function fee_payer() external view returns (address payable);
function fee_amount() external view returns (uint256);
function accepted_weight() external view returns (uint256);
function rejected_weight() external view returns (uint256);
function total_weight() external view returns (uint256);
function quorum_weight() external view returns (uint256);
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 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 of UpgradeProposal
*/
contract IUpgradeProposal is IProposal {
function impl() external view returns (IGovernedContract);
}
// File: ../interfaces/IGovernedProxy.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.
//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 spork_proxy() external view returns (IGovernedProxy);
function proposeUpgrade(IGovernedContract _newImpl, uint256 _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/ISporkRegistry.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 ISporkRegistry {
function createUpgradeProposal(
IGovernedContract _impl,
uint256 _period,
address payable _fee_payer
) external payable returns (IUpgradeProposal);
function consensusGasLimits()
external
view
returns (uint256 callGas, uint256 xferGas);
}
// File: WhitelistGovernedProxy.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 WhitelistGovernedProxy is
NonReentrant,
IGovernedContract,
IGovernedProxy
{
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,
"WhitelistGovernedProxy: Only direct calls are allowed!"
);
_;
}
modifier onlyImpl {
require(
msg.sender == address(impl),
"WhitelistGovernedProxy: Only calls from impl are allowed!"
);
_;
}
IGovernedContract public impl;
IGovernedProxy public spork_proxy;
mapping(address => IGovernedContract) public upgrade_proposals;
IUpgradeProposal[] public upgrade_proposal_list;
constructor(address payable _sporkProxy, address _impl) public {
spork_proxy = IGovernedProxy(_sporkProxy);
impl = IGovernedContract(_impl);
}
event AddressAdded(address indexed smartContract);
event AddressRemoved(address indexed smartContract);
function emitAddressAdded(address smartContract) external onlyImpl {
emit AddressAdded(smartContract);
}
function emitAddressRemoved(address smartContract) external onlyImpl {
emit AddressRemoved(smartContract);
}
/**
* Pre-create a new contract first.
* Then propose upgrade based on that.
*/
function proposeUpgrade(IGovernedContract _newImpl, uint256 _period)
external
payable
senderOrigin
noReentry
returns (IUpgradeProposal)
{
require(
_newImpl != impl,
"WhitelistGovernedProxy: Already active!"
);
require(
_newImpl.proxy() == address(this),
"WhitelistGovernedProxy: 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,
"WhitelistGovernedProxy: Already active!"
);
// in case it changes in the flight
require(
address(new_impl) != address(0),
"WhitelistGovernedProxy: Not registered!"
);
require(
_proposal.isAccepted(),
"WhitelistGovernedProxy: 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)
{
uint256 len = upgrade_proposal_list.length;
proposals = new IUpgradeProposal[](len);
for (uint256 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),
"WhitelistGovernedProxy: Not registered!"
);
_proposal.collect();
delete upgrade_proposals[address(_proposal)];
_cleanupProposal(_proposal);
}
function _cleanupProposal(IUpgradeProposal _proposal) internal {
delete upgrade_proposals[address(_proposal)];
uint256 len = upgrade_proposal_list.length;
for (uint256 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 {
revert("WhitelistGovernedProxy: Good try");
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function destroy(IGovernedContract) external {
revert("WhitelistGovernedProxy: 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: WhitelistAutoProxy.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.
/**
* WhitelistAutoProxy is a version of GovernedContract which deploys its own proxy.
* This is useful to avoid a circular dependency between GovernedContract and GovernedProxy
* wherein they need each other's address in the constructor.
* If you want a new governed contract to create a proxy, pass address(0) when deploying
* otherwise, you can pass a proxy address like in normal GovernedContract
*/
contract WhitelistAutoProxy is GovernedContract {
constructor(address _proxy, address payable _sporkProxy, address _impl) public GovernedContract(_proxy) {
if (_proxy == address(0)) {
_proxy = address(new WhitelistGovernedProxy(_sporkProxy, _impl));
}
proxy = _proxy;
}
}
// File: ../StorageBase.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.
/**
* 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), "StorageBase: 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: ../UniqueAppendOnlyAddressList.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.
contract UniqueAppendOnlyAddressListStorage is StorageBase {
uint256 private num;
address[] private items;
mapping(address => bool) private exists;
mapping(address => bool) private isActive;
function setNum(uint256 _num) external requireOwner {
num = _num;
}
function pushItems(address _item) external requireOwner {
items.push(_item);
}
function setExists(address _item, bool _Exists) external requireOwner {
exists[_item] = _Exists;
}
function setIsActive(address _item, bool _isActive) external requireOwner {
isActive[_item] = _isActive;
}
function setExistsAndIsActive(address _item, bool _Exists, bool _isActive) external requireOwner {
exists[_item] = _Exists;
isActive[_item] = _isActive;
}
function getNum() external view returns (uint256 _num) {
_num = num;
}
function getItem(uint index) external view returns (address _item) {
_item = items[index];
}
function getAllItems() external view returns (address[] memory _items) {
_items = items;
}
function getItemsCount() external view returns (uint256 _count) {
_count = items.length;
}
function getExists(address _item) external view returns (bool _exists) {
_exists = exists[_item];
}
function getIsActive(address _item) external view returns (bool _isActive) {
_isActive = isActive[_item];
}
function getExistsAndIsActive(address _item) external view returns (bool _exists, bool _isActive) {
_exists = exists[_item];
_isActive = isActive[_item];
}
}
contract UniqueAppendOnlyAddressList is Ownable {
UniqueAppendOnlyAddressListStorage public _storage;
function count() public view returns (uint256) {
return _storage.getItemsCount();
}
function numOfActive() public view returns (uint256) {
return _storage.getNum();
}
function exists(address _item) public view returns (bool) {
return _storage.getExists (_item);
}
function isActive(address _item) public view returns (bool) {
return _storage.getIsActive(_item);
}
function activateItem(address _item) internal returns (bool) {
if (_storage.getIsActive(_item)) {
return false;
}
if (!_storage.getExists(_item)) {
_storage.pushItems(_item);
}
_storage.setNum(_storage.getNum() + 1);
_storage.setExistsAndIsActive(_item, true, true);
return true;
}
function deactivateItem(address _item) internal returns (bool) {
if (_storage.getExists(_item) && _storage.getIsActive(_item)) {
_storage.setNum(_storage.getNum() - 1);
_storage.setExistsAndIsActive(_item, true, false);
return true;
}
return false;
}
function getActiveItems(uint256 offset, uint8 limit) public view returns (uint256 count_, address[] memory items_) {
// local storage of data to save gas
uint256 itemsLengthLocal = _storage.getItemsCount();
address[] memory itemsLocal = _storage.getAllItems();
items_ = new address[](limit);
require (offset < itemsLengthLocal && limit != 0, "UniqueAppendOnlyAddressList: Offset too high or limit is 0");
for (uint256 i = 0; i < limit; i++) {
if (offset + i >= itemsLengthLocal) {
break;
}
if (_storage.getIsActive(itemsLocal[offset + i])) {
items_[count_] = itemsLocal[offset + i];
count_++;
}
}
}
function getAllItems() external view returns (address[] memory _items) {
_items = _storage.getAllItems();
}
}
// File: IWhitelistGovernedProxy.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 IWhitelistGovernedProxy {
event AddressAdded(address indexed smartContract);
event AddressRemoved(address indexed smartContract);
function emitAddressAdded(address smartContract) external;
function emitAddressRemoved(address smartContract) external;
}
// File: ../interfaces/IStorageBase.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 IStorageBase {
function setOwner(address _newOwner) external;
}
// File: Whitelist.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.
contract Whitelist is Ownable, UniqueAppendOnlyAddressList, WhitelistAutoProxy {
constructor(address _proxy, address payable _sporkProxy) public WhitelistAutoProxy(_proxy, _sporkProxy, address(this)) {
_storage = new UniqueAppendOnlyAddressListStorage();
}
// This function is called in order to upgrade to a new Whitelist implementation
function destroy(IGovernedContract _newImpl) external requireProxy {
IStorageBase(address(_storage)).setOwner(address(_newImpl));
// Self destruct
_destroy(_newImpl);
}
// This function (placeholder) would be called on the new implementation if necessary for the upgrade
function migrate(IGovernedContract _oldImpl) external requireProxy {
_migrate(_oldImpl);
}
function numOfWhitelisted() external view returns (uint256) {
return numOfActive();
}
function isWhitelisted(address _item) external view returns (bool) {
return isActive(_item);
}
function removeAddress(address _address) external onlyOwner returns (bool success_) {
if(deactivateItem(_address)){
IWhitelistGovernedProxy(proxy).emitAddressRemoved(_address);
success_ = true;
}
}
function addAddress(address _address) external onlyOwner returns (bool success_) {
if(activateItem(_address)){
IWhitelistGovernedProxy(proxy).emitAddressAdded(_address);
success_ = true;
}
}
function getWhitelisted(uint256 offset, uint8 limit) public view returns (uint256 count_, address[] memory items_) {
(count_, items_) = getActiveItems(offset, limit);
}
}