The createMarket transaction lack of expiration timestamp check
The createMarket transaction lack of expiration timestamp check\\nLet us look into the heavily forked Uniswap V2 contract addLiquidity function implementation\\n```\\n// **** ADD LIQUIDITY ****\\nfunction _addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin\\n) internal virtual returns (uint amountA, uint amountB) {\\n // create the pair if it doesn't exist yet\\n if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) {\\n  IUniswapV2Factory(factory).createPair(tokenA, tokenB);\\n }\\n (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB);\\n if (reserveA == 0 && reserveB == 0) {\\n  (amountA, amountB) = (amountADesired, amountBDesired);\\n } else {\\n  uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);\\n  if (amountBOptimal <= amountBDesired) {\\n   require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT');\\n   (amountA, amountB) = (amountADesired, amountBOptimal);\\n  } else {\\n   uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA);\\n   assert(amountAOptimal <= amountADesired);\\n   require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT');\\n   (amountA, amountB) = (amountAOptimal, amountBDesired);\\n  }\\n }\\n}\\n\\nfunction addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {\\n (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);\\n address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);\\n TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);\\n TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);\\n liquidity = IUniswapV2Pair(pair).mint(to);\\n}\\n```\\n\\nthe implementation has two point that worth noting,\\nthe first point is the deadline check\\n```\\nmodifier ensure(uint deadline) {\\n require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED');\\n _;\\n}\\n```\\n\\nThe transaction can be pending in mempool for a long time and can be executed in a long time after the user submit the transaction.\\nProblem is createMarket, which calculates the length and maxPayout by block.timestamp inside it.\\n```\\n        // Calculate market length and check time bounds\\n        uint48 length = uint48(params_.conclusion - block.timestamp); \\\\n        if (\\n            length < minMarketDuration ||\\n            params_.depositInterval < minDepositInterval ||\\n            params_.depositInterval > length\\n        ) revert Auctioneer_InvalidParams();\\n\\n        // Calculate the maximum payout amount for this market, determined by deposit interval\\n        uint256 capacity = params_.capacityInQuote\\n            ? params_.capacity.mulDiv(scale, price)\\n            : params_.capacity;\\n        market.maxPayout = capacity.mulDiv(uint256(params_.depositInterval), uint256(length));\\n```\\n\\nAfter the market is created at wrong time, user can call purchase. At purchaseBond(),\\n```\\n        // Payout for the deposit = amount / price\\n        //\\n        // where:\\n        // payout = payout tokens out\\n        // amount = quote tokens in\\n        // price = quote tokens : payout token (i.e. 200 QUOTE : BASE), adjusted for scaling\\n        payout = amount_.mulDiv(term.scale, price);\\n\\n        // Payout must be greater than user inputted minimum\\n        if (payout < minAmountOut_) revert Auctioneer_AmountLessThanMinimum();\\n\\n        // Markets have a max payout amount, capping size because deposits\\n        // do not experience slippage. max payout is recalculated upon tuning\\n        if (payout > market.maxPayout) revert Auctioneer_MaxPayoutExceeded();\\n```\\n\\npayout value is calculated by term.scale which the market owner has set assuming the market would be created at desired timestamp. Even, maxPayout is far bigger than expected, as it is calculated by very small length.
Use deadline, like uniswap
Even though the market owner close the market at any time, malicious user can attack the market before close and steal unexpectedly large amount of payout Tokens.
```\\n// **** ADD LIQUIDITY ****\\nfunction _addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin\\n) internal virtual returns (uint amountA, uint amountB) {\\n // create the pair if it doesn't exist yet\\n if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) {\\n  IUniswapV2Factory(factory).createPair(tokenA, tokenB);\\n }\\n (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB);\\n if (reserveA == 0 && reserveB == 0) {\\n  (amountA, amountB) = (amountADesired, amountBDesired);\\n } else {\\n  uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB);\\n  if (amountBOptimal <= amountBDesired) {\\n   require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT');\\n   (amountA, amountB) = (amountADesired, amountBOptimal);\\n  } else {\\n   uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA);\\n   assert(amountAOptimal <= amountADesired);\\n   require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT');\\n   (amountA, amountB) = (amountAOptimal, amountBDesired);\\n  }\\n }\\n}\\n\\nfunction addLiquidity(\\n address tokenA,\\n address tokenB,\\n uint amountADesired,\\n uint amountBDesired,\\n uint amountAMin,\\n uint amountBMin,\\n address to,\\n uint deadline\\n) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {\\n (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);\\n address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);\\n TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);\\n TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);\\n liquidity = IUniswapV2Pair(pair).mint(to);\\n}\\n```\\n