@pollum-io/pegasys-protocol
Version:
Contracts for the Pegasys Dex.
46 lines • 5.72 MB
JSON
{
"id": "ccec1582c8263ea0d9b8e8185e39d388",
"_format": "hh-sol-build-info-1",
"solcVersion": "0.5.16",
"solcLongVersion": "0.5.16+commit.9c3226ce",
"input": {
"language": "Solidity",
"sources": {
"contracts/pegasys-core/PegasysPair.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity =0.5.16;\n\nimport \"./interfaces/IPegasysPair.sol\";\nimport \"./PegasysERC20.sol\";\nimport \"./libraries/Math.sol\";\nimport \"./libraries/UQ112x112.sol\";\nimport \"./interfaces/IERC20.sol\";\nimport \"./interfaces/IPegasysFactory.sol\";\nimport \"./interfaces/IPegasysCallee.sol\";\n\ncontract PegasysPair is IPegasysPair, PegasysERC20 {\n using SafeMath for uint256;\n using UQ112x112 for uint224;\n\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n bytes4 private constant SELECTOR =\n bytes4(keccak256(bytes(\"transfer(address,uint256)\")));\n\n address public factory;\n address public token0;\n address public token1;\n\n uint112 private reserve0; // uses single storage slot, accessible via getReserves\n uint112 private reserve1; // uses single storage slot, accessible via getReserves\n uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves\n\n uint256 public price0CumulativeLast;\n uint256 public price1CumulativeLast;\n uint256 public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event\n\n uint256 private unlocked = 1;\n modifier lock() {\n require(unlocked == 1, \"Pegasys: LOCKED\");\n unlocked = 0;\n _;\n unlocked = 1;\n }\n\n function getReserves()\n public\n view\n returns (\n uint112 _reserve0,\n uint112 _reserve1,\n uint32 _blockTimestampLast\n )\n {\n _reserve0 = reserve0;\n _reserve1 = reserve1;\n _blockTimestampLast = blockTimestampLast;\n }\n\n function _safeTransfer(\n address token,\n address to,\n uint256 value\n ) private {\n (bool success, bytes memory data) = token.call(\n abi.encodeWithSelector(SELECTOR, to, value)\n );\n require(\n success && (data.length == 0 || abi.decode(data, (bool))),\n \"Pegasys: TRANSFER_FAILED\"\n );\n }\n\n event Mint(address indexed sender, uint256 amount0, uint256 amount1);\n event Burn(\n address indexed sender,\n uint256 amount0,\n uint256 amount1,\n address indexed to\n );\n event Swap(\n address indexed sender,\n uint256 amount0In,\n uint256 amount1In,\n uint256 amount0Out,\n uint256 amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n constructor() public {\n factory = msg.sender;\n }\n\n // called once by the factory at time of deployment\n function initialize(address _token0, address _token1) external {\n require(msg.sender == factory, \"Pegasys: FORBIDDEN\"); // sufficient check\n token0 = _token0;\n token1 = _token1;\n }\n\n // update reserves and, on the first call per block, price accumulators\n function _update(\n uint256 balance0,\n uint256 balance1,\n uint112 _reserve0,\n uint112 _reserve1\n ) private {\n require(\n balance0 <= uint112(-1) && balance1 <= uint112(-1),\n \"Pegasys: OVERFLOW\"\n );\n uint32 blockTimestamp = uint32(block.timestamp % 2**32);\n uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired\n if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {\n // * never overflows, and + overflow is desired\n price0CumulativeLast +=\n uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) *\n timeElapsed;\n price1CumulativeLast +=\n uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) *\n timeElapsed;\n }\n reserve0 = uint112(balance0);\n reserve1 = uint112(balance1);\n blockTimestampLast = blockTimestamp;\n emit Sync(reserve0, reserve1);\n }\n\n // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)\n function _mintFee(uint112 _reserve0, uint112 _reserve1)\n private\n returns (bool feeOn)\n {\n address feeTo = IPegasysFactory(factory).feeTo();\n feeOn = feeTo != address(0);\n uint256 _kLast = kLast; // gas savings\n if (feeOn) {\n if (_kLast != 0) {\n uint256 rootK = Math.sqrt(uint256(_reserve0).mul(_reserve1));\n uint256 rootKLast = Math.sqrt(_kLast);\n if (rootK > rootKLast) {\n uint256 numerator = totalSupply.mul(rootK.sub(rootKLast));\n uint256 denominator = rootK.mul(5).add(rootKLast);\n uint256 liquidity = numerator / denominator;\n if (liquidity > 0) _mint(feeTo, liquidity);\n }\n }\n } else if (_kLast != 0) {\n kLast = 0;\n }\n }\n\n // this low-level function should be called from a contract which performs important safety checks\n function mint(address to) external lock returns (uint256 liquidity) {\n (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings\n uint256 balance0 = IERC20(token0).balanceOf(address(this));\n uint256 balance1 = IERC20(token1).balanceOf(address(this));\n uint256 amount0 = balance0.sub(_reserve0);\n uint256 amount1 = balance1.sub(_reserve1);\n\n bool feeOn = _mintFee(_reserve0, _reserve1);\n uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee\n if (_totalSupply == 0) {\n liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);\n _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens\n } else {\n liquidity = Math.min(\n amount0.mul(_totalSupply) / _reserve0,\n amount1.mul(_totalSupply) / _reserve1\n );\n }\n require(liquidity > 0, \"Pegasys: INSUFFICIENT_LIQUIDITY_MINTED\");\n _mint(to, liquidity);\n\n _update(balance0, balance1, _reserve0, _reserve1);\n if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date\n emit Mint(msg.sender, amount0, amount1);\n }\n\n // this low-level function should be called from a contract which performs important safety checks\n function burn(address to)\n external\n lock\n returns (uint256 amount0, uint256 amount1)\n {\n (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings\n address _token0 = token0; // gas savings\n address _token1 = token1; // gas savings\n uint256 balance0 = IERC20(_token0).balanceOf(address(this));\n uint256 balance1 = IERC20(_token1).balanceOf(address(this));\n uint256 liquidity = balanceOf[address(this)];\n\n bool feeOn = _mintFee(_reserve0, _reserve1);\n uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee\n amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution\n amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution\n require(\n amount0 > 0 && amount1 > 0,\n \"Pegasys: INSUFFICIENT_LIQUIDITY_BURNED\"\n );\n _burn(address(this), liquidity);\n _safeTransfer(_token0, to, amount0);\n _safeTransfer(_token1, to, amount1);\n balance0 = IERC20(_token0).balanceOf(address(this));\n balance1 = IERC20(_token1).balanceOf(address(this));\n\n _update(balance0, balance1, _reserve0, _reserve1);\n if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date\n emit Burn(msg.sender, amount0, amount1, to);\n }\n\n // this low-level function should be called from a contract which performs important safety checks\n function swap(\n uint256 amount0Out,\n uint256 amount1Out,\n address to,\n bytes calldata data\n ) external lock {\n require(\n amount0Out > 0 || amount1Out > 0,\n \"Pegasys: INSUFFICIENT_OUTPUT_AMOUNT\"\n );\n (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings\n require(\n amount0Out < _reserve0 && amount1Out < _reserve1,\n \"Pegasys: INSUFFICIENT_LIQUIDITY\"\n );\n\n uint256 balance0;\n uint256 balance1;\n {\n // scope for _token{0,1}, avoids stack too deep errors\n address _token0 = token0;\n address _token1 = token1;\n require(to != _token0 && to != _token1, \"Pegasys: INVALID_TO\");\n if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens\n if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens\n if (data.length > 0)\n IPegasysCallee(to).pegasysCall(\n msg.sender,\n amount0Out,\n amount1Out,\n data\n );\n balance0 = IERC20(_token0).balanceOf(address(this));\n balance1 = IERC20(_token1).balanceOf(address(this));\n }\n uint256 amount0In = balance0 > _reserve0 - amount0Out\n ? balance0 - (_reserve0 - amount0Out)\n : 0;\n uint256 amount1In = balance1 > _reserve1 - amount1Out\n ? balance1 - (_reserve1 - amount1Out)\n : 0;\n require(\n amount0In > 0 || amount1In > 0,\n \"Pegasys: INSUFFICIENT_INPUT_AMOUNT\"\n );\n {\n // scope for reserve{0,1}Adjusted, avoids stack too deep errors\n uint256 balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));\n uint256 balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));\n require(\n balance0Adjusted.mul(balance1Adjusted) >=\n uint256(_reserve0).mul(_reserve1).mul(1000**2),\n \"Pegasys: K\"\n );\n }\n\n _update(balance0, balance1, _reserve0, _reserve1);\n emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);\n }\n\n // force balances to match reserves\n function skim(address to) external lock {\n address _token0 = token0; // gas savings\n address _token1 = token1; // gas savings\n _safeTransfer(\n _token0,\n to,\n IERC20(_token0).balanceOf(address(this)).sub(reserve0)\n );\n _safeTransfer(\n _token1,\n to,\n IERC20(_token1).balanceOf(address(this)).sub(reserve1)\n );\n }\n\n // force reserves to match balances\n function sync() external lock {\n _update(\n IERC20(token0).balanceOf(address(this)),\n IERC20(token1).balanceOf(address(this)),\n reserve0,\n reserve1\n );\n }\n}\n"
},
"contracts/pegasys-core/interfaces/IPegasysPair.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysPair {\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function name() external pure returns (string memory);\n\n function symbol() external pure returns (string memory);\n\n function decimals() external pure returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n function nonces(address owner) external view returns (uint256);\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n event Mint(address indexed sender, uint256 amount0, uint256 amount1);\n event Burn(\n address indexed sender,\n uint256 amount0,\n uint256 amount1,\n address indexed to\n );\n event Swap(\n address indexed sender,\n uint256 amount0In,\n uint256 amount1In,\n uint256 amount0Out,\n uint256 amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n function MINIMUM_LIQUIDITY() external pure returns (uint256);\n\n function factory() external view returns (address);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function getReserves()\n external\n view\n returns (\n uint112 reserve0,\n uint112 reserve1,\n uint32 blockTimestampLast\n );\n\n function price0CumulativeLast() external view returns (uint256);\n\n function price1CumulativeLast() external view returns (uint256);\n\n function kLast() external view returns (uint256);\n\n function mint(address to) external returns (uint256 liquidity);\n\n function burn(address to)\n external\n returns (uint256 amount0, uint256 amount1);\n\n function swap(\n uint256 amount0Out,\n uint256 amount1Out,\n address to,\n bytes calldata data\n ) external;\n\n function skim(address to) external;\n\n function sync() external;\n\n function initialize(address, address) external;\n}\n"
},
"contracts/pegasys-core/PegasysERC20.sol": {
"content": "pragma solidity =0.5.16;\n\nimport \"./interfaces/IPegasysERC20.sol\";\nimport \"./libraries/SafeMath.sol\";\n\ncontract PegasysERC20 is IPegasysERC20 {\n using SafeMath for uint256;\n\n string public constant name = \"Pegasys LP Token\";\n string public constant symbol = \"PLP\";\n uint8 public constant decimals = 18;\n uint256 public totalSupply;\n mapping(address => uint256) public balanceOf;\n mapping(address => mapping(address => uint256)) public allowance;\n\n bytes32 public DOMAIN_SEPARATOR;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint256) public nonces;\n\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n constructor() public {\n uint256 chainId;\n assembly {\n chainId := chainid\n }\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n ),\n keccak256(bytes(name)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n function _mint(address to, uint256 value) internal {\n totalSupply = totalSupply.add(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(address(0), to, value);\n }\n\n function _burn(address from, uint256 value) internal {\n balanceOf[from] = balanceOf[from].sub(value);\n totalSupply = totalSupply.sub(value);\n emit Transfer(from, address(0), value);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 value\n ) private {\n allowance[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 value\n ) private {\n balanceOf[from] = balanceOf[from].sub(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function approve(address spender, uint256 value) external returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transfer(address to, uint256 value) external returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool) {\n if (allowance[from][msg.sender] != uint256(-1)) {\n allowance[from][msg.sender] = allowance[from][msg.sender].sub(\n value\n );\n }\n _transfer(from, to, value);\n return true;\n }\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n require(deadline >= block.timestamp, \"Pegasys: EXPIRED\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(\n recoveredAddress != address(0) && recoveredAddress == owner,\n \"Pegasys: INVALID_SIGNATURE\"\n );\n _approve(owner, spender, value);\n }\n}\n"
},
"contracts/pegasys-core/libraries/Math.sol": {
"content": "pragma solidity =0.5.16;\n\n// a library for performing various math operations\n\nlibrary Math {\n function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n z = x < y ? x : y;\n }\n\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n function sqrt(uint256 y) internal pure returns (uint256 z) {\n if (y > 3) {\n z = y;\n uint256 x = y / 2 + 1;\n while (x < z) {\n z = x;\n x = (y / x + x) / 2;\n }\n } else if (y != 0) {\n z = 1;\n }\n }\n}\n"
},
"contracts/pegasys-core/libraries/UQ112x112.sol": {
"content": "pragma solidity =0.5.16;\n\n// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))\n\n// range: [0, 2**112 - 1]\n// resolution: 1 / 2**112\n\nlibrary UQ112x112 {\n uint224 constant Q112 = 2**112;\n\n // encode a uint112 as a UQ112x112\n function encode(uint112 y) internal pure returns (uint224 z) {\n z = uint224(y) * Q112; // never overflows\n }\n\n // divide a UQ112x112 by a uint112, returning a UQ112x112\n function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {\n z = x / uint224(y);\n }\n}\n"
},
"contracts/pegasys-core/interfaces/IERC20.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IERC20 {\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool);\n}\n"
},
"contracts/pegasys-core/interfaces/IPegasysFactory.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysFactory {\n event PairCreated(\n address indexed token0,\n address indexed token1,\n address pair,\n uint256\n );\n\n function feeTo() external view returns (address);\n\n function feeToSetter() external view returns (address);\n\n function getPair(address tokenA, address tokenB)\n external\n view\n returns (address pair);\n\n function allPairs(uint256) external view returns (address pair);\n\n function allPairsLength() external view returns (uint256);\n\n function createPair(address tokenA, address tokenB)\n external\n returns (address pair);\n\n function setFeeTo(address) external;\n\n function setFeeToSetter(address) external;\n}\n"
},
"contracts/pegasys-core/interfaces/IPegasysCallee.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysCallee {\n function pegasysCall(\n address sender,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n}\n"
},
"contracts/pegasys-core/interfaces/IPegasysERC20.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysERC20 {\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function name() external pure returns (string memory);\n\n function symbol() external pure returns (string memory);\n\n function decimals() external pure returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n function nonces(address owner) external view returns (uint256);\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n"
},
"contracts/pegasys-core/libraries/SafeMath.sol": {
"content": "// SPDX-License-Identifier: GNU\npragma solidity =0.5.16;\n\n// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)\n\nlibrary SafeMath {\n function add(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x + y) >= x, \"ds-math-add-overflow\");\n }\n\n function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x - y) <= x, \"ds-math-sub-underflow\");\n }\n\n function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require(y == 0 || (z = x * y) / y == x, \"ds-math-mul-overflow\");\n }\n}\n"
},
"contracts/pegasys-core/test/ERC20.sol": {
"content": "pragma solidity =0.5.16;\n\nimport \"../PegasysERC20.sol\";\n\ncontract ERC20 is PegasysERC20 {\n constructor(uint256 _totalSupply) public {\n _mint(msg.sender, _totalSupply);\n }\n}\n"
},
"contracts/pegasys-core/PegasysFactory.sol": {
"content": "pragma solidity =0.5.16;\n\nimport \"./interfaces/IPegasysFactory.sol\";\nimport \"./PegasysPair.sol\";\n\ncontract PegasysFactory is IPegasysFactory {\n address public feeTo;\n address public feeToSetter;\n\n mapping(address => mapping(address => address)) public getPair;\n address[] public allPairs;\n\n event PairCreated(\n address indexed token0,\n address indexed token1,\n address pair,\n uint256\n );\n\n constructor(address _feeToSetter) public {\n feeToSetter = _feeToSetter;\n }\n\n function allPairsLength() external view returns (uint256) {\n return allPairs.length;\n }\n\n function createPair(address tokenA, address tokenB)\n external\n returns (address pair)\n {\n require(tokenA != tokenB, \"Pegasys: IDENTICAL_ADDRESSES\");\n (address token0, address token1) = tokenA < tokenB\n ? (tokenA, tokenB)\n : (tokenB, tokenA);\n require(token0 != address(0), \"Pegasys: ZERO_ADDRESS\");\n require(getPair[token0][token1] == address(0), \"Pegasys: PAIR_EXISTS\"); // single check is sufficient\n bytes memory bytecode = type(PegasysPair).creationCode;\n bytes32 salt = keccak256(abi.encodePacked(token0, token1));\n assembly {\n pair := create2(0, add(bytecode, 32), mload(bytecode), salt)\n }\n IPegasysPair(pair).initialize(token0, token1);\n getPair[token0][token1] = pair;\n getPair[token1][token0] = pair; // populate mapping in the reverse direction\n allPairs.push(pair);\n emit PairCreated(token0, token1, pair, allPairs.length);\n }\n\n function setFeeTo(address _feeTo) external {\n require(msg.sender == feeToSetter, \"Pegasys: FORBIDDEN\");\n feeTo = _feeTo;\n }\n\n function setFeeToSetter(address _feeToSetter) external {\n require(msg.sender == feeToSetter, \"Pegasys: FORBIDDEN\");\n feeToSetter = _feeToSetter;\n }\n}\n"
},
"contracts/flatten/PegasysFactoryFlatten.sol": {
"content": "// Sources flattened with hardhat v2.7.0 https://hardhat.org\n\n// File contracts/pegasys-core/interfaces/IPegasysFactory.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysFactory {\n event PairCreated(\n address indexed token0,\n address indexed token1,\n address pair,\n uint256\n );\n\n function feeTo() external view returns (address);\n\n function feeToSetter() external view returns (address);\n\n function getPair(address tokenA, address tokenB)\n external\n view\n returns (address pair);\n\n function allPairs(uint256) external view returns (address pair);\n\n function allPairsLength() external view returns (uint256);\n\n function createPair(address tokenA, address tokenB)\n external\n returns (address pair);\n\n function setFeeTo(address) external;\n\n function setFeeToSetter(address) external;\n}\n\n// File contracts/pegasys-core/interfaces/IPegasysPair.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysPair {\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function name() external pure returns (string memory);\n\n function symbol() external pure returns (string memory);\n\n function decimals() external pure returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n function nonces(address owner) external view returns (uint256);\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n event Mint(address indexed sender, uint256 amount0, uint256 amount1);\n event Burn(\n address indexed sender,\n uint256 amount0,\n uint256 amount1,\n address indexed to\n );\n event Swap(\n address indexed sender,\n uint256 amount0In,\n uint256 amount1In,\n uint256 amount0Out,\n uint256 amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n function MINIMUM_LIQUIDITY() external pure returns (uint256);\n\n function factory() external view returns (address);\n\n function token0() external view returns (address);\n\n function token1() external view returns (address);\n\n function getReserves()\n external\n view\n returns (\n uint112 reserve0,\n uint112 reserve1,\n uint32 blockTimestampLast\n );\n\n function price0CumulativeLast() external view returns (uint256);\n\n function price1CumulativeLast() external view returns (uint256);\n\n function kLast() external view returns (uint256);\n\n function mint(address to) external returns (uint256 liquidity);\n\n function burn(address to)\n external\n returns (uint256 amount0, uint256 amount1);\n\n function swap(\n uint256 amount0Out,\n uint256 amount1Out,\n address to,\n bytes calldata data\n ) external;\n\n function skim(address to) external;\n\n function sync() external;\n\n function initialize(address, address) external;\n}\n\n// File contracts/pegasys-core/interfaces/IPegasysERC20.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysERC20 {\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function name() external pure returns (string memory);\n\n function symbol() external pure returns (string memory);\n\n function decimals() external pure returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool);\n\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n function PERMIT_TYPEHASH() external pure returns (bytes32);\n\n function nonces(address owner) external view returns (uint256);\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n\n// File contracts/pegasys-core/libraries/SafeMath.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity =0.5.16;\n\n// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)\n\nlibrary SafeMath {\n function add(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x + y) >= x, \"ds-math-add-overflow\");\n }\n\n function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require((z = x - y) <= x, \"ds-math-sub-underflow\");\n }\n\n function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {\n require(y == 0 || (z = x * y) / y == x, \"ds-math-mul-overflow\");\n }\n}\n\n// File contracts/pegasys-core/PegasysERC20.sol\n\npragma solidity =0.5.16;\n\ncontract PegasysERC20 is IPegasysERC20 {\n using SafeMath for uint256;\n\n string public constant name = \"Pegasys LP Token\";\n string public constant symbol = \"PLP\";\n uint8 public constant decimals = 18;\n uint256 public totalSupply;\n mapping(address => uint256) public balanceOf;\n mapping(address => mapping(address => uint256)) public allowance;\n\n bytes32 public DOMAIN_SEPARATOR;\n // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public constant PERMIT_TYPEHASH =\n 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n mapping(address => uint256) public nonces;\n\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n constructor() public {\n uint256 chainId;\n assembly {\n chainId := chainid\n }\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n ),\n keccak256(bytes(name)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n function _mint(address to, uint256 value) internal {\n totalSupply = totalSupply.add(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(address(0), to, value);\n }\n\n function _burn(address from, uint256 value) internal {\n balanceOf[from] = balanceOf[from].sub(value);\n totalSupply = totalSupply.sub(value);\n emit Transfer(from, address(0), value);\n }\n\n function _approve(\n address owner,\n address spender,\n uint256 value\n ) private {\n allowance[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _transfer(\n address from,\n address to,\n uint256 value\n ) private {\n balanceOf[from] = balanceOf[from].sub(value);\n balanceOf[to] = balanceOf[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function approve(address spender, uint256 value) external returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transfer(address to, uint256 value) external returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool) {\n if (allowance[from][msg.sender] != uint256(-1)) {\n allowance[from][msg.sender] = allowance[from][msg.sender].sub(\n value\n );\n }\n _transfer(from, to, value);\n return true;\n }\n\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n require(deadline >= block.timestamp, \"Pegasys: EXPIRED\");\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n value,\n nonces[owner]++,\n deadline\n )\n )\n )\n );\n address recoveredAddress = ecrecover(digest, v, r, s);\n require(\n recoveredAddress != address(0) && recoveredAddress == owner,\n \"Pegasys: INVALID_SIGNATURE\"\n );\n _approve(owner, spender, value);\n }\n}\n\n// File contracts/pegasys-core/libraries/Math.sol\n\npragma solidity =0.5.16;\n\n// a library for performing various math operations\n\nlibrary Math {\n function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n z = x < y ? x : y;\n }\n\n // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n function sqrt(uint256 y) internal pure returns (uint256 z) {\n if (y > 3) {\n z = y;\n uint256 x = y / 2 + 1;\n while (x < z) {\n z = x;\n x = (y / x + x) / 2;\n }\n } else if (y != 0) {\n z = 1;\n }\n }\n}\n\n// File contracts/pegasys-core/libraries/UQ112x112.sol\n\npragma solidity =0.5.16;\n\n// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))\n\n// range: [0, 2**112 - 1]\n// resolution: 1 / 2**112\n\nlibrary UQ112x112 {\n uint224 constant Q112 = 2**112;\n\n // encode a uint112 as a UQ112x112\n function encode(uint112 y) internal pure returns (uint224 z) {\n z = uint224(y) * Q112; // never overflows\n }\n\n // divide a UQ112x112 by a uint112, returning a UQ112x112\n function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {\n z = x / uint224(y);\n }\n}\n\n// File contracts/pegasys-core/interfaces/IERC20.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IERC20 {\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function transferFrom(\n address from,\n address to,\n uint256 value\n ) external returns (bool);\n}\n\n// File contracts/pegasys-core/interfaces/IPegasysCallee.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity >=0.5.0;\n\ninterface IPegasysCallee {\n function pegasysCall(\n address sender,\n uint256 amount0,\n uint256 amount1,\n bytes calldata data\n ) external;\n}\n\n// File contracts/pegasys-core/PegasysPair.sol\n\n// SPDX-License-Identifier: GNU\npragma solidity =0.5.16;\n\ncontract PegasysPair is IPegasysPair, PegasysERC20 {\n using SafeMath for uint256;\n using UQ112x112 for uint224;\n\n uint256 public constant MINIMUM_LIQUIDITY = 10**3;\n bytes4 private constant SELECTOR =\n bytes4(keccak256(bytes(\"transfer(address,uint256)\")));\n\n address public factory;\n address public token0;\n address public token1;\n\n uint112 private reserve0; // uses single storage slot, accessible via getReserves\n uint112 private reserve1; // uses single storage slot, accessible via getReserves\n uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves\n\n uint256 public price0CumulativeLast;\n uint256 public price1CumulativeLast;\n uint256 public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event\n\n uint256 private unlocked = 1;\n modifier lock() {\n require(unlocked == 1, \"Pegasys: LOCKED\");\n unlocked = 0;\n _;\n unlocked = 1;\n }\n\n function getReserves()\n public\n view\n returns (\n uint112 _reserve0,\n uint112 _reserve1,\n uint32 _blockTimestampLast\n )\n {\n _reserve0 = reserve0;\n _reserve1 = reserve1;\n _blockTimestampLast = blockTimestampLast;\n }\n\n function _safeTransfer(\n address token,\n address to,\n uint256 value\n ) private {\n (bool success, bytes memory data) = token.call(\n abi.encodeWithSelector(SELECTOR, to, value)\n );\n require(\n success && (data.length == 0 || abi.decode(data, (bool))),\n \"Pegasys: TRANSFER_FAILED\"\n );\n }\n\n event Mint(address indexed sender, uint256 amount0, uint256 amount1);\n event Burn(\n address indexed sender,\n uint256 amount0,\n uint256 amount1,\n address indexed to\n );\n event Swap(\n address indexed sender,\n uint256 amount0In,\n uint256 amount1In,\n uint256 amount0Out,\n uint256 amount1Out,\n address indexed to\n );\n event Sync(uint112 reserve0, uint112 reserve1);\n\n constructor() public {\n factory = msg.sender;\n }\n\n // called once by the factory at time of deployment\n function initialize(address _token0, address _token1) external {\n require(msg.sender == factory, \"Pegasys: FORBIDDEN\"); // sufficient check\n token0 = _token0;\n token1 = _token1;\n }\n\n // update reserves and, on the first call per block, price accumulators\n function _update(\n uint256 balance0,\n uint256 balance1,\n uint112 _reserve0,\n uint112 _reserve1\n ) private {\n require(\n balance0 <= uint112(-1) && balance1 <= uint112(-1),\n \"Pegasys: OVERFLOW\"\n );\n uint32 blockTimestamp = uint32(block.timestamp % 2**32);\n uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired\n if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {\n // * never overflows, and + overflow is desired\n price0CumulativeLast +=\n uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) *\n timeElapsed;\n price1CumulativeLast +=\n uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) *\n timeElapsed;\n }\n reserve0 = uint112(balance0);\n reserve1 = uint112(balance1);\n blockTimestampLast = blockTimestamp;\n emit Sync(reserve0, reserve1);\n }\n\n // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)\n function _mintFee(uint112 _reserve0, uint112 _reserve1)\n private\n returns (bool feeOn)\n {\n address feeTo = IPegasysFactory(factory).feeTo();\n feeOn = feeTo != address(0);\n uint256 _kLast = kLast; // gas savings\n if (feeOn) {\n if (_kLast != 0) {\n uint256 rootK = Math.sqrt(uint256(_reserve0).mul(_reserve1));\n uint256 rootKLast = Math.sqrt(_kLast);\n if (rootK > rootKLast) {\n uint256 numerator = totalSupply.mul(rootK.sub(rootKLast));\n uint256 denominator = rootK.mul(5).add(rootKLast);\n uint256 liquidity = numerator / denominator;\n if (liquidity > 0) _mint(feeTo, liquidity);\n }\n }\n } else if (_kLast != 0) {\n kLast = 0;\n }\n }\n\n // this low-level function should be called from a contract which performs important safety checks\n function mint(address to) external lock returns (uint256 liquidity) {\n (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings\n uint256 balance0 = IERC20(token0).balanceOf(address(this));\n uint256 balance1 = IERC20(token1).balanceOf(address(this));\n uint256 amount0 = balance0.sub(_reserve0);\n uint256 amount1 = balance1.sub(_reserve1);\n\n bool feeOn = _mintFee(_reserve0, _reserve1);\n uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee\n if (_totalSupply == 0) {\n liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);\n _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens\n } else {\n liquidity = Math.min(\n amount0.mul(_totalSupply) / _reserve0,\n amount1.mul(_totalSupply) / _reserve1\n );\n }\n require(liquidity > 0, \"Pegasys: INSUFFICIENT_LIQUIDITY_MINTED\");\n _mint(to, liquidity);\n\n _update(balance0, balance1, _reserve0, _reserve1);\n if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date\n emit Mint(msg.sender, amount0, amount1);\n }\n\n // this low-level function should be called from a contract which performs important safety checks\n function burn(address to)\n external\n lock\n returns (uint256 amount0, uint256 amount1)\n {\n (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings\n address _token0 = token0; // gas savings\n address _token1 = token1; // gas savings\n uint256 balance0 = IERC20(_token0).balanceOf(address(this));\n uint256 balance1 = IERC20(_token1).balanceOf(address(this));\n uint256 liquidity = balanceOf[address(this)];\n\n bool feeOn = _mintFee(_reserve0, _reserve1);\n uint256 _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee\n amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution\n amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution\n require(\n amount0 > 0 && amount1 > 0,\n \"Pegasys: INSUFFICIENT_LIQUIDITY_BURNED\"\n );\n _burn(address(this), liquidity);\n _safeTransfer(_token0, to, amount0);\n _safeTransfer(_token1, to, amount1);\n balance0 = IERC20(_token0).balanceOf(address(this));\n balance1 = IERC20(_token1).balanceOf(address(this));\n\n _update(balance0, balance1, _reserve0, _reserve1);\n if (feeOn) kLast = uint256(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date\n emit Burn(msg.sender, amount0, amount1, to);\n }\n\n // this low-level function should be called from a contract which performs important safety checks\n function swap(\n uint256 amount0Out,\n uint256 amount1Out,\n address to,\n bytes calldata data\n ) external lock {\n require(\n amount0Out > 0 || amount1Out > 0,\n \"Pegasys: INSUFFICIENT_OUTPUT_AMOUNT\"\n );\n (uint112 _reserve0, uint112 _reserve1, ) = getReserves(); // gas savings\n require(\n amount0Out < _reserve0 && amount1Out < _reserve1,\n \"Pegasys: INSUFFICIENT_LIQUIDITY\"\n );\n\n uint256 balance0;\n uint256 balance1;\n {\n // scope for _token{0,1}, avoids stack too deep errors\n address _token0 = token0;\n address _token1 = token1;\n require(to != _token0 && to != _token1, \"Pegasys: INVALID_TO\");\n if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens\n if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens\n if (data.length > 0)\n IPegasysCallee(to).pegasysCall(\n msg.sender,\n amount0Out,\n amount1Out,\n data\n );\n balance0 = IERC20(_token0).balanceOf(address(this));\n balance1 = IERC20(_token1).balanceOf(address(this));\n }\n uint256 amount0In = balance0 > _reserve0 - amount0Out\n ? balance0 - (_reserve0 - amount0Out)\n : 0;\n uint256 amount1In = balance1 > _reserve1 - amount1Out\n ? balance1 - (_reserve1 - amount1Out)\n : 0;\n require(\n amount0In > 0 || amount1In > 0,\n \"Pegasys: INSUFFICIENT_INPUT_AMOUNT\"\n );\n {\n // scope for reserve{0,1}Adjusted, avoids stack too deep errors\n uint