Timeswap contest - tnevler's results

Like Uniswap, but for lending & borrowing.

General Information

Platform: Code4rena

Start Date: 20/01/2023

Pot Size: $90,500 USDC

Total HM: 10

Participants: 59

Period: 7 days

Judge: Picodes

Total Solo HM: 4

Id: 206

League: ETH

Timeswap

Findings Distribution

Researcher Performance

Rank: 36/59

Findings: 1

Award: $65.35

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

65.3481 USDC - $65.35

Labels

bug
grade-b
QA (Quality Assurance)
Q-11

External Links

Report

Non-Critical Issues

[N-1]: Function defines a named return variable but then it uses return statements

Context:

  1. if (product1 == 0) return result = product0.div(divisor, roundUp); L185
  2. if (value == type(uint256).max) return result = type(uint128).max; L70
  3. return value1 < value2 ? value1 : value2; L89
  4. return pools[strike][maturity].feeGrowth(); L119
  5. return pools[strike][maturity].feesEarnedOf(owner); L124
  6. return pools[strike][maturity].protocolFeesEarned(); L129
  7. return mint(param, true, durationForward); L249
  8. return burn(param, true, durationForward); L314
  9. return deleverage(param, true, durationForward); L374
  10. return leverage(param, true, durationForward); L427
  11. return (pool.long0FeeGrowth, pool.long1FeeGrowth, pool.shortFeeGrowth); L67
  12. return pool.liquidityPositions[owner].feesEarnedOf(pool.long0FeeGrowth, pool.long1FeeGrowth, pool.shortFeeGrowth); L76
  13. return (pool.long0ProtocolFees, pool.long1ProtocolFees, pool.shortProtocolFees); L84

Recommendation:

Choose named return variable or return statement. It is unnecessary to use both.

[N-2]: Wrong order of functions

Context:

  1. constructor() NoDelegateCall() { L77 (constructor can not go after private function)
  2. function tokenByIndex(uint256 index) external view override returns (uint256) { L41 (external function can not go after public function)
  3. mapping(bytes32 => uint96) private reentrancyGuards; L41 (state variable declaration can not go after constructor)
  4. function positionOf(address owner, TimeswapV2TokenPosition calldata timeswapV2TokenPosition) public view returns (uint256 amount) { L66 (public function can not go after private function)
  5. constructor() NoDelegateCall() { L65 (constructor can not go after private function)

Description:

According to official solidity documentation functions should be grouped according to their visibility and ordered:

  • constructor

  • receive function (if exists)

  • fallback function (if exists)

  • external

  • public

  • internal

  • private

Within a grouping, place the view and pure functions last.

Recommendation:

Put the functions in the correct order according to the documentation.

[N-3]: NatSpec is missing

Context:

  1. function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) { L12
  2. TimeswapV2Pool.sol (8 functions are missing NatSpec)
  3. function deploy(address poolFactory, address optionPair, uint256 transactionFee, uint256 protocolFee) internal returns (address poolPair) { L25
  4. LiquidityPosition.sol (5 functions are missing NatSpec)
  5. TimeswapV2LiquidityToken.sol (5 functions are missing NatSpec)
  6. function changeInteractedIfNecessary(address token0, address token1, uint256 strike, uint256 maturity) private { L45
  7. FeesPosition.sol
  8. TimeswapV2Option.sol (5 functions are missing NatSpec)

[N-4]: Typos

Context:

  1. /// @param addendA0 The least signficant part of addendA. L40 (Change signficant to significant)
  2. // correct result modulo 2**256. Since the precoditions guarantee L250 (Change precoditions to precondition)
  3. /// @dev When oneToZero, given a larger base amount, and toekn1 amount, get the difference token0 amount. L40 (Change toekn1 to token1)
  4. /// @param to If isLong0ToLong1 then receipient of long0 positions, ekse recipient of long1 positions. L132 (Change ekse to else)
  5. /// @param long0Fees The amount of long0 position fees transferrred. L179 (Change transferrred to transferred)
  6. /// @param long1Fees The amount of long1 position fees transferrred. L180 (Change transferrred to transferred)
  7. /// @param shortFees The amount of short position fees transferrred. L181 (Change transferrred to transferred)
  8. /// @dev Reverts when there is not enough time value liqudity to receive when lending. L19 (Change liqudity to liquidity)
  9. /// @return sqrtDiscriminant The square root disriminant calculated. L394 (Change disriminant to discriminant)
  10. /// @return optionPair The retreived option pair address. Zero address if not deployed. L27 (Change retreived to retrieved)
  11. /// @return poolPair The retreived pool pair address. Zero address if not deployed. L28 (Change retreived to retrieved)
  12. /// @return optionPair The retreived option pair address. L41 (Change retreived to retrieved)
  13. /// @return poolPair The retreived pool pair address. L42 (Change retreived to retrieved)
  14. /// @dev Checks if the pool doesn not exist. L19 (Change doesn to does)
  15. /// @dev mints TimeswapV2LiquidityToken as per the liqudityAmount L44 (Change liqudityAmount to liquidityAmount)
  16. /// @dev burns TimeswapV2LiquidityToken as per the liqudityAmount L49 (Change liqudityAmount to liquidityAmount)
  17. /// @dev mints TimeswapV2Token as per postion and amount L27 (Change postion to position)
  18. /// @dev burns TimeswapV2Token as per postion and amount L32 (Change postion to position)
  19. /// @dev Any additional condition to add token enumeration when overidden. L69 (Change overidden to overridden)
  20. /// @dev Any additional condition to add token enumeration when overidden. L74 (Change overidden to overridden)
  21. /// @dev Any additional condition to remove token enumeration when overidden. L103 (Change overidden to overridden)
  22. /// @dev Any additional condition to remove token enumeration when overidden. L108 (Change overidden to overridden)
  23. /// @dev paramater for minting Timeswap V2 Tokens L4 (Change paramater to parameter)
  24. /// @dev paramater for burning Timeswap V2 Tokens L24 (Change paramater to parameter)
  25. /// @param data Arbitrary data passed to the callback, initalize as empty if not required. L32 (Change initalize to initialize)
  26. /// @dev paramater for minting Timeswap V2 Tokens L6 (Change paramater to parameter)
  27. /// @dev paramater for burning Timeswap V2 Tokens L32 (Change paramater to parameter)
  28. /// @param data Arbitrary data passed to the callback, initalize as empty if not required. L43 (Change initalize to initialize)
  29. /// @dev paramater for minting Timeswap V2 Liquidity Tokens L58 (Change paramater to parameter)
  30. /// @dev paramater for burning Timeswap V2 Liquidity Tokens L76 (Change paramater to parameter)
  31. /// @param data Arbitrary data passed to the callback, initalize as empty if not required. L83 (Change initalize to initialize)
  32. /// @dev paramater for collecting fees from Timeswap V2 Liquidity Tokens L94 (Change paramater to parameter)
  33. /// @param data Arbitrary data passed to the callback, initalize as empty if not required. L103 (Change initalize to initialize)
  34. /// @dev The long0 positions, long1 positions, and/or short positions will already minted to the receipients. L12 (Change receipients to recipients)
  35. /// @notice If data length is zero, skips the calback. L43 (Change calback to callback)
  36. /// @notice If data length is zero, skips the calback. L88 (Change calback to callback)
  37. // Can be overidden for testing purposes. L69 (Change overidden to overridden)

[N-5]: Line is too long

Context:

  1. function add512(uint256 addendA0, uint256 addendA1, uint256 addendB0, uint256 addendB1) internal pure returns (uint256 sum0, uint256 sum1) { L46
  2. function sub512(uint256 minuend0, uint256 minuend1, uint256 subtrahend0, uint256 subtrahend1) internal pure returns (uint256 difference0, uint256 difference1) { L62
  3. if (subtrahend1 > minuend1 || (subtrahend1 == minuend1 && subtrahend0 > minuend0)) revert SubUnderflow(minuend0, minuend1, subtrahend0, subtrahend1); L68
  4. function div512(uint256 dividend0, uint256 dividend1, uint256 divisor) private pure returns (uint256 quotient0, uint256 quotient1) { L115
  5. function div512To256(uint256 dividend0, uint256 dividend1, uint256 divisor, bool roundUp) internal pure returns (uint256 quotient) { L138
  6. function div512(uint256 dividend0, uint256 dividend1, uint256 divisor, bool roundUp) internal pure returns (uint256 quotient0, uint256 quotient1) { L158
  7. function mulDiv(uint256 multiplicand, uint256 multiplier, uint256 divisor, bool roundUp) internal pure returns (uint256 result) { L181
  8. return zeroToOne ? FullMath.mulDiv(amount, strike, uint256(1) << 128, roundUp) : FullMath.mulDiv(amount, uint256(1) << 128, strike, roundUp); L17
  9. return strike > type(uint128).max ? (toOne ? convert(amount, strike, true, roundUp) : amount) : (toOne ? amount : convert(amount, strike, false, roundUp)); L27
  10. return strike > type(uint128).max ? amount0 + convert(amount1, strike, false, roundUp) : amount1 + convert(amount0, strike, true, roundUp); L36
  11. function feeGrowth(uint256 strike, uint256 maturity) external view override returns (uint256 long0FeeGrowth, uint256 long1FeeGrowth, uint256 shortFeeGrowth) { L118
  12. function feesEarnedOf(uint256 strike, uint256 maturity, address owner) external view override returns (uint256 long0Fees, uint256 long1Fees, uint256 shortFees) L123 {
  13. constructor(address chosenOwner, uint256 chosenTransactionFee, uint256 chosenProtocolFee) OwnableTwoSteps(chosenOwner) { L37
  14. event TransferFees(uint256 indexed strike, uint256 indexed maturity, address indexed from, address to, uint256 long0Fees, uint256 long1Fees, uint256 shortFees); L26
  15. event Mint(uint256 indexed strike, uint256 indexed maturity, address indexed caller, address to, uint160 liquidityAmount, uint256 long0Amount, uint256 long1Amount, uint256 shortAmount); L81
  16. event Deleverage(uint256 indexed strike, uint256 indexed maturity, address indexed caller, address to, uint256 long0Amount, uint256 long1Amount, uint256 shortAmount); L115
  17. event Leverage(uint256 indexed strike, uint256 indexed maturity, address indexed caller, address long0To, address long1To, uint256 long0Amount, uint256 long1Amount, uint256 shortAmount); L126
  18. event Rebalance(uint256 indexed strike, uint256 indexed maturity, address indexed caller, address to, bool isLong0ToLong1, uint256 long0Amount, uint256 long1Amount); L138
  19. function feeGrowth(uint256 strike, uint256 maturity) external view returns (uint256 long0FeeGrowth, uint256 long1FeeGrowth, uint256 shortFeeGrowth); L189
  20. function feesEarnedOf(uint256 strike, uint256 maturity, address owner) external view returns (uint256 long0Fees, uint256 long1Fees, uint256 shortFees); L197
  21. function protocolFeesEarned(uint256 strike, uint256 maturity) external view returns (uint256 long0ProtocolFees, uint256 long1ProtocolFees, uint256 shortProtocolFees); L204
  22. function totalLongBalanceAdjustFees(uint256 strike, uint256 maturity) external view returns (uint256 long0Amount, uint256 long1Amount); L218
  23. function collectProtocolFees(TimeswapV2PoolCollectParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, uint256 shortAmount); L261
  24. function collectTransactionFees(TimeswapV2PoolCollectParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, uint256 shortAmount); L270
  25. function mint(TimeswapV2PoolMintParam calldata param) external returns (uint160 liquidityAmount, uint256 long0Amount, uint256 long1Amount, uint256 shortAmount, bytes memory data); L280
  26. function burn(TimeswapV2PoolBurnParam calldata param) external returns (uint160 liquidityAmount, uint256 long0Amount, uint256 long1Amount, uint256 shortAmount, bytes memory data); L307
  27. function deleverage(TimeswapV2PoolDeleverageParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, uint256 shortAmount, bytes memory data); L333
  28. function deleverage(TimeswapV2PoolDeleverageParam calldata param, uint96 durationForward) external returns (uint256 long0Amount, uint256 long1Amount, uint256 shortAmount, bytes memory data); L344
  29. function leverage(TimeswapV2PoolLeverageParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, uint256 shortAmount, bytes memory data); L353
  30. function leverage(TimeswapV2PoolLeverageParam calldata param, uint96 durationForward) external returns (uint256 long0Amount, uint256 long1Amount, uint256 shortAmount, bytes memory data); L364
  31. function rebalance(TimeswapV2PoolRebalanceParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, bytes memory data); L372
  32. function timeswapV2PoolBurnChoiceCallback(TimeswapV2PoolBurnChoiceCallbackParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, bytes memory data); L13
  33. function timeswapV2PoolDeleverageChoiceCallback(TimeswapV2PoolDeleverageChoiceCallbackParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, bytes memory data); L14
  34. function timeswapV2PoolLeverageChoiceCallback(TimeswapV2PoolLeverageChoiceCallbackParam calldata param) external returns (uint256 long0Amount, uint256 long1Amount, bytes memory data); L14
  35. function feesEarnedOf(Pool storage pool, address owner) external view returns (uint256 long0Fees, uint256 long1Fees, uint256 shortFees) { L75
  36. function protocolFeesEarned(Pool storage pool) external view returns (uint256 long0ProtocolFees, uint256 long1ProtocolFees, uint256 shortProtocolFees) { L83
  37. function totalPositions(Pool storage pool, uint256 maturity, uint96 blockTimestamp) external view returns (uint256 longAmount, uint256 shortAmount) { L101
  38. shortAmount = ConstantProduct.getShort(pool.liquidity, pool.sqrtInterestRate, DurationCalculation.unsafeDurationFromNowToMaturity(maturity, blockTimestamp), false); L103
  39. function transferFees(Pool storage pool, uint256 maturity, address to, uint256 long0Fees, uint256 long1Fees, uint256 shortFees, uint96 blockTimestamp) external { L183
  40. (pool.shortFeeGrowth, pool.shortProtocolFees) = FeeCalculation.update(pool.liquidity, pool.shortFeeGrowth, pool.shortProtocolFees, shortFees, protocolFee); L530
  41. TimeswapV2PoolDeleverageChoiceCallbackParam({strike: param.strike, maturity: param.maturity, longAmount: longAmount, shortAmount: shortAmount, data: param.data}) L533
  42. (pool.long0FeeGrowth, pool.long0ProtocolFees) = FeeCalculation.update(pool.liquidity, pool.long0FeeGrowth, pool.long0ProtocolFees, long0Fees, protocolFee); L639
  43. (pool.long1FeeGrowth, pool.long1ProtocolFees) = FeeCalculation.update(pool.liquidity, pool.long1FeeGrowth, pool.long1ProtocolFees, long1Fees, protocolFee); L653
  44. function rebalance(Pool storage pool, TimeswapV2PoolRebalanceParam memory param, uint256 transactionFee, uint256 protocolFee) external returns (uint256 long0Amount, uint256 long1Amount) { L665
  45. (pool.long1FeeGrowth, pool.long1ProtocolFees) = FeeCalculation.update(pool.liquidity, pool.long1FeeGrowth, pool.long1ProtocolFees, longFees, protocolFee); L697
  46. (long0Amount, longFees) = ConstantSum.calculateGivenLongIn(param.strike, long1Amount = param.delta, transactionFee, false); L715
  47. (pool.long0FeeGrowth, pool.long0ProtocolFees) = FeeCalculation.update(pool.liquidity, pool.long0FeeGrowth, pool.long0ProtocolFees, longFees, protocolFee); L724
  48. function calculateGivenLiquidityDelta(uint160 rate, uint160 deltaLiquidity, uint96 duration, bool isAdd) internal pure returns (uint256 longAmount, uint256 shortAmount) { L51
  49. function calculateGivenLiquidityLong(uint160 rate, uint256 longAmount, uint96 duration, bool isAdd) internal pure returns (uint160 liquidityAmount, uint256 shortAmount) { L66
  50. function calculateGivenLiquidityShort(uint160 rate, uint256 shortAmount, uint96 duration, bool isAdd) internal pure returns (uint160 liquidityAmount, uint256 longAmount) { L81
  51. /// @dev Calculate the amount of liquidity positions and amount of long positions in base denomination or short position whichever is larger or smaller. L87
  52. function getLongFromSqrtInterestRate(uint160 liquidity, uint160 rate, uint160 deltaRate, uint160 newRate, bool roundUp) private pure returns (uint256) { L329
  53. return roundUp ? FullMath.mulDiv(numerator, deltaRate, uint256(rate), true).div(newRate, true) : FullMath.mulDiv(numerator, deltaRate, uint256(newRate), false).div(rate, false); L334
  54. function getShortOrLongFromGivenSum(uint160 liquidity, uint160 rate, uint256 sumAmount, uint96 duration, uint256 transactionFee, bool isShort) private pure returns (uint256 amount) { L356
  55. function calculateNegativeB(uint160 liquidity, uint160 rate, uint256 sumAmount, uint96 duration, uint256 transactionFee, bool isShort) private pure returns (uint256 negativeB) { L373
  56. uint256 denominator = isShort ? (uint256(1) << 174).unsafeMul((uint256(1) << 16).unsafeSub(transactionFee)) : uint256(rate).unsafeMul((uint256(1) << 16).unsafeSub(transactionFee)); L404
  57. (uint256 a0, uint256 a1) = isShort ? FullMath.mul512(uint256(liquidity).unsafeMul(duration), rate) : FullMath.mul512(liquidity, uint256(1) << 114); L406
  58. function update(uint160 liquidity, uint256 feeGrowth, uint256 protocolFees, uint256 fees, uint256 protocolFee) internal pure returns (uint256 newFeeGrowth, uint256 newProtocolFees) { L27
  59. return globalFeeGrowth != lastFeeGrowth ? FullMath.mulDiv(liquidity, uint256(1) << 128, globalFeeGrowth.unsafeSub(lastFeeGrowth), false) : 0; L41
  60. function get(address optionFactory, address poolFactory, address token0, address token1) internal view returns (address optionPair, address poolPair) { L29
  61. function getWithCheck(address optionFactory, address poolFactory, address token0, address token1) internal view returns (address optionPair, address poolPair) { L43
  62. function transferFeesFrom(address from, address to, TimeswapV2LiquidityTokenPosition calldata position, uint256 long0Fees, uint256 long1Fees, uint256 shortFees) external; L42
  63. function collect(TimeswapV2LiquidityTokenCollectParam calldata param) external returns (uint256 long0Fees, uint256 long1Fees, uint256 shortFees, bytes memory data); L59
  64. function _beforeTokenTransfer(address, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory) internal virtual override { L47
  65. if (_idTotalSupply[id] == 0 && _additionalConditionAddTokenToAllTokensEnumeration(id)) _addTokenToAllTokensEnumeration(id); L60
  66. if (balanceOf(to, id) == 0 && _additionalConditionAddTokenToOwnerEnumeration(to, id)) _addTokenToOwnerEnumeration(to, id); L65
  67. function _afterTokenTransfer(address, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory) internal virtual override { L81
  68. if (_idTotalSupply[id] == 0 && _additionalConditionRemoveTokenFromAllTokensEnumeration(id)) _removeTokenFromAllTokensEnumeration(id); L94
  69. if (balanceOf(from, id) == 0 && _additionalConditionRemoveTokenFromOwnerEnumeration(from, id)) _removeTokenFromOwnerEnumeration(from, id); L99
  70. function positionOf(address owner, TimeswapV2LiquidityTokenPosition calldata timeswapV2LiquidityTokenPosition) external view returns (uint256 amount) { L65
  71. function transferTokenPositionFrom(address from, address to, TimeswapV2LiquidityTokenPosition calldata timeswapV2LiquidityTokenPosition, uint160 liquidityAmount) external { L70
  72. safeTransferFrom(from, to, _timeswapV2LiquidityTokenPositionIds[timeswapV2LiquidityTokenPosition.toKey()], liquidityAmount, bytes("")); L71
  73. function transferFeesFrom(address from, address to, TimeswapV2LiquidityTokenPosition calldata position, uint256 long0Fees, uint256 long1Fees, uint256 shortFees) external override { L75
  74. function transferTokenPositionFrom(address from, address to, TimeswapV2TokenPosition calldata timeswapV2TokenPosition, uint256 amount) external override { L71
  75. long0BalanceTarget = ITimeswapV2Option(optionPair).positionOf(param.strike, param.maturity, address(this), TimeswapV2OptionPosition.Long0) + param.long0Amount; L87
  76. long1BalanceTarget = ITimeswapV2Option(optionPair).positionOf(param.strike, param.maturity, address(this), TimeswapV2OptionPosition.Long1) + param.long1Amount; L117
  77. shortBalanceTarget = ITimeswapV2Option(optionPair).positionOf(param.strike, param.maturity, address(this), TimeswapV2OptionPosition.Short) + param.shortAmount; L146
  78. if (param.long0Amount != 0) Error.checkEnough(ITimeswapV2Option(optionPair).positionOf(param.strike, param.maturity, address(this), TimeswapV2OptionPosition.Long0), long0BalanceTarget); L186
  79. if (param.long1Amount != 0) Error.checkEnough(ITimeswapV2Option(optionPair).positionOf(param.strike, param.maturity, address(this), TimeswapV2OptionPosition.Long1), long1BalanceTarget); L189
  80. if (param.shortAmount != 0) Error.checkEnough(ITimeswapV2Option(optionPair).positionOf(param.strike, param.maturity, address(this), TimeswapV2OptionPosition.Short), shortBalanceTarget); L192
  81. if (param.long0Amount != 0) ITimeswapV2Option(optionPair).transferPosition(param.strike, param.maturity, param.long0To, TimeswapV2OptionPosition.Long0, param.long0Amount); L205
  82. ITimeswapV2Option(optionPair).transferPosition(param.strike, param.maturity, param.long1To, TimeswapV2OptionPosition.Long1, param.long1Amount); L210
  83. if (param.shortAmount != 0) ITimeswapV2Option(optionPair).transferPosition(param.strike, param.maturity, param.shortTo, TimeswapV2OptionPosition.Short, param.shortAmount); L213
  84. function timeswapV2LiquidityTokenMintCallback(TimeswapV2LiquidityTokenMintCallbackParam calldata param) external returns (bytes memory data); L8
  85. function update(FeesPosition storage feesPosition, uint160 liquidity, uint256 long0FeeGrowth, uint256 long1FeeGrowth, uint256 shortFeeGrowth) internal { L29
  86. event TransferPosition(uint256 indexed strike, uint256 indexed maturity, address indexed from, address to, TimeswapV2OptionPosition position, uint256 amount); L21
  87. function totalPosition(uint256 strike, uint256 maturity, TimeswapV2OptionPosition position) external view returns (uint256 balance); L130
  88. function positionOf(uint256 strike, uint256 maturity, address owner, TimeswapV2OptionPosition position) external view returns (uint256 balance); L138
  89. function mint(TimeswapV2OptionMintParam calldata param) external returns (uint256 token0AndLong0Amount, uint256 token1AndLong1Amount, uint256 shortAmount, bytes memory data); L159
  90. function burn(TimeswapV2OptionBurnParam calldata param) external returns (uint256 token0AndLong0Amount, uint256 token1AndLong1Amount, uint256 shortAmount, bytes memory data); L169
  91. function swap(TimeswapV2OptionSwapParam calldata param) external returns (uint256 token0AndLong0Amount, uint256 token1AndLong1Amount, bytes memory data); L182
  92. function collect(TimeswapV2OptionCollectParam calldata param) external returns (uint256 token0Amount, uint256 token1Amount, uint256 shortAmount, bytes memory data); L190
  93. function updateProcess(Process[] storage processing, uint256 token0Amount, uint256 token1Amount, bool isAddToken0, bool isAddToken1) internal { L33
  94. function proportion(uint256 multiplicand, uint256 multiplier, uint256 divisor, bool roundUp) internal pure returns (uint256) { L12
  95. function totalPosition(uint256 strike, uint256 maturity, TimeswapV2OptionPosition position) external view override returns (uint256) { L85
  96. function positionOf(uint256 strike, uint256 maturity, address owner, TimeswapV2OptionPosition position) external view override returns (uint256) { L90
  97. function transferPosition(uint256 strike, uint256 maturity, address to, TimeswapV2OptionPosition position, uint256 amount) external override { L97
  98. ) external override noDelegateCall returns (uint256 token0AndLong0Amount, uint256 token1AndLong1Amount, uint256 shortAmount, bytes memory data) { L111
  99. (token0AndLong0Amount, token1AndLong1Amount, shortAmount) = option.mint(param.strike, param.long0To, param.long1To, param.shortTo, param.transaction, param.amount0, param.amount1); L118
  100. if (token0AndLong0Amount != 0) Error.checkEnough(IERC20(token0).balanceOf(address(this)), currentProcess.balance0Target); L145
  101. if (token1AndLong1Amount != 0) Error.checkEnough(IERC20(token1).balanceOf(address(this)), currentProcess.balance1Target); L148
  102. emit Mint(param.strike, param.maturity, msg.sender, param.long0To, param.long1To, param.shortTo, token0AndLong0Amount, token1AndLong1Amount, shortAmount); L153
  103. ) external override noDelegateCall returns (uint256 token0AndLong0Amount, uint256 token1AndLong1Amount, uint256 shortAmount, bytes memory data) { L159
  104. (token0AndLong0Amount, token1AndLong1Amount, shortAmount) = option.burn(param.strike, param.transaction, param.amount0, param.amount1); L166
  105. emit Burn(param.strike, param.maturity, msg.sender, param.token0To, param.token1To, token0AndLong0Amount, token1AndLong1Amount, shortAmount); L194
  106. function swap(TimeswapV2OptionSwapParam calldata param) external override noDelegateCall returns (uint256 token0AndLong0Amount, uint256 token1AndLong1Amount, bytes memory data) { L198
  107. (token0AndLong0Amount, token1AndLong1Amount) = option.swap(param.strike, param.longTo, param.isLong0ToLong1, param.transaction, param.amount); L205
  108. param.isLong0ToLong1 ? IERC20(token0).balanceOf(address(this)) - token0AndLong0Amount : IERC20(token0).balanceOf(address(this)) + token0AndLong0Amount, L215
  109. param.isLong0ToLong1 ? IERC20(token1).balanceOf(address(this)) + token1AndLong1Amount : IERC20(token1).balanceOf(address(this)) - token1AndLong1Amount L216
  110. IERC20(param.isLong0ToLong1 ? token0 : token1).safeTransfer(param.tokenTo, param.isLong0ToLong1 ? token0AndLong0Amount : token1AndLong1Amount); L220
  111. Error.checkEnough(IERC20(param.isLong0ToLong1 ? token1 : token0).balanceOf(address(this)), param.isLong0ToLong1 ? currentProcess.balance1Target : currentProcess.balance0Target); L235
  112. emit Swap(param.strike, param.maturity, msg.sender, param.tokenTo, param.longTo, param.isLong0ToLong1, token0AndLong0Amount, token1AndLong1Amount); L243
  113. function collect(TimeswapV2OptionCollectParam calldata param) external override noDelegateCall returns (uint256 token0Amount, uint256 token1Amount, uint256 shortAmount, bytes memory data) { L246

Description:

Maximum suggested line length is 120 characters.

#0 - c4-judge

2023-02-01T23:01:05Z

Picodes marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter