pragma solidity 0.5.16;
// File: ../interfaces/IEnergiswapGovernedContract.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/>.
interface IEnergiswapGovernedContract {
function proxy() external returns(address);
}
// File: ../interfaces/IStorageBase.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/>.
pragma solidity = 0.5.16;
interface IStorageBase {
function setOwner(address _newOwner) external;
}
// File: ../EnergiswapGovernedContract.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 solidity = 0.5.16;
/**
* 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 EnergiswapGovernedContract is IEnergiswapGovernedContract {
address public proxy;
constructor(address _proxy) public {
proxy = _proxy;
}
modifier requireProxy {
require(msg.sender == proxy, "EnergiswapGovernedContract: FORBIDDEN, not proxy");
_;
}
function getProxy() internal view returns(address _proxy) {
_proxy = proxy;
}
// solium-disable-next-line no-empty-blocks
function _migrate(address) internal {}
function _destroy(address _newImpl) internal {
selfdestruct(address(uint160(_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 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: IEnergiswapFactory.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface IEnergiswapFactory {
function initialized() external view returns (bool);
function _storage() external view returns (address);
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function initialize(address _routerProxy, address _pairsManagerProxy, address _pairsERC20Proxy) external;
function destroy(address _newImpl) external;
function migrate(address _oldImpl) external;
function createPair(
address tokenA,
address tokenB
) external returns (address pairProxy);
function setFeeTo(address _feeTo) external;
function setFeeToSetter(address _feeToSetter) external;
function feeTo() external view returns (address _feeTo);
function feeToSetter() external view returns (address _feeToSetter);
function sporkProxy() external view returns (address _sporkProxy);
function getPair(address tokenA, address tokenB) external view returns (address _pair);
function allPairs(uint index) external view returns (address _pair);
function allPairsLength() external view returns (uint);
}
// 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.
pragma solidity >=0.5.0;
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.
pragma solidity >=0.5.0;
/**
* 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 solidity >=0.5.0;
//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: IEnergiswapFactoryGovernedProxy.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 solidity >=0.5.0;
//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 IEnergiswapFactoryGovernedProxy {
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 emitPairCreated(address token0, address token1, address pair, uint allPairsLength) external;
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 collectUpgradeProposal(IUpgradeProposal _proposal) external;
function proxy() external view returns (address);
function migrate(IGovernedContract) external pure;
function destroy(IGovernedContract) external pure;
function () external payable;
}
// 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.
pragma solidity >=0.5.0;
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: EnergiswapFactoryGovernedProxy.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/>.
pragma solidity = 0.5.16;
/**
* 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 EnergiswapFactoryGovernedProxy is IEnergiswapFactoryGovernedProxy, NonReentrant {
IGovernedContract public impl;
IGovernedProxy public spork_proxy;
mapping(address => IGovernedContract) public upgrade_proposals;
IUpgradeProposal[] public upgrade_proposal_list;
event PairCreated(address indexed token0, address indexed token1, address pair, uint allPairsLength);
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,
"EnergiswapFactoryGovernedProxy: FORBIDDEN, not a direct call");
_;
}
modifier requireImpl {
require(msg.sender == address(impl), "EnergiswapFactoryGovernedProxy: FORBIDDEN, not impl");
_;
}
constructor(address _impl, address payable _sporkProxy) public {
impl = IGovernedContract(_impl);
spork_proxy = IGovernedProxy(_sporkProxy);
}
// Emit PairCreated event
function emitPairCreated(address token0, address token1, address pair, uint allPairsLength) external requireImpl {
emit PairCreated(token0, token1, pair, allPairsLength);
}
/**
* Pre-create a new contract first.
* Then propose upgrade based on that.
*/
function proposeUpgrade(IGovernedContract _newImpl, uint _period)
external payable
senderOrigin
noReentry
returns(IUpgradeProposal)
{
require(_newImpl != impl, "Already active!");
require(_newImpl.proxy() == address(this), "Wrong proxy!");
ISporkRegistry spork_reg = ISporkRegistry(address(spork_proxy.impl()));
IUpgradeProposal proposal = spork_reg.createUpgradeProposal.value(msg.value)(_newImpl, _period, msg.sender);
upgrade_proposals[address(proposal)] = _newImpl;
upgrade_proposal_list.push(proposal);
emit UpgradeProposal(_newImpl, proposal);
return proposal;
}
/**
* Once proposal is accepted, anyone can activate that.
*/
function upgrade(IUpgradeProposal _proposal)
external
noReentry
{
IGovernedContract new_impl = upgrade_proposals[address(_proposal)];
require(new_impl != impl, "Already active!"); // in case it changes in the flight
require(address(new_impl) != address(0), "Not registered!");
require(_proposal.isAccepted(), "Not accepted!");
IGovernedContract old_impl = impl;
new_impl.migrate(old_impl);
impl = new_impl;
old_impl.destroy(new_impl);
// SECURITY: prevent downgrade attack
_cleanupProposal(_proposal);
// Return fee ASAP
_proposal.destroy();
emit Upgraded(new_impl, _proposal);
}
/**
* Map proposal to implementation
*/
function upgradeProposalImpl(IUpgradeProposal _proposal)
external view
returns(IGovernedContract new_impl)
{
new_impl = upgrade_proposals[address(_proposal)];
}
/**
* Lists all available upgrades
*/
function listUpgradeProposals()
external view
returns(IUpgradeProposal[] memory proposals)
{
uint len = upgrade_proposal_list.length;
proposals = new IUpgradeProposal[](len);
for (uint i = 0; i < len; ++i) {
proposals[i] = upgrade_proposal_list[i];
}
return proposals;
}
/**
* Once proposal is reject, anyone can start collect procedure.
*/
function collectUpgradeProposal(IUpgradeProposal _proposal)
external
noReentry
{
IGovernedContract new_impl = upgrade_proposals[address(_proposal)];
require(address(new_impl) != address(0), "Not registered!");
_proposal.collect();
delete upgrade_proposals[address(_proposal)];
_cleanupProposal(_proposal);
}
function _cleanupProposal(IUpgradeProposal _proposal) internal {
delete upgrade_proposals[address(_proposal)];
uint len = upgrade_proposal_list.length;
for (uint i = 0; i < len; ++i) {
if (upgrade_proposal_list[i] == _proposal) {
upgrade_proposal_list[i] = upgrade_proposal_list[len - 1];
upgrade_proposal_list.pop();
break;
}
}
}
/**
* Related to above
*/
function proxy() external view returns (address) {
return address(this);
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function migrate(IGovernedContract) external pure {
revert("Good try");
}
/**
* SECURITY: prevent on-behalf-of calls
*/
function destroy(IGovernedContract) external pure {
revert("Good try");
}
/**
* Proxy all other calls to implementation.
*/
function ()
external
payable
senderOrigin
{
// SECURITY: senderOrigin() modifier is mandatory
IGovernedContract impl_m = impl;
// solium-disable-next-line security/no-inline-assembly
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize())
let res := call(sub(gas(), 10000), impl_m, callvalue(), ptr, calldatasize(), 0, 0)
// NOTE: returndatasize should allow repeatable calls
// what should save one opcode.
returndatacopy(ptr, 0, returndatasize())
switch res
case 0 {
revert(ptr, returndatasize())
}
default {
return(ptr, returndatasize())
}
}
}
}
// File: EnergiswapFactoryAutoProxy.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/>.
pragma solidity = 0.5.16;
contract EnergiswapFactoryAutoProxy is EnergiswapGovernedContract {
constructor (
address _proxy,
address _impl,
address payable _sporkProxy
) public EnergiswapGovernedContract(_proxy) {
// If _proxy is set to address(0), a new EnergiswapFactoryGovernedProxy is deployed
if(_proxy == address(0)){
_proxy = address(new EnergiswapFactoryGovernedProxy(_impl, _sporkProxy));
}
proxy = _proxy;
}
}
// File: ../energiswapPairsManager/IEnergiswapPairsManager.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface IEnergiswapPairsManager {
event Mint(address indexed pair, address indexed sender, uint amount0, uint amount1, address indexed to);
event Burn(address indexed pair, address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(address indexed sender, uint112 reserve0, uint112 reserve1);
function _storage() external view returns (address);
function destroy(address _newImpl) external;
function migrate(address _oldImpl) external;
function registerPair(address _pairProxy, address _pairStorage, address _erc20Storage) external;
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function skim(address to) external;
function sync() external;
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 redeemLiquidity(address router, address owner, uint value) external returns (bool result);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
function emitApproval(address pair, address owner, address spender, uint value) external;
function emitTransfer(address pair, address from, address to, uint value) external;
function factory() external view returns (address _factory);
function getReserves(address pair) external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);
function token0(address pair) external view returns (address _token0);
function token1(address pair) external view returns (address _token1);
function price0CumulativeLast(address pair) external view returns (uint _price0CumulativeLast);
function price1CumulativeLast(address pair) external view returns (uint _price1CumulativeLast);
function kLast(address pair) external view returns (uint _kLast);
}
// File: ../energiswapPair/IEnergiswapPairProxy.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 solidity >=0.5.0;
/**
* 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 IEnergiswapPairProxy {
function pairsManagerProxy() external view returns (address);
function pairsERC20Proxy() external view returns (address);
function routerProxy() external view returns (address);
function emitMint(address sender, uint amount0, uint amount1, address to) external;
function emitBurn(address sender, uint amount0, uint amount1, address to) external;
function emitSwap(address sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address to) external;
function emitSync(uint112 reserve0, uint112 reserve1) external;
function emitApproval(address owner, address spender, uint value) external;
function emitTransfer(address from, address to, uint value) external;
function safeTransfer(address token, address to, uint value, bytes4 SELECTOR) external;
function getReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);
function token0() external view returns (address _token0);
function token1() external view returns (address _token1);
function price0CumulativeLast() external view returns (uint _price0CumulativeLast);
function price1CumulativeLast() external view returns (uint _price1CumulativeLast);
function kLast() external view returns (uint _kLast);
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 (uint _totalSupply);
function balanceOf(address account) external view returns (uint _balance);
function allowance(address owner, address spender) external view returns (uint _allowance);
function nonce(address owner) external view returns(uint _nonce);
function () external payable;
}
// File: ../energiswapPairsERC20/IEnergiswapPairsERC20.sol
// Copyright 2021 The Energi Core Authors
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
interface IEnergiswapPairsERC20 {
function initialized() external view returns (bool);
function _storage() external view returns (address);
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function initialize(address _pairsManagerProxy) external;
function destroy(address _newImpl) external;
function migrate(address _oldImpl) external;
function registerPair(address _pairProxy, address _erc20Storage) external;
function _mint(address pair, address to, uint value) external;
function _burn(address pair, address from, uint value) external;
function approve(address pair, address owner, address spender, uint value) external returns (bool);
function transfer(address pair, address from, address to, uint value) external returns (bool);
function transferFrom(address pair, address spender, address from, address to, uint value) external returns (bool);
function permit(address pair, address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
function nonce(address pair, address owner) external view returns(uint _nonce);
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(address pair) external view returns (uint _totalSupply);
function balanceOf(address pair, address account) external view returns (uint _balance);
function allowance(address pair, address owner, address spender) external view returns (uint _allowance);
}
// File: ../energiswapPair/EnergiswapPairProxy.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/>.
pragma solidity = 0.5.16;
/**
* 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 EnergiswapPairProxy is IEnergiswapPairProxy {
address public pairsManagerProxy;
address public pairsERC20Proxy;
address public routerProxy;
function pairsManager() private view returns(address _pairsManager) {
_pairsManager = address(IGovernedProxy(address(uint160(pairsManagerProxy))).impl());
}
function pairsERC20() private view returns(address _pairsERC20) {
_pairsERC20 = address(IGovernedProxy(address(uint160(pairsERC20Proxy))).impl());
}
function router() private view returns(address _router) {
_router = address(IGovernedProxy(address(uint160(routerProxy))).impl());
}
modifier senderOrigin {
// solium-disable-next-line security/no-tx-origin
require(
tx.origin == msg.sender
|| msg.sender == router(),
"EnergiswapPairGovernedProxy: FORBIDDEN, not a direct call or a call from router");
_;
}
modifier requireManager {
require(msg.sender == pairsManager(), "EnergiswapPairGovernedProxy: FORBIDDEN, not pairsManager");
_;
}
event Mint(address indexed sender, uint amount0, uint amount1, address indexed to);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
address indexed sender,
uint amount0In,
uint amount1In,
uint amount0Out,
uint amount1Out,
address indexed to
);
event Sync(uint112 reserve0, uint112 reserve1);
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
constructor(address _routerProxy, address _pairsManagerProxy, address _pairsERC20Proxy) public {
routerProxy = _routerProxy;
pairsManagerProxy = _pairsManagerProxy;
pairsERC20Proxy = _pairsERC20Proxy;
}
// Emit Mint event
function emitMint(address sender, uint amount0, uint amount1, address to) external requireManager {
emit Mint(sender, amount0, amount1, to);
}
// Emit Burn event
function emitBurn(address sender, uint amount0, uint amount1, address to) external requireManager {
emit Burn(sender, amount0, amount1, to);
}
// Emit Swap event
function emitSwap(address sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address to) external requireManager {
emit Swap(sender, amount0In, amount1In, amount0Out, amount1Out, to);
}
// Emit Sync event
function emitSync(uint112 reserve0, uint112 reserve1) external requireManager {
emit Sync(reserve0, reserve1);
}
// Emit Approval event
function emitApproval(address owner, address spender, uint value) external requireManager {
emit Approval(owner, spender, value);
}
// Emit Transfer event
function emitTransfer(address from, address to, uint value) external requireManager {
emit Transfer(from, to, value);
}
// EnergiswapPairGovernedProxy holds pair assets. This function can be called by EnegiswapPairsManager to transfer funds
function safeTransfer(address token, address to, uint value, bytes4 SELECTOR) external requireManager {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'EnergiswapPairGovernedProxy: TRANSFER_FAILED');
}
// Expose Pair getter functions
function getReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
(_reserve0, _reserve1, _blockTimestampLast) = IEnergiswapPairsManager(pairsManager()).getReserves(address(this));
}
function token0() external view returns (address _token0) {
_token0 = IEnergiswapPairsManager(pairsManager()).token0(address(this));
}
function token1() external view returns (address _token1) {
_token1 = IEnergiswapPairsManager(pairsManager()).token1(address(this));
}
function price0CumulativeLast() external view returns (uint _price0CumulativeLast) {
_price0CumulativeLast = IEnergiswapPairsManager(pairsManager()).price0CumulativeLast(address(this));
}
function price1CumulativeLast() external view returns (uint _price1CumulativeLast) {
_price1CumulativeLast = IEnergiswapPairsManager(pairsManager()).price1CumulativeLast(address(this));
}
function kLast() external view returns (uint _kLast) {
_kLast = IEnergiswapPairsManager(pairsManager()).kLast(address(this));
}
// Expose ERC20 getter functions
function name() external view returns(string memory _name) {
_name = IEnergiswapPairsERC20(pairsERC20()).name();
}
function symbol() external view returns(string memory _symbol) {
_symbol = IEnergiswapPairsERC20(pairsERC20()).symbol();
}
function decimals() external view returns(uint8 _decimals) {
_decimals = IEnergiswapPairsERC20(pairsERC20()).decimals();
}
function totalSupply() external view returns (uint _totalSupply) {
_totalSupply = IEnergiswapPairsERC20(pairsERC20()).totalSupply(address(this));
}
function balanceOf(address account) external view returns (uint _balance) {
_balance = IEnergiswapPairsERC20(pairsERC20()).balanceOf(address(this), account);
}
function allowance(address owner, address spender) external view returns (uint _allowance) {
_allowance = IEnergiswapPairsERC20(pairsERC20()).allowance(address(this), owner, spender);
}
function nonce(address owner) external view returns(uint _nonce) {
_nonce = IEnergiswapPairsERC20(pairsERC20()).nonce(address(this), owner);
}
/**
* Proxy all other calls to pairsManager.
*/
function ()
external
payable
senderOrigin
{
// SECURITY: senderOrigin() modifier is mandatory
IEnergiswapPairsManager _pairsManager = IEnergiswapPairsManager(pairsManager());
// solium-disable-next-line security/no-inline-assembly
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize())
let res := call(sub(gas(), 10000), _pairsManager, 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: ../StorageBase.sol
// This file is part of Energi Core.
//
// Energi Core is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Energi Core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Energi Core. If not, see <http://www.gnu.org/licenses/>.
// Energi Governance system is the fundamental part of Energi Core.
// NOTE: It's not allowed to change the compiler due to byte-to-byte
// match requirement.
/**
* Base for contract storage (SC-14).
*
* NOTE: it MUST NOT change after blockchain launch!
*/
contract StorageBase {
address payable internal owner;
modifier requireOwner {
require(msg.sender == address(owner), "Not owner!");
_;
}
constructor() public {
owner = msg.sender;
}
function setOwner(IGovernedContract _newOwner) external requireOwner {
owner = address(uint160(address(_newOwner)));
}
function kill() external requireOwner {
selfdestruct(msg.sender);
}
}
// File: ../energiswapPair/IPairStorage.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/>.
interface IPairStorage {
function pairsManagerProxy() external view returns (address);
function kill() external;
function setReserves(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) external;
function setCumulativePrices(uint _price0CumulativeLast, uint _price1CumulativeLast) external;
function setKLast(uint _kLast) external;
function setUnlocked(uint _unlocked) external;
function getTokens()external view returns(address _token0, address _token1);
function getToken0()external view returns(address _token0);
function getToken1()external view returns(address _token1);
function getReserves() external view returns(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);
function getCumulativePrices() external view returns(uint _price0CumulativeLast, uint _price1CumulativeLast);
function getCumulativePrice0() external view returns(uint _price0CumulativeLast);
function getCumulativePrice1() external view returns(uint _price1CumulativeLast);
function getKLast() external view returns(uint _kLast);
function getUnlocked() external view returns(uint _unlocked);
}
// File: ../energiswapPair/PairStorage.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/>.
pragma solidity = 0.5.16;
contract PairStorage is IPairStorage {
address public pairsManagerProxy;
address private token0;
address private token1;
uint112 private reserve0;
uint112 private reserve1;
uint32 private blockTimestampLast;
// Used to track prices time series (see: https://uniswap.org/blog/uniswap-v2/)
uint private price0CumulativeLast;
uint private price1CumulativeLast;
uint private kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
uint private unlocked = 1;
modifier requirePairsManager {
require(msg.sender == address(IGovernedProxy(address(uint160(pairsManagerProxy))).impl()), "PairStorage: FORBIDDEN, not pairsManager");
_;
}
constructor(address _pairsManagerProxy, address _token0, address _token1) public {
pairsManagerProxy = _pairsManagerProxy;
token0 = _token0;
token1 = _token1;
}
// Self-destruct
function kill() external requirePairsManager {
selfdestruct(msg.sender);
}
function setReserves(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) external requirePairsManager {
reserve0 = _reserve0;
reserve1 = _reserve1;
blockTimestampLast = _blockTimestampLast;
}
function setCumulativePrices(uint _price0CumulativeLast, uint _price1CumulativeLast) external requirePairsManager {
price0CumulativeLast = _price0CumulativeLast;
price1CumulativeLast = _price1CumulativeLast;
}
function setKLast(uint _kLast) external requirePairsManager {
kLast = _kLast;
}
function setUnlocked(uint _unlocked) external requirePairsManager {
unlocked = _unlocked;
}
// Expose getter functions
function getTokens()external view returns(address _token0, address _token1) {
_token0 = token0;
_token1 = token1;
}
function getToken0()external view returns(address _token0) {
_token0 = token0;
}
function getToken1()external view returns(address _token1) {
_token1 = token1;
}
function getReserves() external view returns(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
_reserve0 = reserve0;
_reserve1 = reserve1;
_blockTimestampLast = blockTimestampLast;
}
function getCumulativePrices() external view returns(uint _price0CumulativeLast, uint _price1CumulativeLast) {
_price0CumulativeLast = price0CumulativeLast;
_price1CumulativeLast = price1CumulativeLast;
}
function getCumulativePrice0() external view returns(uint _price0CumulativeLast) {
_price0CumulativeLast = price0CumulativeLast;
}
function getCumulativePrice1() external view returns(uint _price1CumulativeLast) {
_price1CumulativeLast = price1CumulativeLast;
}
function getKLast() external view returns(uint _kLast) {
_kLast = kLast;
}
function getUnlocked() external view returns(uint _unlocked) {
_unlocked = unlocked;
}
}
// File: ../energiswapPair/IERC20Storage.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/>.
interface IERC20Storage {
function pairsERC20Proxy() external view returns (address);
function kill() external;
function setBalance(address _owner, uint _amount) external;
function setAllowance(address _owner, address _spender, uint _amount) external;
function setTotalSupply(uint _amount) external;
function setNonce(address _owner, uint _nonce) external;
function getBalance(address _account) external view returns(uint _balance);
function getAllowance(address _owner, address _spender) external view returns(uint _allowance);
function getTotalSupply() external view returns(uint _totalSupply);
function getNonce(address _account) external view returns(uint _nonce);
}
// File: ../energiswapPair/ERC20Storage.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/>.
pragma solidity = 0.5.16;
contract ERC20Storage is IERC20Storage {
address public pairsERC20Proxy;
mapping (address => uint) private balance;
mapping (address => mapping (address => uint)) private allowance;
uint private totalSupply;
mapping(address => uint) private nonce;
modifier requirePairsERC20 {
require(msg.sender == address(IGovernedProxy(address(uint160(pairsERC20Proxy))).impl()), "ERC20Storage: FORBIDDEN, not pairsERC20");
_;
}
constructor(address _pairsERC20Proxy) public {
pairsERC20Proxy = _pairsERC20Proxy;
}
// Self-destruct
function kill() external requirePairsERC20 {
selfdestruct(msg.sender);
}
// ERC20 functions
function setBalance(address _owner, uint _amount) external requirePairsERC20 {
balance[_owner] = _amount;
}
function setAllowance(address _owner, address _spender, uint _amount) external requirePairsERC20 {
allowance[_owner][_spender] = _amount;
}
function setTotalSupply(uint _amount) external requirePairsERC20 {
totalSupply = _amount;
}
function setNonce(address _owner, uint _nonce) external requirePairsERC20 {
nonce[_owner] = _nonce;
}
function getBalance(address _account) external view returns(uint _balance) {
_balance = balance[_account];
}
function getAllowance(address _owner, address _spender) external view returns(uint _allowance) {
_allowance = allowance[_owner][_spender];
}
function getTotalSupply() external view returns(uint _totalSupply){
_totalSupply = totalSupply;
}
function getNonce(address _account) external view returns(uint _nonce) {
_nonce = nonce[_account];
}
}
// File: IEnergiswapFactoryStorage.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/>.
interface IEnergiswapFactoryStorage {
function setFeeTo(address _feeTo) external;
function setFeeToSetter(address _feeToSetter) external;
function setRouterProxy(address _routerProxy) external;
function setPairsManagerProxy(address _pairsManagerProxy) external;
function setPairsERC20Proxy(address _pairsERC20Proxy) external;
function setPair(address token0, address token1, address _pair) external;
function pushPair(address _pair) external;
function getFeeTo() external view returns (address _feeTo);
function getFeeToSetter() external view returns (address _feeToSetter);
function getSporkProxy() external view returns (address _sporkProxy);
function getRouterProxy() external view returns (address _routerProxy);
function getPairsManagerProxy() external view returns (address _pairsManagerProxy);
function getPairsManager() external view returns (address _pairsManager);
function getPairsERC20Proxy() external view returns (address _pairsERC20Proxy);
function getPair(address token0, address token1) external view returns (address _pair);
function allPairs(uint index) external view returns (address _pair);
function allPairsLength() external view returns (uint _length);
}
// File: ../energiswapPairsManager/IEnergiswapPairsManagerGovernedProxy.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/>.
pragma solidity >=0.5.0;
interface IEnergiswapPairsManagerGovernedProxy {
event UpgradeProposal(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
event Upgraded(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
function impl() external view returns (address);
function spork_proxy() external view returns (address);
// function factoryProxy() external view returns (address);
// function registerPair(address _pairProxy, address _pairStorage, address _erc20Storage) external;
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 proxy() external view returns (address);
function migrate(IGovernedContract) external pure;
function destroy(IGovernedContract) external pure;
function () external payable;
}
// File: ../energiswapRouter/IEnergiswapRouterGovernedProxy.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/>.
pragma solidity >=0.5.0;
interface IEnergiswapRouterGovernedProxy {
event UpgradeProposal(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
event Upgraded(
IGovernedContract indexed impl,
IUpgradeProposal proposal
);
function impl() external view returns (address);
function spork_proxy() external view returns (address);
function safeTransferFrom(address token, address from, address to, uint value) external;
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 proxy() external view returns (address);
function migrate(IGovernedContract) external pure;
function destroy(IGovernedContract) external pure;
function () external payable;
}
// File: ../interfaces/IPausable.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.
/**
* @title Pausable Interface
*/
interface IPausable {
/**
* @dev Events
*/
event Masterpaused(address account, uint256 unpauseBlock);
event Paused(address account, uint256 unpauseBlock);
event Unpaused(address account);
/**
* @dev state variables
*/
function blockNumberWhenToUnpauseMasterPause() external view returns (uint256);
function blockNumberWhenToUnpausePause() external view returns (uint256);
/**
* @dev setter functions
*/
function masterPause(uint256 blocks) external;
function pause(uint256 blocks) external;
function unpause() external;
}
// File: EnergiswapFactory.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.
contract EnergiswapFactoryStorage is StorageBase, IEnergiswapFactoryStorage {
address private feeTo;
address private feeToSetter;
address private sporkProxy;
address private multicall;
address private routerProxy;
address private pairsManagerProxy;
address private pairsERC20Proxy;
mapping(address => mapping(address => address)) private pair; // token0 -> token1 -> pairProxy
address[] private _allPairs;
constructor(address _feeToSetter, address _sporkProxy) public {
feeToSetter = _feeToSetter;
sporkProxy = _sporkProxy;
}
function setFeeTo(address _feeTo) external requireOwner {
feeTo = _feeTo;
}
function setFeeToSetter(address _feeToSetter) external requireOwner {
feeToSetter = _feeToSetter;
}
function setRouterProxy(address _routerProxy) external requireOwner {
routerProxy = _routerProxy;
}
function setPairsManagerProxy(address _pairsManagerProxy) external requireOwner {
pairsManagerProxy = _pairsManagerProxy;
}
function setPairsERC20Proxy(address _pairsERC20Proxy) external requireOwner {
pairsERC20Proxy = _pairsERC20Proxy;
}
function setPair(address token0, address token1, address _pair) external requireOwner {
pair[token0][token1] = _pair;
}
function pushPair(address _pair) external requireOwner {
_allPairs.push(_pair);
}
function getFeeTo() external view returns (address _feeTo) {
_feeTo = feeTo;
}
function getFeeToSetter() external view returns (address _feeToSetter) {
_feeToSetter = feeToSetter;
}
function getSporkProxy() external view returns (address _sporkProxy) {
_sporkProxy = sporkProxy;
}
function getRouterProxy() external view returns (address _routerProxy) {
_routerProxy = routerProxy;
}
function getPairsManagerProxy() external view returns (address _pairsManagerProxy) {
_pairsManagerProxy = pairsManagerProxy;
}
function getPairsManager() external view returns (address _pairsManager) {
_pairsManager = address(IEnergiswapPairsManagerGovernedProxy(address(uint160(pairsManagerProxy))).impl());
}
function getPairsERC20Proxy() external view returns (address _pairsERC20Proxy) {
_pairsERC20Proxy = pairsERC20Proxy;
}
function getPair(address token0, address token1) external view returns (address _pair) {
_pair = pair[token0][token1];
}
function allPairs(uint index) external view returns (address _pair) {
_pair = _allPairs[index];
}
function allPairsLength() external view returns (uint _length) {
_length = _allPairs.length;
}
}
contract EnergiswapFactory is EnergiswapFactoryAutoProxy, IEnergiswapFactory {
bool public initialized = false;
EnergiswapFactoryStorage public _storage;
modifier requireFeeToSetter {
require(tx.origin == _storage.getFeeToSetter(), 'EnergiswapFactory: FORBIDDEN, not feeToSetter');
_;
}
modifier requireProxy {
require(msg.sender == proxy, 'EnergiswapFactory: FORBIDDEN, not proxy');
_;
}
/**
* @dev Modifier to make a function callable only when EnergiswapPairsManager contract is not paused.
*
* Requirements:
*
* - EnergiswapPairsManager must not be paused or masterPaused.
*/
modifier whenNotPaused {
require(block.number >= IPausable(_storage.getPairsManager()).blockNumberWhenToUnpausePause() &&
block.number >= IPausable(_storage.getPairsManager()).blockNumberWhenToUnpauseMasterPause(),
'Pausable: Revert - Code execution is paused');
_;
}
constructor(
address _feeToSetter,
address _sporkProxy,
address _proxy // If set to address(0), EnergiswapFactoryGovernedProxy will be deployed by EnergiswapFactoryAutoProxy
) public EnergiswapFactoryAutoProxy(
_proxy,
address(this),
address(uint160(_sporkProxy))
) {
_storage = new EnergiswapFactoryStorage(_feeToSetter, _sporkProxy); // Deploy EnergiswapFactoryStorage contract
}
// Initialize contract. This function can only be called once
function initialize(address _routerProxy, address _pairsManagerProxy, address _pairsERC20Proxy) external {
require(initialized == false, 'EnergiswapFactory: already initialized');
_storage.setRouterProxy(_routerProxy);
_storage.setPairsManagerProxy(_pairsManagerProxy);
_storage.setPairsERC20Proxy(_pairsERC20Proxy);
initialized = true;
}
// This function must be called in order to upgrade to a new EnergiswapFactory implementation
function destroy(address _newImpl) external requireProxy {
// Updates EnergiswapFactoryStorage contract with new EnergiswapFactory implementation address as owner
IStorageBase(address(_storage)).setOwner(_newImpl);
// Self destruct
_destroy(_newImpl);
}
// This function (placeholder) would be called on the new implementation if necessary for the upgrade
function migrate(address _oldImpl) external requireProxy {
_migrate(_oldImpl);
}
// Create pair
function createPair(
address tokenA,
address tokenB
) external whenNotPaused returns (address pairProxy) {
// Check that tokens addresses are not identical
require(tokenA != tokenB, 'EnergiswapFactory: IDENTICAL_TOKENS_ADDRESSES');
// Sort tokens addresses
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
// Check that no token address is zero
require(token0 != address(0), 'EnergiswapFactory: ZERO_ADDRESS');
// Check that pair does not already exist
require(_storage.getPair(token0, token1) == address(0), 'EnergiswapFactory: PAIR_EXISTS'); // single check is sufficient
// Deploy pair proxy via CREATE2
bytes memory bytecode = abi.encodePacked(
type(EnergiswapPairProxy).creationCode,
abi.encode(
_storage.getRouterProxy(),
_storage.getPairsManagerProxy(),
_storage.getPairsERC20Proxy()
)
);
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
assembly {
pairProxy := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
// Deploy new PairStorage contract
address pairStorage = address(new PairStorage(_storage.getPairsManagerProxy(), token0, token1));
// Deploy new ERC20Storage contract
address erc20Storage = address(new ERC20Storage(_storage.getPairsERC20Proxy()));
// Register pairProxy, pairStorage and erc20Storage addresses into EnergiswapPairsManager and
// EnergiswapPairsERC20 contracts
IEnergiswapPairsManager(address(uint160(_storage.getPairsManager()))).registerPair(pairProxy, pairStorage, erc20Storage);
// Register pairProxy address into EnergiswapFactoryStorage contract mapping with tokens addresses
_storage.setPair(token0, token1, pairProxy);
_storage.setPair(token1, token0, pairProxy); // populate mapping in the reverse direction
_storage.pushPair(pairProxy);
// Emit pair creation event
IEnergiswapFactoryGovernedProxy(address(uint160(proxy))).emitPairCreated(token0, token1, pairProxy, _storage.allPairsLength());
}
// Set feeTo address
function setFeeTo(address _feeTo) external requireFeeToSetter {
_storage.setFeeTo(_feeTo);
}
// Set feeToSetter address
function setFeeToSetter(address _feeToSetter) external requireFeeToSetter {
_storage.setFeeToSetter(_feeToSetter);
}
// Expose getter functions
function feeTo() external view returns (address _feeTo) {
_feeTo = _storage.getFeeTo();
}
function feeToSetter() external view returns (address _feeToSetter) {
_feeToSetter = _storage.getFeeToSetter();
}
function sporkProxy() external view returns (address _sporkProxy) {
_sporkProxy = _storage.getSporkProxy();
}
function getPair(address tokenA, address tokenB) external view returns (address _pair) {
_pair = _storage.getPair(tokenA, tokenB);
}
function allPairs(uint index) external view returns (address _pair) {
_pair = _storage.allPairs(index);
}
function allPairsLength() external view returns (uint) {
return _storage.allPairsLength();
}
}