Skip to main content

FeSwap Factory Contract


FeSwap Factory contract is the contract that manages all liquidity-pool contracts. Factory is responsible to create all the token-pair liquidity pools, and store the reference address to these pools.

Only the NFT owner of the corresponding token-pair has the right to create the owned liquidity pool contract. Two linked sub-pools are created for each token pair. The owner can also use Factory contract to config a few transaction parameters of the liquidity pool, mainly the arbitrage trigger rate, and the swapping profit receiver.

Factory Contract Address #

ETH NetWorkFeswap Factory Contract Address
ETH Mainnet0xEDc22C273ea25EeDA49F049e528150dBA367Da9A
ETH Testnet Ropsten0x75f7b730c51610aba6f3d89deb4864f156c8e747
ETH Testnet Rinkeby0x75f7b730c51610aba6f3d89deb4864f156c8e747
ETH Testnet Goerli0x1BdB1555bDc425183ad56FcB31c06205726FEFB0
ETH Testnet Kovan0x75f7b730c51610aba6f3d89deb4864f156c8e747

FeSwapFactory Code #

The open-source FeSwap Factory contact is stored at Github FeSwapCore Project

Following is the code deployed:

FeSwapFactory.sol
// SPDX-License-Identifier: MITpragma solidity =0.6.12;
import './interfaces/IFeSwapFactory.sol';import './FeSwapPair.sol';
contract FeSwapFactory is IFeSwapFactory {    uint64 public constant RATE_TRIGGER_FACTORY         = 10;       //  price difference be 1%    uint64 public constant RATE_CAP_TRIGGER_ARBITRAGE   = 50;       //  price difference < 5%    uint64 public constant RATE_PROFIT_SHARE            = 11;       //  Feswap and Pair owner share 1/12 of the swap profit, 11 means 1/12
    address public override factoryAdmin;    address public override feeTo;    address public override routerFeSwap;    uint64 public override rateTriggerFactory;    uint64 public override rateCapArbitrage;    uint64 public override rateProfitShare;                        // 1/X => rateProfitShare = (X-1)
    mapping(address => mapping(address => address)) public override getPair;    address[] public override allPairs;
    event PairCreated(address indexed tokenA, address indexed tokenB, address pairAAB, address pairABB, uint allPairsLength);    event PairOwnerChanged(address indexed pairAAB, address indexed pairABB, address oldOwner, address newOwner);
    constructor(address _factoryAdmin) public {                     //factoryAdmin will be set to TimeLock after Feswap works normally        factoryAdmin        = _factoryAdmin;        rateTriggerFactory  = RATE_TRIGGER_FACTORY;        rateCapArbitrage    = RATE_CAP_TRIGGER_ARBITRAGE;        rateProfitShare     = RATE_PROFIT_SHARE;     }
    function allPairsLength() external view override returns (uint) {        return allPairs.length;    }
        function getFeeInfo() external view override returns (address _feeTo, uint256 _rateProfitShare) {        return (feeTo, rateProfitShare);    }
    function createUpdatePair(address tokenA, address tokenB, address pairOwner, uint256 rateTrigger) external override returns (address pairAAB, address pairABB ) {        require(tokenA != tokenB, 'FeSwap: IDENTICAL_ADDRESSES');        // pairOwner allowed to zero to discard the profit        require(tokenA != address(0) && tokenB != address(0) && routerFeSwap != address(0) , 'FeSwap: ZERO_ADDRESS');        require((msg.sender == factoryAdmin) || (msg.sender == routerFeSwap) , 'FeSwap: FORBIDDEN');        require(rateTrigger <= rateCapArbitrage, 'FeSwap: GAP TOO MORE');
        pairAAB = getPair[tokenA][tokenB];        if(pairAAB != address(0)) {            pairABB = getPair[tokenB][tokenA];            address oldOwner = IFeSwapPair(pairAAB).pairOwner();            if(oldOwner!=pairOwner) {                IFeSwapPair(pairAAB).setOwner(pairOwner);           // Owner Security must be checked by Router                IFeSwapPair(pairABB).setOwner(pairOwner);                emit PairOwnerChanged(pairAAB, pairABB, oldOwner, pairOwner);            }            if(rateTrigger!=0)            {                rateTrigger = rateTrigger*6 + rateTriggerFactory*4 + 10000;     // base is 10000                IFeSwapPair(pairAAB).adjusArbitragetRate(rateTrigger);                 IFeSwapPair(pairABB).adjusArbitragetRate(rateTrigger);                            }        } else {            bytes memory bytecode = type(FeSwapPair).creationCode;            bytes32 saltAAB = keccak256(abi.encodePacked(tokenA, tokenB));            bytes32 saltABB = keccak256(abi.encodePacked(tokenB, tokenA));            assembly {                pairAAB := create2(0, add(bytecode, 32), mload(bytecode), saltAAB)                pairABB := create2(0, add(bytecode, 32), mload(bytecode), saltABB)            }
            if(rateTrigger == 0) rateTrigger = rateTriggerFactory;            rateTrigger = rateTrigger*6 + rateTriggerFactory*4 + 10000;
            IFeSwapPair(pairAAB).initialize(tokenA, tokenB, pairOwner, routerFeSwap, rateTrigger);            getPair[tokenA][tokenB] = pairAAB;            allPairs.push(pairAAB);
            IFeSwapPair(pairABB).initialize(tokenB, tokenA, pairOwner, routerFeSwap, rateTrigger);            getPair[tokenB][tokenA] = pairABB;            allPairs.push(pairABB);
            emit PairCreated(tokenA, tokenB, pairAAB, pairABB, allPairs.length);        }    }
    function setFeeTo(address _feeTo) external override {        require(msg.sender == factoryAdmin, 'FeSwap: FORBIDDEN');        feeTo = _feeTo;    }
    function setFactoryAdmin(address _factoryAdmin) external override {        require(msg.sender == factoryAdmin, 'FeSwap: FORBIDDEN');        factoryAdmin = _factoryAdmin;    }
    function setRouterFeSwap(address _routerFeSwap) external override {        require(msg.sender == factoryAdmin, 'FeSwap: FORBIDDEN');        routerFeSwap = _routerFeSwap;                                         // for Router Initiation    }    
    function configFactory(uint64 newTriggerRate, uint64 newRateCap, uint64 newProfitShareRate) external override {        require(msg.sender == factoryAdmin, 'FeSwap: FORBIDDEN');        rateTriggerFactory  = newTriggerRate;        rateCapArbitrage    = newRateCap;        rateProfitShare     = newProfitShareRate;                   // 1/X => rateProfitShare = (X-1)    }         // Function to update Router in case of emergence, factoryAdmin will be set to TimeLock after Feswap works normally    // routerFeSwap must be secured and absolutely cannot be replaced uncontrolly.    function managePair(address _tokenA, address _tokenB, address _pairOwner, address _routerFeSwap) external override {        require(msg.sender == factoryAdmin, 'FeSwap: FORBIDDEN');        address pairAAB = getPair[_tokenA][_tokenB];        address pairABB = getPair[_tokenB][_tokenA];                require(pairAAB != address(0), 'FeSwap: NO TOKEN PAIR');        IFeSwapPair(pairAAB).initialize(_tokenA, _tokenB, _pairOwner, _routerFeSwap, 0);        IFeSwapPair(pairABB).initialize(_tokenB, _tokenA, _pairOwner, _routerFeSwap, 0);    } }