This contract's source code is verified! Compiler
0.7.6+commit.7338295f
File 1 of 12: AbstractERC20.sol
pragma solidity 0.7.6;
import '../interfaces/ITwapERC20.sol' ;
import './SafeMath.sol' ;
abstract contract AbstractERC20 is ITwapERC20 {
using SafeMath for uint256 ;
string public override name;
string public override symbol;
uint8 public override decimals;
uint256 public override totalSupply;
mapping (address = > uint256 ) public override balanceOf;
mapping (address = > mapping (address = > uint256 )) public override allowance;
bytes32 public constant DOMAIN_TYPEHASH =
keccak256 ('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' );
bytes32 public constant override PERMIT_TYPEHASH =
0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9 ;
mapping (address = > uint256 ) public override nonces;
function _mint (address to, uint256 value ) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(address (0 ), to, value);
}
function _burn (address from , uint256 value ) internal {
balanceOf[from ] = balanceOf[from ].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from , address (0 ), value);
}
function _approve (
address owner,
address spender,
uint256 value
) internal {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer (
address from ,
address to,
uint256 value
) internal {
balanceOf[from ] = balanceOf[from ].sub(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from , to, value);
}
function approve (address spender, uint256 value ) external override returns (bool ) {
_approve(msg .sender , spender, value);
return true ;
}
function increaseAllowance (address spender, uint256 addedValue ) external override returns (bool ) {
_approve(msg .sender , spender, allowance[msg .sender ][spender].add(addedValue));
return true ;
}
function decreaseAllowance (address spender, uint256 subtractedValue ) external override returns (bool ) {
uint256 currentAllowance = allowance[msg .sender ][spender];
require (currentAllowance > = subtractedValue, 'TA48' );
_approve(msg .sender , spender, currentAllowance.sub(subtractedValue));
return true ;
}
function transfer (address to, uint256 value ) external override returns (bool ) {
_transfer(msg .sender , to, value);
return true ;
}
function transferFrom (
address from ,
address to,
uint256 value
) external override returns (bool ) {
if (allowance[from ][msg .sender ] ! = uint256 (-1 )) {
allowance[from ][msg .sender ] = allowance[from ][msg .sender ].sub(value);
}
_transfer(from , to, value);
return true ;
}
function permit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external override {
require (deadline > = block .timestamp , 'TA04' );
bytes32 digest = keccak256 (
abi .encodePacked (
'\x19\x01' ,
getDomainSeparator(),
keccak256 (abi .encode (PERMIT_TYPEHASH, owner, spender, value, nonces[owner]+ + , deadline))
)
);
address recoveredAddress = ecrecover (digest, v, r, s);
require (recoveredAddress ! = address (0 ) & & recoveredAddress = = owner, 'TA2F' );
_approve(owner, spender, value);
}
function getDomainSeparator ( ) public view returns (bytes32 ) {
uint256 chainId;
assembly {
chainId := chainid ()
}
return
keccak256 (
abi .encode (DOMAIN_TYPEHASH, keccak256 (bytes (name)), keccak256 (bytes ('1' )), chainId, address (this ))
);
}
}
File 2 of 12: IERC20.sol
pragma solidity 0.7.6;
interface IERC20 {
event Approval (address indexed owner, address indexed spender, uint256 value ) ;
event Transfer (address indexed from , address indexed to, uint256 value ) ;
function name ( ) external view returns (string memory ) ;
function symbol ( ) external view returns (string memory ) ;
function decimals ( ) external view returns (uint8 ) ;
function totalSupply ( ) external view returns (uint256 ) ;
function balanceOf (address owner ) external view returns (uint256 ) ;
function allowance (address owner, address spender ) external view returns (uint256 ) ;
function approve (address spender, uint256 value ) external returns (bool ) ;
function transfer (address to, uint256 value ) external returns (bool ) ;
function transferFrom (
address from ,
address to,
uint256 value
) external returns (bool ) ;
}
File 3 of 12: IReserves.sol
pragma solidity 0.7.6;
interface IReserves {
function getReserves ( ) external view returns (uint112 reserve0, uint112 reserve1 ) ;
function getFees ( ) external view returns (uint256 fee0, uint256 fee1 ) ;
}
File 4 of 12: ITwapERC20.sol
pragma solidity 0.7.6;
import './IERC20.sol' ;
interface ITwapERC20 is IERC20 {
function PERMIT_TYPEHASH ( ) external pure returns (bytes32 ) ;
function nonces (address owner ) external view returns (uint256 ) ;
function permit (
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external ;
function increaseAllowance (address spender, uint256 addedValue ) external returns (bool ) ;
function decreaseAllowance (address spender, uint256 subtractedValue ) external returns (bool ) ;
}
File 5 of 12: ITwapFactory.sol
pragma solidity 0.7.6;
interface ITwapFactory {
event PairCreated (address indexed token0, address indexed token1, address pair, uint256 ) ;
event OwnerSet (address owner ) ;
function owner ( ) external view returns (address ) ;
function getPair (address tokenA, address tokenB ) external view returns (address pair ) ;
function allPairs (uint256 ) external view returns (address pair ) ;
function allPairsLength ( ) external view returns (uint256 ) ;
function createPair (
address tokenA,
address tokenB,
address oracle,
address trader
) external returns (address pair ) ;
function setOwner (address ) external ;
function setMintFee (
address tokenA,
address tokenB,
uint256 fee
) external ;
function setBurnFee (
address tokenA,
address tokenB,
uint256 fee
) external ;
function setSwapFee (
address tokenA,
address tokenB,
uint256 fee
) external ;
function setOracle (
address tokenA,
address tokenB,
address oracle
) external ;
function setTrader (
address tokenA,
address tokenB,
address trader
) external ;
function collect (
address tokenA,
address tokenB,
address to
) external ;
function withdraw (
address tokenA,
address tokenB,
uint256 amount,
address to
) external ;
}
File 6 of 12: ITwapOracle.sol
pragma solidity 0.7.6;
interface ITwapOracle {
event OwnerSet (address owner ) ;
event UniswapPairSet (address uniswapPair ) ;
function decimalsConverter ( ) external view returns (int256 ) ;
function xDecimals ( ) external view returns (uint8 ) ;
function yDecimals ( ) external view returns (uint8 ) ;
function owner ( ) external view returns (address ) ;
function uniswapPair ( ) external view returns (address ) ;
function getPriceInfo ( ) external view returns (uint256 priceAccumulator, uint32 priceTimestamp ) ;
function getSpotPrice ( ) external view returns (uint256 ) ;
function getAveragePrice (uint256 priceAccumulator, uint32 priceTimestamp ) external view returns (uint256 ) ;
function setOwner (address _owner ) external ;
function setUniswapPair (address _uniswapPair ) external ;
function tradeX (
uint256 xAfter,
uint256 xBefore,
uint256 yBefore,
bytes calldata data
) external view returns (uint256 yAfter ) ;
function tradeY (
uint256 yAfter,
uint256 yBefore,
uint256 xBefore,
bytes calldata data
) external view returns (uint256 xAfter ) ;
function depositTradeXIn (
uint256 xLeft,
uint256 xBefore,
uint256 yBefore,
bytes calldata data
) external view returns (uint256 xIn ) ;
function depositTradeYIn (
uint256 yLeft,
uint256 yBefore,
uint256 xBefore,
bytes calldata data
) external view returns (uint256 yIn ) ;
}
File 7 of 12: ITwapPair.sol
pragma solidity 0.7.6;
import './ITwapERC20.sol' ;
import './IReserves.sol' ;
interface ITwapPair is ITwapERC20 , IReserves {
event Mint (address indexed sender, uint256 amount0In, uint256 amount1In, uint256 liquidityOut, address indexed to ) ;
event Burn (address indexed sender, uint256 amount0Out, uint256 amount1Out, uint256 liquidityIn, address indexed to ) ;
event Swap (
address indexed sender,
uint256 amount0In,
uint256 amount1In,
uint256 amount0Out,
uint256 amount1Out,
address indexed to
) ;
event SetMintFee (uint256 fee ) ;
event SetBurnFee (uint256 fee ) ;
event SetSwapFee (uint256 fee ) ;
event SetOracle (address account ) ;
event SetTrader (address trader ) ;
function MINIMUM_LIQUIDITY ( ) external pure returns (uint256 ) ;
function factory ( ) external view returns (address ) ;
function token0 ( ) external view returns (address ) ;
function token1 ( ) external view returns (address ) ;
function oracle ( ) external view returns (address ) ;
function trader ( ) external view returns (address ) ;
function mintFee ( ) external view returns (uint256 ) ;
function setMintFee (uint256 fee ) external ;
function mint (address to ) external returns (uint256 liquidity ) ;
function burnFee ( ) external view returns (uint256 ) ;
function setBurnFee (uint256 fee ) external ;
function burn (address to ) external returns (uint256 amount0, uint256 amount1 ) ;
function swapFee ( ) external view returns (uint256 ) ;
function setSwapFee (uint256 fee ) external ;
function setOracle (address account ) external ;
function setTrader (address account ) external ;
function collect (address to ) external ;
function swap (
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external ;
function sync ( ) external ;
function initialize (
address _token0,
address _token1,
address _oracle,
address _trader
) external ;
function getSwapAmount0In (uint256 amount1Out, bytes calldata data ) external view returns (uint256 swapAmount0In ) ;
function getSwapAmount1In (uint256 amount0Out, bytes calldata data ) external view returns (uint256 swapAmount1In ) ;
function getSwapAmount0Out (uint256 amount1In, bytes calldata data ) external view returns (uint256 swapAmount0Out ) ;
function getSwapAmount1Out (uint256 amount0In, bytes calldata data ) external view returns (uint256 swapAmount1Out ) ;
function getDepositAmount0In (uint256 amount0, bytes calldata data ) external view returns (uint256 depositAmount0In ) ;
function getDepositAmount1In (uint256 amount1, bytes calldata data ) external view returns (uint256 depositAmount1In ) ;
}
File 8 of 12: Math.sol
pragma solidity 0.7.6;
library Math {
function min (uint256 x, uint256 y ) internal pure returns (uint256 z ) {
z = x < y ? x : y;
}
function max (uint256 x, uint256 y ) internal pure returns (uint256 z ) {
z = x > y ? x : y;
}
function sqrt (uint256 y ) internal pure returns (uint256 z ) {
if (y > 3 ) {
z = y;
uint256 x = y / 2 + 1 ;
while (x < z) {
z = x;
x = (y / x + x) / 2 ;
}
} else if (y ! = 0 ) {
z = 1 ;
}
}
}
File 9 of 12: Reserves.sol
pragma solidity 0.7.6;
import '../interfaces/IReserves.sol' ;
import '../interfaces/IERC20.sol' ;
import '../libraries/SafeMath.sol' ;
contract Reserves is IReserves {
using SafeMath for uint256 ;
uint112 private reserve0;
uint112 private reserve1;
uint112 private fee0;
uint112 private fee1;
function getReserves ( ) public view override returns (uint112 , uint112 ) {
return (reserve0, reserve1);
}
function setReserves (uint256 balance0MinusFee, uint256 balance1MinusFee ) internal {
require (balance0MinusFee ! = 0 & & balance1MinusFee ! = 0 , 'RS09' );
reserve0 = balance0MinusFee.toUint112();
reserve1 = balance1MinusFee.toUint112();
}
function syncReserves (address token0, address token1 ) internal {
uint256 balance0 = IERC20(token0).balanceOf(address (this ));
uint256 balance1 = IERC20(token1).balanceOf(address (this ));
uint256 oldBalance0 = uint256 (reserve0) + fee0;
uint256 oldBalance1 = uint256 (reserve1) + fee1;
if (balance0 ! = oldBalance0 | | balance1 ! = oldBalance1) {
if (oldBalance0 ! = 0 ) {
fee0 = (balance0.mul(fee0).div(oldBalance0)).toUint112();
}
if (oldBalance1 ! = 0 ) {
fee1 = (balance1.mul(fee1).div(oldBalance1)).toUint112();
}
setReserves(balance0.sub(fee0), balance1.sub(fee1));
}
}
function getFees ( ) public view override returns (uint256 , uint256 ) {
return (fee0, fee1);
}
function addFees (uint256 _fee0, uint256 _fee1 ) internal {
setFees(_fee0.add(fee0), _fee1.add(fee1));
}
function setFees (uint256 _fee0, uint256 _fee1 ) internal {
fee0 = _fee0.toUint112();
fee1 = _fee1.toUint112();
}
function getBalances (address token0, address token1 ) internal returns (uint256 , uint256 ) {
uint256 balance0 = IERC20(token0).balanceOf(address (this ));
uint256 balance1 = IERC20(token1).balanceOf(address (this ));
if (fee0 > balance0) {
fee0 = uint112 (balance0);
}
if (fee1 > balance1) {
fee1 = uint112 (balance1);
}
return (balance0.sub(fee0), balance1.sub(fee1));
}
}
File 10 of 12: SafeMath.sol
pragma solidity 0.7.6;
library SafeMath {
int256 private constant _INT256_MIN = -2 * * 255 ;
function add (uint256 x, uint256 y ) internal pure returns (uint256 z ) {
require ((z = x + y) > = x, 'SM4E' );
}
function sub (uint256 x, uint256 y ) internal pure returns (uint256 z ) {
z = sub(x, y, 'SM12' );
}
function sub (
uint256 x,
uint256 y,
string memory message
) internal pure returns (uint256 z ) {
require ((z = x - y) < = x, message);
}
function mul (uint256 x, uint256 y ) internal pure returns (uint256 z ) {
require (y = = 0 | | (z = x * y) / y = = x, 'SM2A' );
}
function div (uint256 a, uint256 b ) internal pure returns (uint256 ) {
require (b > 0 , 'SM43' );
uint256 c = a / b;
return c;
}
function ceil_div (uint256 a, uint256 b ) internal pure returns (uint256 c ) {
c = div(a, b);
if (c = = mul(a, b)) {
return c;
} else {
return add(c, 1 );
}
}
function toUint32 (uint256 n ) internal pure returns (uint32 ) {
require (n < = type (uint32 ).max , 'SM50' );
return uint32 (n);
}
function toUint112 (uint256 n ) internal pure returns (uint112 ) {
require (n < = type (uint112 ).max , 'SM51' );
return uint112 (n);
}
function toInt256 (uint256 unsigned ) internal pure returns (int256 signed ) {
require (unsigned < = uint256 (type (int256 ).max ), 'SM34' );
signed = int256 (unsigned);
}
function add (int256 a, int256 b ) internal pure returns (int256 ) {
int256 c = a + b;
require ((b > = 0 & & c > = a) | | (b < 0 & & c < a), 'SM4D' );
return c;
}
function sub (int256 a, int256 b ) internal pure returns (int256 ) {
int256 c = a - b;
require ((b > = 0 & & c < = a) | | (b < 0 & & c > a), 'SM11' );
return c;
}
function mul (int256 a, int256 b ) internal pure returns (int256 ) {
if (a = = 0 ) {
return 0 ;
}
require (! (a = = -1 & & b = = _INT256_MIN), 'SM29' );
int256 c = a * b;
require (c / a = = b, 'SM29' );
return c;
}
function div (int256 a, int256 b ) internal pure returns (int256 ) {
require (b ! = 0 , 'SM43' );
require (! (b = = -1 & & a = = _INT256_MIN), 'SM42' );
int256 c = a / b;
return c;
}
}
File 11 of 12: TwapLPToken.sol
pragma solidity 0.7.6;
import './libraries/AbstractERC20.sol' ;
contract TwapLPToken is AbstractERC20 {
constructor ( ) {
name = 'Twap LP' ;
symbol = 'TWAP-LP' ;
decimals = 18 ;
}
}
File 12 of 12: TwapPair.sol
pragma solidity 0.7.6;
import './interfaces/ITwapPair.sol' ;
import './libraries/Reserves.sol' ;
import './TwapLPToken.sol' ;
import './libraries/Math.sol' ;
import './interfaces/IERC20.sol' ;
import './interfaces/ITwapFactory.sol' ;
import './interfaces/ITwapOracle.sol' ;
contract TwapPair is Reserves , TwapLPToken , ITwapPair {
using SafeMath for uint256 ;
uint256 private constant PRECISION = 10 * * 18 ;
uint256 public override mintFee = 0 ;
uint256 public override burnFee = 0 ;
uint256 public override swapFee = 0 ;
uint256 public constant override MINIMUM_LIQUIDITY = 10 * * 3 ;
bytes4 private constant SELECTOR = bytes4 (keccak256 (bytes ('transfer(address,uint256)' )));
address public immutable override factory;
address public override token0;
address public override token1;
address public override oracle;
address public override trader;
uint256 private unlocked = 1 ;
modifier lock ( ) {
require (unlocked = = 1 , 'TP06' );
unlocked = 0 ;
_ ;
unlocked = 1 ;
}
function isContract (address addr ) private view returns (bool ) {
uint256 size;
assembly {
size := extcodesize (addr)
}
return size > 0 ;
}
function setMintFee (uint256 fee ) external override {
require (msg .sender = = factory, 'TP00' );
require (fee ! = mintFee, 'TP01' );
mintFee = fee;
emit SetMintFee(fee);
}
function setBurnFee (uint256 fee ) external override {
require (msg .sender = = factory, 'TP00' );
require (fee ! = burnFee, 'TP01' );
burnFee = fee;
emit SetBurnFee(fee);
}
function setSwapFee (uint256 fee ) external override {
require (msg .sender = = factory, 'TP00' );
require (fee ! = swapFee, 'TP01' );
swapFee = fee;
emit SetSwapFee(fee);
}
function setOracle (address _oracle ) external override {
require (msg .sender = = factory, 'TP00' );
require (_oracle ! = oracle, 'TP01' );
require (_oracle ! = address (0 ), 'TP02' );
require (isContract(_oracle), 'TP1D' );
oracle = _oracle;
emit SetOracle(_oracle);
}
function setTrader (address _trader ) external override {
require (msg .sender = = factory, 'TP00' );
require (_trader ! = trader, 'TP01' );
trader = _trader;
emit SetTrader(_trader);
}
function collect (address to ) external override lock {
require (msg .sender = = factory, 'TP00' );
require (to ! = address (0 ), 'TP02' );
(uint256 fee0, uint256 fee1) = getFees();
if (fee0 > 0 ) _safeTransfer(token0, to, fee0);
if (fee1 > 0 ) _safeTransfer(token1, to, fee1);
setFees(0 , 0 );
_sync();
}
function _safeTransfer (
address token,
address to,
uint256 value
) private {
(bool success, bytes memory data) = token.call (abi .encodeWithSelector (SELECTOR, to, value));
require (success & & (data.length = = 0 | | abi .decode (data, (bool ))), 'TP05' );
}
function canTrade (address user ) private view returns (bool ) {
return user = = trader | | user = = factory;
}
constructor ( ) {
factory = msg .sender ;
}
function initialize (
address _token0,
address _token1,
address _oracle,
address _trader
) external override {
require (msg .sender = = factory, 'TP00' );
require (_oracle ! = address (0 ), 'TP02' );
require (isContract(_oracle), 'TP1D' );
require (isContract(_token0) & & isContract(_token1), 'TP10' );
token0 = _token0;
token1 = _token1;
oracle = _oracle;
trader = _trader;
}
function mint (address to ) external override lock returns (uint256 liquidityOut ) {
require (canTrade(msg .sender ), 'TP0C' );
require (to ! = address (0 ), 'TP02' );
(uint112 reserve0, uint112 reserve1) = getReserves();
(uint256 balance0, uint256 balance1) = getBalances(token0, token1);
uint256 amount0In = balance0.sub(reserve0);
uint256 amount1In = balance1.sub(reserve1);
uint256 _totalSupply = totalSupply;
if (_totalSupply = = 0 ) {
liquidityOut = Math.sqrt(amount0In.mul(amount1In)).sub(MINIMUM_LIQUIDITY);
_mint(address (0 ), MINIMUM_LIQUIDITY);
} else {
liquidityOut = Math.min (amount0In.mul(_totalSupply) / reserve0, amount1In.mul(_totalSupply) / reserve1);
}
require (liquidityOut > 0 , 'TP38' );
if (mintFee > 0 ) {
uint256 fee = liquidityOut.mul(mintFee).div(PRECISION);
liquidityOut = liquidityOut.sub(fee);
_mint(factory, fee);
}
_mint(to, liquidityOut);
setReserves(balance0, balance1);
emit Mint(msg .sender , amount0In, amount1In, liquidityOut, to);
}
function burn (address to ) external override lock returns (uint256 amount0Out, uint256 amount1Out ) {
require (canTrade(msg .sender ), 'TP0C' );
require (to ! = address (0 ), 'TP02' );
uint256 _totalSupply = totalSupply;
require (_totalSupply > 0 , 'TP36' );
address _token0 = token0;
address _token1 = token1;
(uint256 balance0, uint256 balance1) = getBalances(token0, token1);
uint256 liquidityIn = balanceOf[address (this )];
if (msg .sender ! = factory & & burnFee > 0 ) {
uint256 fee = liquidityIn.mul(burnFee).div(PRECISION);
liquidityIn = liquidityIn.sub(fee);
_transfer(address (this ), factory, fee);
}
_burn(address (this ), liquidityIn);
amount0Out = liquidityIn.mul(balance0) / _totalSupply;
amount1Out = liquidityIn.mul(balance1) / _totalSupply;
require (amount0Out > 0 & & amount1Out > 0 , 'TP39' );
_safeTransfer(_token0, to, amount0Out);
_safeTransfer(_token1, to, amount1Out);
(balance0, balance1) = getBalances(token0, token1);
setReserves(balance0, balance1);
emit Burn(msg .sender , amount0Out, amount1Out, liquidityIn, to);
}
function swap (
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external override lock {
require (canTrade(msg .sender ), 'TP0C' );
require (to ! = address (0 ), 'TP02' );
require ((amount0Out > 0 & & amount1Out = = 0 ) | | (amount1Out > 0 & & amount0Out = = 0 ), 'TP31' );
(uint112 _reserve0, uint112 _reserve1) = getReserves();
require (amount0Out < _reserve0 & & amount1Out < _reserve1, 'TP07' );
{
address _token0 = token0;
address _token1 = token1;
require (to ! = _token0 & & to ! = _token1, 'TP2D' );
if (amount0Out > 0 ) _safeTransfer(_token0, to, amount0Out);
if (amount1Out > 0 ) _safeTransfer(_token1, to, amount1Out);
}
(uint256 balance0, uint256 balance1) = getBalances(token0, token1);
if (amount0Out > 0 ) {
require (balance1 > _reserve1, 'TP08' );
uint256 amount1In = balance1 - _reserve1;
emit Swap(msg .sender , 0 , amount1In, amount0Out, 0 , to);
uint256 fee1 = amount1In.mul(swapFee).div(PRECISION);
uint256 balance1After = balance1.sub(fee1);
uint256 balance0After = ITwapOracle(oracle).tradeY(balance1After, _reserve0, _reserve1, data);
require (balance0 > = balance0After, 'TP2E' );
uint256 fee0 = balance0.sub(balance0After);
addFees(fee0, fee1);
setReserves(balance0After, balance1After);
} else {
require (balance0 > _reserve0, 'TP08' );
uint256 amount0In = balance0 - _reserve0;
emit Swap(msg .sender , amount0In, 0 , 0 , amount1Out, to);
uint256 fee0 = amount0In.mul(swapFee).div(PRECISION);
uint256 balance0After = balance0.sub(fee0);
uint256 balance1After = ITwapOracle(oracle).tradeX(balance0After, _reserve0, _reserve1, data);
require (balance1 > = balance1After, 'TP2E' );
uint256 fee1 = balance1.sub(balance1After);
addFees(fee0, fee1);
setReserves(balance0After, balance1After);
}
}
function sync ( ) external override lock {
require (canTrade(msg .sender ), 'TP0C' );
_sync();
}
function _sync ( ) internal {
syncReserves(token0, token1);
uint256 tokens = balanceOf[address (this )];
if (tokens > 0 ) {
_transfer(address (this ), factory, tokens);
}
}
function getSwapAmount0In (uint256 amount1Out, bytes calldata data )
public
view
override
returns (uint256 swapAmount0In )
{
(uint112 reserve0, uint112 reserve1) = getReserves();
uint256 balance1After = uint256 (reserve1).sub(amount1Out);
uint256 balance0After = ITwapOracle(oracle).tradeY(balance1After, reserve0, reserve1, data);
return balance0After.sub(uint256 (reserve0)).mul(PRECISION).ceil_div(PRECISION.sub(swapFee));
}
function getSwapAmount1In (uint256 amount0Out, bytes calldata data )
public
view
override
returns (uint256 swapAmount1In )
{
(uint112 reserve0, uint112 reserve1) = getReserves();
uint256 balance0After = uint256 (reserve0).sub(amount0Out);
uint256 balance1After = ITwapOracle(oracle).tradeX(balance0After, reserve0, reserve1, data);
return balance1After.add(1 ).sub(uint256 (reserve1)).mul(PRECISION).ceil_div(PRECISION.sub(swapFee));
}
function getSwapAmount0Out (uint256 amount1In, bytes calldata data )
public
view
override
returns (uint256 swapAmount0Out )
{
(uint112 reserve0, uint112 reserve1) = getReserves();
uint256 fee = amount1In.mul(swapFee).div(PRECISION);
uint256 balance0After = ITwapOracle(oracle).tradeY(
uint256 (reserve1).add(amount1In).sub(fee),
reserve0,
reserve1,
data
);
return uint256 (reserve0).sub(balance0After);
}
function getSwapAmount1Out (uint256 amount0In, bytes calldata data )
public
view
override
returns (uint256 swapAmount1Out )
{
(uint112 reserve0, uint112 reserve1) = getReserves();
uint256 fee = amount0In.mul(swapFee).div(PRECISION);
uint256 balance1After = ITwapOracle(oracle).tradeX(
uint256 (reserve0).add(amount0In).sub(fee),
reserve0,
reserve1,
data
);
return uint256 (reserve1).sub(balance1After);
}
function getDepositAmount0In (uint256 amount0, bytes calldata data ) external view override returns (uint256 ) {
(uint112 reserve0, uint112 reserve1) = getReserves();
return ITwapOracle(oracle).depositTradeXIn(amount0, reserve0, reserve1, data);
}
function getDepositAmount1In (uint256 amount1, bytes calldata data ) external view override returns (uint256 ) {
(uint112 reserve0, uint112 reserve1) = getReserves();
return ITwapOracle(oracle).depositTradeYIn(amount1, reserve0, reserve1, data);
}
}
{
"compilationTarget" : {
"contracts/TwapPair.sol" : "TwapPair"
} ,
"evmVersion" : "istanbul" ,
"libraries" : { } ,
"metadata" : {
"bytecodeHash" : "ipfs"
} ,
"optimizer" : {
"enabled" : true ,
"runs" : 200
} ,
"remappings" : [ ]
} [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityIn","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityOut","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetBurnFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetMintFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetSwapFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trader","type":"address"}],"name":"SetTrader","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"collect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getDepositAmount0In","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getDepositAmount1In","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeparator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint112","name":"","type":"uint112"},{"internalType":"uint112","name":"","type":"uint112"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getSwapAmount0In","outputs":[{"internalType":"uint256","name":"swapAmount0In","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount1In","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getSwapAmount0Out","outputs":[{"internalType":"uint256","name":"swapAmount0Out","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getSwapAmount1In","outputs":[{"internalType":"uint256","name":"swapAmount1In","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0In","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getSwapAmount1Out","outputs":[{"internalType":"uint256","name":"swapAmount1Out","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_trader","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidityOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setBurnFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"}],"name":"setTrader","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trader","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]