Skip to content

Instantly share code, notes, and snippets.

@CloudEllie
Created July 6, 2023 16:26
Show Gist options
  • Save CloudEllie/eafeb9865761200397c00d70febe5f9d to your computer and use it in GitHub Desktop.
Save CloudEllie/eafeb9865761200397c00d70febe5f9d to your computer and use it in GitHub Desktop.
Tapioca Code4rena audit: winning bot race report by IllIllI

Note: There is a section for disputed findings below the gas report section

Summary

Medium Risk Issues

Issue Instances
[M‑01] The owner is a single point of failure and a centralization risk 85
[M‑02] Excess funds sent via msg.value not refunded 1
[M‑03] Contracts are vulnerable to fee-on-transfer accounting-related issues 4
[M‑04] Unsafe use of transfer()/transferFrom() with IERC20 4
[M‑05] Use of transferFrom() rather than safeTransferFrom() for NFTs in will lead to the loss of NFTs 1
[M‑06] Return values of transfer()/transferFrom() not checked 6
[M‑07] _safeMint() should be used rather than _mint() wherever possible 3

Total: 104 instances over 7 issues

Low Risk Issues

Issue Instances
[L‑01] Some tokens may revert when zero value transfers are made 19
[L‑02] calc_token_amount() has slippage added on top of Curve's calculated slippage 1
[L‑03] approve()/safeApprove() may revert if the current approval is not zero 20
[L‑04] Missing contract-existence checks before low-level calls 29
[L‑05] External call recipient may consume all transaction gas 12
[L‑06] Multiplication on the result of a division 8
[L‑07] Division by zero not prevented 13
[L‑08] External calls in an un-bounded for-loop may result in a DOS 61
[L‑09] State variables not capped at reasonable values 3
[L‑10] Missing checks for address(0x0) when assigning values to address state variables 46
[L‑11] Allowed fees/rates should be capped by smart contracts 2
[L‑12] Solidity version 0.8.20 may not work on other chains due to PUSH0 67
[L‑13] Consider implementing two-step procedure for updating protocol addresses 7
[L‑14] Unsafe downcast 64
[L‑15] Loss of precision 121
[L‑16] Array lengths not checked 9
[L‑17] Empty receive()/payable fallback() function does not authorize requests 10
[L‑18] Draft imports may break in new minor versions 7
[L‑19] Functions calling contracts/addresses with transfer hooks are missing reentrancy guards 8
[L‑20] Use Ownable2Step rather than Ownable 4
[L‑21] addRewardToken() does note remove old entries before adding new ones 2
[L‑22] Signature use at deadlines should be allowed 3
[L‑23] NFT doesn't handle hard forks 2
[L‑24] decimals() is not a part of the ERC-20 standard 4
[L‑25] tokenURI() does not follow EIP-721 2
[L‑26] Open TODOs 10
[L‑27] Calls to _get() will revert when totalSupply() returns zero 1
[L‑28] latestAnswer() is deprecated 5
[L‑29] safeApprove() is deprecated 1
[L‑30] Use of a single-step ownership transfer 1

Total: 542 instances over 30 issues

Non-critical Issues

Issue Instances
[N‑01] Events are missing sender information 21
[N‑02] Variables need not be initialized to zero 129
[N‑03] Consider using named mappings 57
[N‑04] Contract uses both require()/revert() as well as custom errors 4
[N‑05] Consider adding a block/deny-list 55
[N‑06] Non-external/public variable and function names should begin with an underscore 89
[N‑07] Large numeric literals should use underscores for readability 15
[N‑08] Unused contract variables 4
[N‑09] Use abi.encodeCall() instead of abi.encodeSignature()/abi.encodeSelector() 58
[N‑10] Constants in comparisons should appear on the left side 92
[N‑11] Consider disabling renounceOwnership() 24
[N‑12] Consider adding emergency-stop functionality 18
[N‑13] Events may be emitted out of order due to reentrancy 23
[N‑14] Function names should use lowerCamelCase 17
[N‑15] Consider bounding input array length 29
[N‑16] Consider moving msg.sender checks to a common authorization modifier 10
[N‑17] Imports could be organized more systematically 27
[N‑18] Overridden function has no body 4
[N‑19] Use OpenZeppelin's or Solady's Ownable, rather than re-inventing the wheel 20
[N‑20] Array is push()ed but not pop()ed 5
[N‑21] Long functions should be refactored into multiple, smaller, functions 7
[N‑22] Mixed usage of int/uint with int256/uint256 7
[N‑23] Unsafe conversion from unsigned to signed values 10
[N‑24] public functions not called by the contract should be declared external instead 74
[N‑25] constants should be defined rather than using magic numbers 194
[N‑26] Event is not properly indexed 22
[N‑27] Duplicated require()/revert() checks should be refactored to a modifier or function 33
[N‑28] Vulnerable versions of packages are being used 6
[N‑29] Import declarations should import specific identifiers, rather than the whole file 345
[N‑30] Return values of approve() not checked 45
[N‑31] Contract implements interface without extending the interface 9
[N‑32] override function arguments that are unused should have the variable name removed or commented out to avoid compiler warnings 5
[N‑33] Cast is more restrictive than the type of the variable being assigned 8
[N‑34] Events that mark critical parameter changes should contain both the old and the new value 59
[N‑35] Constant redefined elsewhere 23
[N‑36] Use @inheritdoc rather than using a non-standard annotation 5
[N‑37] Inconsistent spacing in comments 315
[N‑38] Lines are too long 361
[N‑39] Variable names that consist of all capital letters should be reserved for constant/immutable variables 6
[N‑40] Non-library/interface files should use fixed compiler versions, not floating ones 59
[N‑41] Typos 31
[N‑42] NatSpec @param is missing 329
[N‑43] NatSpec @return argument is missing 168
[N‑44] Avoid the use of sensitive terms 60
[N‑45] Function ordering does not follow the Solidity style guide 81
[N‑46] Contract does not follow the Solidity style guide's suggested layout ordering 15
[N‑47] Control structures do not follow the Solidity Style Guide 5
[N‑48] Expressions for constant values such as a call to keccak256(), should use immutable rather than constant 5
[N‑49] Numeric values having to do with time should use time units for readability 14
[N‑50] Consider using delete rather than assigning zero/false to clear values 19
[N‑51] Contracts should have full test coverage 6
[N‑52] Large or complicated code bases should implement invariant tests 6
[N‑53] Enable IR-based code generation 6
[N‑54] private functions not called by the contract should be removed 1
[N‑55] internal functions not called by the contract should be removed 1
[N‑56] Unused error definition 1
[N‑57] Contract names should use CamelCase 1
[N‑58] Cast to bytes or bytes32 for clearer semantic meaning 2
[N‑59] Custom error has no error details 23
[N‑60] Variable names don't follow the Solidity style guide 4
[N‑61] Contracts containing only utility functions should be made into libraries 2
[N‑62] Unused struct definition 8
[N‑63] if-statement can be converted to a ternary 6
[N‑64] Adding a return statement when the function defines a named return variable, is redundant 3
[N‑65] 2**<n> - 1 should be re-written as type(uint<n>).max 1
[N‑66] require()/revert() statements should have descriptive reason strings 2
[N‑67] Non-assembly method available 2
[N‑68] Missing event and or timelock for critical parameter change 5
[N‑69] Constructor visibility is ignored 1
[N‑70] Visibility should be set explicitly rather than defaulting to internal 10
[N‑71] Memory-safe annotation preferred over comment variant 2
[N‑72] Interfaces should be defined in separate files from their usage 2
[N‑73] Duplicate import statements 1
[N‑74] Using >/>= without specifying an upper bound is unsafe 1
[N‑75] File is missing NatSpec 4
[N‑76] addresss shouldn't be hard-coded 1
[N‑77] pragma experimental ABIEncoderV2 is deprecated 3
[N‑78] Use scientific notation (e.g. 1e18) rather than exponentiation (e.g. 10**18) 2
[N‑79] else-block not required 3
[N‑80] Use a more recent version of solidity 1
[N‑81] Use a more recent version of solidity 3
[N‑82] Strings should use double quotes rather than single quotes 7

Total: 3142 instances over 82 issues

Gas Optimizations

Issue Instances Total Gas Saved
[G‑01] Reduce gas usage by moving to Solidity 0.8.19 or later 68 -
[G‑02] Using bools for storage incurs overhead 17 290700
[G‑03] Avoid updating storage when the value hasn't changed 26 20800
[G‑04] unchecked {} can be used on the division of two uints in order to save gas 76 1520
[G‑05] Remove or replace unused state variables 3 -
[G‑06] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, where appropriate 10 420
[G‑07] State variables only set in the constructor should be declared immutable 27 56619
[G‑08] State variables can be packed into fewer storage slots 6 12000
[G‑09] Using storage instead of memory for structs/arrays saves gas 18 75600
[G‑10] State variables should be cached in stack variables rather than re-reading them from storage 156 15132
[G‑11] <x> += <y> costs more gas than <x> = <x> + <y> for state variables 5 565
[G‑12] Add unchecked {} for subtractions where the operands cannot underflow because of a previous require() or if-statement 21 1785
[G‑13] <array>.length should not be looked up in every loop of a for-loop 24 72
[G‑14] ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for- and while-loops 27 1620
[G‑15] private functions not called by the contract should be removed to save deployment gas 1 -
[G‑16] Optimize names to save gas 54 1188
[G‑17] >= costs less gas than > 2 6
[G‑18] internal functions not called by the contract should be removed to save deployment gas 1 -
[G‑19] ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too) 41 205
[G‑20] Splitting require() statements that use && saves gas 7 21
[G‑21] Using private rather than public for constants, saves gas 17 -
[G‑22] Don't compare boolean expressions to boolean literals 6 54
[G‑23] Multiple if-statements with mutually-exclusive conditions should be changed to if-else statements 2 -
[G‑24] require() or revert() statements that check input arguments should be at the top of the function 3 -
[G‑25] Empty blocks should be removed or emit something 23 -
[G‑26] Superfluous event fields 1 34
[G‑27] Use custom errors rather than revert()/require() strings to save gas 244 -
[G‑28] Functions guaranteed to revert when called by normal users can be marked payable 87 1827
[G‑29] Constructors can be marked payable 50 1050
[G‑30] Structs can be packed into fewer storage slots 5 10000
[G‑31] Inverting the condition of an if-else-statement wastes gas 1 -
[G‑32] Division by two should use bit shifting 3 60
[G‑33] Structs can be packed into fewer storage slots by truncating timestamp bytes 1 2000
[G‑34] Multiple accesses of a mapping/array should use a local variable cache 10 420
[G‑35] internal functions only called once can be inlined to save gas 26 520
[G‑36] require()/revert() strings longer than 32 bytes cost extra gas 23 69
[G‑37] keccak256() should only need to be called on a specific string literal once 3 126
[G‑38] Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead 5 110
[G‑39] Stack variable used as a cheaper cache for a state variable is only used once 1 3
[G‑40] Consider using bytes32 rather than a string 8 -
[G‑41] The result of function calls should be cached rather than re-calling the function 8 -
[G‑42] Use a more recent version of solidity 2 -
[G‑43] Not using the named return variables anywhere in the function is confusing 69 -
[G‑44] Avoid contract existence checks by using low level calls 2 200
[G‑45] String literals passed to abi.encode()/abi.encodePacked() should not be split by commas 1 21

Total: 1191 instances over 45 issues with 494747 gas saved

Gas totals are estimates based on data from the Ethereum Yellowpaper. The estimates use the lower bounds of ranges and count two iterations of each for-loop. All values above are runtime, not deployment, values; deployment values are listed in the individual issue descriptions. The table above as well as its gas numbers do not include any of the excluded findings.

Disputed Issues

The issues below may be reported by other bots/wardens, but can be penalized/ignored since either the rule or the specified instances are invalid

Issue Instances
[D‑01] Storage Write Removal Bug On Conditional Early Termination 16
[D‑02] Do not calculate constant variables, which will save gas 5
[D‑03] Use delete instead of setting mapping/state variable to zero, to save gas 16
[D‑04] abi.encode() is less efficient than abi.encodepacked() 17
[D‑05] Contracts do not work with fee-on-transfer tokens 72
[D‑06] Tokens may be minted to address(0x0) 10
[D‑07] Contracts are not using their OZ Upgradeable counterparts 59
[D‑08] Change public function visibility to external to save gas 70
[D‑09] Save gas with the use of specific import statements 324
[D‑10] safeTransfer function does not check for contract existence 2
[D‑11] Shorten the array rather than copying to a new one 7

Total: 598 instances over 11 issues

Medium Risk Issues

[M‑01] The owner is a single point of failure and a centralization risk

Having a single EOA as the only owner of contracts is a large centralization risk and a single point of failure. A single private key may be taken in a hack, or the sole holder of the key may become unable to retrieve the key when necessary. Consider changing to a multi-signature setup, or having a role-based authorization model.

There are 85 instances of this issue:

see instances
File: contracts/Penrose.sol

256:     function setBigBangEthMarketDebtRate(uint256 _rate) external onlyOwner {

263:     function setBigBangEthMarket(address _market) external onlyOwner {

281:     function setConservator(address _conservator) external onlyOwner {

291:     function setUsdoToken(address _usdoToken) external onlyOwner {

317      function registerSingularityMasterContract(
318          address mcAddress,
319          IPenrose.ContractType contractType_
320:     ) external onlyOwner {

339      function registerBigBangMasterContract(
340          address mcAddress,
341          IPenrose.ContractType contractType_
342:     ) external onlyOwner {

362      function registerSingularity(
363          address mc,
364          bytes calldata data,
365          bool useCreate2
366      )
367          external
368          payable
369          onlyOwner
370          registeredSingularityMasterContract(mc)
371          returns (address _contract)
372:     {

381      function addSingularity(
382          address mc,
383          address _contract
384:     ) external onlyOwner registeredSingularityMasterContract(mc) {

395      function registerBigBang(
396          address mc,
397          bytes calldata data,
398          bool useCreate2
399      )
400          external
401          payable
402          onlyOwner
403          registeredBigBangMasterContract(mc)
404          returns (address _contract)
405:     {

414      function addBigBang(
415          address mc,
416          address _contract
417:     ) external onlyOwner registeredBigBangMasterContract(mc) {

424      function executeMarketFn(
425          address[] calldata mc,
426          bytes[] memory data,
427          bool forceSuccess
428      )
429          external
430          onlyOwner
431          notPaused
432          returns (bool[] memory success, bytes[] memory result)
433:     {

455:     function setFeeTo(address feeTo_) external onlyOwner {

464:     function setSwapper(ISwapper swapper, bool enable) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L256-L256

File: contracts/markets/Market.sol

142:     function setBorrowOpeningFee(uint256 _val) external onlyOwner {

151:     function setBorrowCap(uint256 _cap) external notPaused onlyOwner {

158      function setMarketConfig(
159          uint256 _borrowOpeningFee,
160          IOracle _oracle,
161          bytes calldata _oracleData,
162          address _conservator,
163          uint256 _callerFee,
164          uint256 _protocolFee,
165          uint256 _liquidationBonusAmount,
166          uint256 _minLiquidatorReward,
167          uint256 _maxLiquidatorReward,
168          uint256 _totalBorrowCap,
169          uint256 _collateralizationRate
170:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L142-L142

File: contracts/markets/bigBang/BigBang.sol

442      function refreshPenroseFees(
443          address
444:     ) external onlyOwner notPaused returns (uint256 feeShares) {

466      function setBigBangConfig(
467          uint256 _minDebtRate,
468          uint256 _maxDebtRate,
469          uint256 _debtRateAgainstEthMarket,
470          uint256 _liquidationMultiplier
471:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L442-L444

File: contracts/markets/singularity/Singularity.sol

477      function refreshPenroseFees(
478          address feeTo
479:     ) external onlyOwner notPaused returns (uint256 feeShares) {

489      function setSingularityConfig(
490          uint256 _lqCollateralizationRate,
491          uint256 _liquidationMultiplier,
492          uint256 _minimumTargetUtilization,
493          uint256 _maximumTargetUtilization,
494          uint64 _minimumInterestPerSecond,
495          uint64 _maximumInterestPerSecond,
496          uint256 _interestElasticity
497:     ) external onlyOwner {

576      function setLiquidationQueueConfig(
577          ILiquidationQueue _liquidationQueue,
578          address _bidExecutionSwapper,
579          address _usdoSwapper
580:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L477-L479

File: contracts/usd0/BaseUSDO.sol

88:      function setMaxFlashMintable(uint256 _val) external onlyOwner {

96:      function setFlashMintFee(uint256 _val) external onlyOwner {

105:     function setConservator(address _conservator) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L88-L88

File: contracts/Balancer.sol

172      function rebalance(
173          address payable _srcOft,
174          uint16 _dstChainId,
175          uint256 _slippage,
176          uint256 _amount,
177          bytes memory _ercData
178      )
179          external
180          payable
181          onlyOwner
182          onlyValidDestination(_srcOft, _dstChainId)
183          onlyValidSlippage(_slippage)
184:     {

219      function initConnectedOFT(
220          address _srcOft,
221          uint16 _dstChainId,
222          address _dstOft,
223          bytes memory _ercData
224:     ) external onlyOwner {

250      function addRebalanceAmount(
251          address _srcOft,
252          uint16 _dstChainId,
253          uint256 _amount
254:     ) external onlyValidDestination(_srcOft, _dstChainId) onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L172-L184

File: contracts/TapiocaWrapper.sol

115      function executeTOFT(
116          address _toft,
117          bytes calldata _bytecode,
118          bool _revertOnFailure
119:     ) external payable onlyOwner returns (bool success, bytes memory result) {

131      function executeCalls(
132          ExecutionCall[] calldata _call
133      )
134          external
135          payable
136          onlyOwner
137          returns (bool success, bytes[] memory results)
138:     {

154      function createTOFT(
155          address _erc20,
156          bytes calldata _bytecode,
157          bytes32 _salt,
158          bool _linked
159:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L115-L119

File: contracts/tOFT/mTapiocaOFT.sol

116      function updateConnectedChain(
117          uint256 _chain,
118          bool _status
119:     ) external onlyOwner {

131      function updateBalancerState(
132          address _balancer,
133          bool _status
134:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L116-L119

File: contracts/Vesting.sol

130:     function registerUser(address _user, uint256 _amount) external onlyOwner {

151:     function init(IERC20 _token, uint256 _seededAmount) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L130-L130

File: contracts/governance/twTAP.sol

455:     function addRewardToken(IERC20 token) external onlyOwner returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L455-L455

File: contracts/option-airdrop/AirdropBroker.sol

308      function setTapOracle(
309          IOracle _tapOracle,
310          bytes calldata _tapOracleData
311:     ) external onlyOwner {

318      function setPhase2MerkleRoots(
319          bytes32[4] calldata _merkleRoots
320:     ) external onlyOwner {

324      function registerUserForPhase(
325          uint256 _phase,
326          address[] calldata _users,
327          uint256[] calldata _amounts
328:     ) external onlyOwner {

344      function setPaymentToken(
345          ERC20 _paymentToken,
346          IOracle _oracle,
347          bytes calldata _oracleData
348:     ) external onlyOwner {

357      function setPaymentTokenBeneficiary(
358          address _paymentTokenBeneficiary
359:     ) external onlyOwner {

365      function collectPaymentTokens(
366          address[] calldata _paymentTokens
367:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L308-L311

File: contracts/options/TapiocaOptionBroker.sol

446      function setTapOracle(
447          IOracle _tapOracle,
448          bytes calldata _tapOracleData
449:     ) external onlyOwner {

458      function setPaymentToken(
459          ERC20 _paymentToken,
460          IOracle _oracle,
461          bytes calldata _oracleData
462:     ) external onlyOwner {

471      function setPaymentTokenBeneficiary(
472          address _paymentTokenBeneficiary
473:     ) external onlyOwner {

479      function collectPaymentTokens(
480          address[] calldata _paymentTokens
481:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L446-L449

File: contracts/options/TapiocaOptionLiquidityProvision.sol

259      function setSGLPoolWEight(
260          IERC20 singularity,
261          uint256 weight
262:     ) external onlyOwner updateTotalSGLPoolWeights {

276      function registerSingularity(
277          IERC20 singularity,
278          uint256 assetID,
279          uint256 weight
280:     ) external onlyOwner updateTotalSGLPoolWeights {

297      function unregisterSingularity(
298          IERC20 singularity
299:     ) external onlyOwner updateTotalSGLPoolWeights {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L259-L262

File: contracts/tokens/BaseTapOFT.sol

326:     function setTwTap(address _twTap) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L326-L326

File: contracts/tokens/LTap.sol

53:      function setLockedUntil(uint256 _lockedUntil) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L53-L53

File: contracts/tokens/TapOFT.sol

140      function setGovernanceChainIdentifier(
141          uint256 _identifier
142:     ) external onlyOwner {

152:     function updatePause(bool val) external onlyOwner {

160:     function setMinter(address _minter) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L140-L142

File: contracts/Swapper/UniswapV3Swapper.sol

61:      function setPoolFee(uint24 _newFee) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L61-L61

File: contracts/aave/AaveStrategy.sol

122:     function setDepositThreshold(uint256 amount) external onlyOwner {

129:     function setMultiSwapper(address _swapper) external onlyOwner {

209:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L122-L122

File: contracts/balancer/BalancerStrategy.sol

109:     function setDepositThreshold(uint256 amount) external onlyOwner {

120:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L109-L109

File: contracts/compound/CompoundStrategy.sol

89:      function setDepositThreshold(uint256 amount) external onlyOwner {

100:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L89-L89

File: contracts/convex/ConvexTricryptoStrategy.sol

148:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

163:     function setDepositThreshold(uint256 amount) external onlyOwner {

170:     function setMultiSwapper(address _swapper) external onlyOwner {

179:     function setTricryptoLPGetter(address _lpGetter) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L148-L148

File: contracts/curve/TricryptoLPStrategy.sol

134:     function setDepositThreshold(uint256 amount) external onlyOwner {

141:     function setMultiSwapper(address _swapper) external onlyOwner {

150:     function setTricryptoLPGetter(address _lpGetter) external onlyOwner {

199:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L134-L134

File: contracts/curve/TricryptoNativeStrategy.sol

125:     function setDepositThreshold(uint256 amount) external onlyOwner {

132:     function setMultiSwapper(address _swapper) external onlyOwner {

141:     function setTricryptoLPGetter(address _lpGetter) external onlyOwner {

182:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L125-L125

File: contracts/glp/GlpStrategy.sol

104:     function harvestGmx(uint256 priceNum, uint256 priceDenom) public onlyOwner {

113:     function setFeeRecipient(address recipient) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L104-L104

File: contracts/lido/LidoEthStrategy.sol

93:      function setDepositThreshold(uint256 amount) external onlyOwner {

104:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L93-L93

File: contracts/stargate/StargateStrategy.sol

142:     function setDepositThreshold(uint256 amount) external onlyOwner {

149:     function setMultiSwapper(address _swapper) external onlyOwner {

193:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L142-L142

File: contracts/yearn/YearnStrategy.sol

90:      function setDepositThreshold(uint256 amount) external onlyOwner {

101:     function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L90-L90

File: contracts/NativeTokenFactory.sol

56:      function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {

109:     function mint(uint256 tokenId, address to, uint256 amount) public onlyOwner(tokenId) {

127:     function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L56-L56

[M‑02] Excess funds sent via msg.value not refunded

The code below allows the caller to provide Ether, but does not refund the amount in excess of what's required, leaving funds stranded in the contract. The condition should be changed to check for equality, or the code should refund the excess.

There is one instance of this issue:

File: contracts/Balancer.sol

201          bool _isNative = ITapiocaOFT(_srcOft).erc20() == address(0);
202          if (_isNative) {
203              if (msg.value <= _amount) revert FeeAmountNotSet();
204              _sendNative(_srcOft, _amount, _dstChainId, _slippage);
205          } else {
206              if (msg.value == 0) revert FeeAmountNotSet();
207              _sendToken(_srcOft, _amount, _dstChainId, _slippage, _ercData);
208          }
209  
210          connectedOFTs[_srcOft][_dstChainId].rebalanceable -= _amount;
211          emit Rebalanced(_srcOft, _dstChainId, _slippage, _amount, _isNative);
212:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L201-L212

[M‑03] Contracts are vulnerable to fee-on-transfer accounting-related issues

The functions below transfer funds from the caller to the receiver via transferFrom(), but do not ensure that the actual number of tokens received is the same as the input amount to the transfer. If the token is a fee-on-transfer token, the balance after the transfer will be smaller than expected, leading to accounting issues. Even if there are checks later, related to a secondary transfer, an attacker may be able to use latent funds (e.g. mistakenly sent by another user) in order to get a free credit. One way to solve this problem is to measure the balance before and after the transfer, and use the difference as the amount, rather than the stated amount.

There are 4 instances of this issue:

File: contracts/option-airdrop/AirdropBroker.sol

487      function _processOTCDeal(
488          ERC20 _paymentToken,
489          PaymentTokenOracle memory _paymentTokenOracle,
490          uint256 tapAmount,
491          uint256 discount
492      ) internal {
493          // Get TAP valuation
494          uint256 otcAmountInUSD = tapAmount * epochTAPValuation;
495  
496          // Get payment token valuation
497          (, uint256 paymentTokenValuation) = _paymentTokenOracle.oracle.get(
498              _paymentTokenOracle.oracleData
499          );
500  
501          // Calculate payment amount and initiate the transfers
502          uint256 discountedPaymentAmount = _getDiscountedPaymentAmount(
503              otcAmountInUSD,
504              paymentTokenValuation,
505              discount,
506              _paymentToken.decimals()
507          );
508  
509          _paymentToken.transferFrom(
510              msg.sender,
511              address(this),
512              discountedPaymentAmount
513          );
514          tapOFT.transfer(msg.sender, tapAmount);
515:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L487-L515

File: contracts/options/TapiocaOptionBroker.sol

508      function _processOTCDeal(
509          ERC20 _paymentToken,
510          PaymentTokenOracle memory _paymentTokenOracle,
511          uint256 tapAmount,
512          uint256 discount
513      ) internal {
514          // Get TAP valuation
515          uint256 otcAmountInUSD = tapAmount * epochTAPValuation;
516  
517          // Get payment token valuation
518          (, uint256 paymentTokenValuation) = _paymentTokenOracle.oracle.get(
519              _paymentTokenOracle.oracleData
520          );
521  
522          // Calculate payment amount and initiate the transfers
523          uint256 discountedPaymentAmount = _getDiscountedPaymentAmount(
524              otcAmountInUSD,
525              paymentTokenValuation,
526              discount,
527              _paymentToken.decimals()
528          );
529  
530          _paymentToken.transferFrom(
531              msg.sender,
532              address(this),
533              discountedPaymentAmount
534          );
535          tapOFT.extractTAP(msg.sender, tapAmount);
536:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L508-L536

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

792      function _extractTokens(
793          address _from,
794          address _token,
795          uint256 _amount
796      ) private {
797          IERC20(_token).safeTransferFrom(_from, address(this), _amount);
798:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L792-L798

File: contracts/Swapper/BaseSwapper.sol

144      function _extractTokens(
145          ISwapper.YieldBoxData calldata ybData,
146          IYieldBox _yieldBox,
147          address token,
148          uint256 tokenId,
149          uint256 amount,
150          uint256 share
151      ) internal returns (uint256) {
152          if (ybData.withdrawFromYb) {
153              (amount, share) = _yieldBox.withdraw(
154                  tokenId,
155                  address(this),
156                  address(this),
157                  amount,
158                  share
159              );
160              return amount;
161          }
162          IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
163          return amount;
164:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L144-L164

[M‑04] Unsafe use of transfer()/transferFrom() with IERC20

Some tokens do not implement the ERC20 standard properly but are still accepted by most code that accepts ERC20 tokens. For example Tether (USDT)'s transfer() and transferFrom() functions on L1 do not return booleans as the specification requires, and instead have no return value. When these sorts of tokens are cast to IERC20, their function signatures do not match and therefore the calls made, revert (see this link for a test case). Use OpenZeppelin’s SafeERC20's safeTransfer()/safeTransferFrom() instead

There are 4 instances of this issue:

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

377                   paymentToken.transfer(
378                       paymentTokenBeneficiary,
379                       paymentToken.balanceOf(address(this))
380:                  );

509           _paymentToken.transferFrom(
510               msg.sender,
511               address(this),
512               discountedPaymentAmount
513:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L377-L380

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

491                   paymentToken.transfer(
492                       paymentTokenBeneficiary,
493                       paymentToken.balanceOf(address(this))
494:                  );

530           _paymentToken.transferFrom(
531               msg.sender,
532               address(this),
533               discountedPaymentAmount
534:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L491-L494

[M‑05] Use of transferFrom() rather than safeTransferFrom() for NFTs in will lead to the loss of NFTs

The EIP-721 standard says the following about transferFrom():

    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    ///  THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;

https://github.com/ethereum/EIPs/blob/78e2c297611f5e92b6a5112819ab71f74041ff25/EIPS/eip-721.md?plain=1#L103-L113 Code must use the safeTransferFrom() flavor if it hasn't otherwise verified that the receiving address can handle it

There is one instance of this issue:

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

342:          tOLP.transferFrom(address(this), otapOwner, oTAPPosition.tOLP);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L342

[M‑06] Return values of transfer()/transferFrom() not checked

Not all IERC20 implementations revert() when there's a failure in transfer()/transferFrom(). The function signature has a boolean return value and they indicate errors that way instead. By not checking the return value, operations that should have marked as failed, may potentially go through without actually making a payment

There are 6 instances of this issue:

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

377                   paymentToken.transfer(
378                       paymentTokenBeneficiary,
379                       paymentToken.balanceOf(address(this))
380:                  );

509           _paymentToken.transferFrom(
510               msg.sender,
511               address(this),
512               discountedPaymentAmount
513:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L377-L380

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

491                   paymentToken.transfer(
492                       paymentTokenBeneficiary,
493                       paymentToken.balanceOf(address(this))
494:                  );

530           _paymentToken.transferFrom(
531               msg.sender,
532               address(this),
533               discountedPaymentAmount
534:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L491-L494

File: tap-token-audit/contracts/tokens/LTap.sol

42:           tapToken.transferFrom(msg.sender, address(this), amount);

50:           tapToken.transfer(msg.sender, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L42

[M‑07] _safeMint() should be used rather than _mint() wherever possible

_mint() is discouraged in favor of _safeMint() which ensures that the recipient is either an EOA or implements IERC721Receiver. Both OpenZeppelin and solmate have versions of this function. In the cases below, _mint() does not call ERC721TokenReceiver.onERC721Received() on the recipient.

There are 3 instances of this issue:

File: YieldBox/contracts/YieldBox.sol

139:          _mint(to, assetId, share);

178:          _mint(to, assetId, 1);

204:          _mint(to, assetId, share);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L139

Low Risk Issues

[L‑01] Some tokens may revert when zero value transfers are made

In spite of the fact that EIP-20 states that zero-valued transfers must be accepted, some tokens, such as LEND will revert if this is attempted, which may cause transactions that involve other tokens (such as batch operations) to fully revert. Consider skipping the transfer if the amount is zero, which will also save gas.

There are 19 instances of this issue:

see instances
File: contracts/tOFT/BaseTOFT.sol

356                  "TOFT_allowed"
357              );
358          }
359:         IERC20(erc20).safeTransferFrom(_fromAddress, address(this), _amount);

371          if (erc20 == address(0)) {
372              _safeTransferETH(_toAddress, _amount);
373          } else {
374:             IERC20(erc20).safeTransfer(_toAddress, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L356-L359

File: contracts/tOFT/mTapiocaOFT.sol

145          if (_isNative) {
146              _safeTransferETH(msg.sender, _amount);
147          } else {
148:             IERC20(erc20).safeTransfer(msg.sender, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L145-L148

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

272          if (erc20 == address(0)) {
273              _safeTransferETH(_toAddress, _amount);
274          } else {
275:             IERC20(erc20).safeTransfer(_toAddress, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L272-L275

File: contracts/Vesting.sol

116          users[msg.sender].claimed += _claimable;
117          users[msg.sender].latestClaimTimestamp = block.timestamp;
118  
119:         token.safeTransfer(msg.sender, _claimable);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L116-L119

File: contracts/governance/twTAP.sol

445          totals.totalDistPerVote[_rewardTokenId] +=
446              (_amount * DIST_PRECISION) /
447              uint256(totals.netActiveVotes);
448:         rewardToken.safeTransferFrom(msg.sender, address(this), _amount);

489                  if (amount > 0) {
490                      // Math is safe: `amount` calculated safely in `claimable()`
491                      claimed[_tokenId][i] += amount;
492:                     rewardTokens[i].safeTransfer(_to, amount);

511                  if (amount > 0) {
512                      // Math is safe: `amount` calculated safely in `claimable()`
513                      claimed[_tokenId][claimableIndex] += amount;
514:                     rewardTokens[claimableIndex].safeTransfer(_to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L445-L448

File: contracts/option-airdrop/AirdropBroker.sol

374          unchecked {
375              for (uint256 i = 0; i < len; ++i) {
376                  ERC20 paymentToken = ERC20(_paymentTokens[i]);
377                  paymentToken.transfer(
378                      paymentTokenBeneficiary,
379                      paymentToken.balanceOf(address(this))
380:                 );

506              _paymentToken.decimals()
507          );
508  
509          _paymentToken.transferFrom(
510              msg.sender,
511              address(this),
512              discountedPaymentAmount
513:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L374-L380

File: contracts/options/TapiocaOptionBroker.sol

488          unchecked {
489              for (uint256 i = 0; i < len; ++i) {
490                  ERC20 paymentToken = ERC20(_paymentTokens[i]);
491                  paymentToken.transfer(
492                      paymentTokenBeneficiary,
493                      paymentToken.balanceOf(address(this))
494:                 );

527              _paymentToken.decimals()
528          );
529  
530          _paymentToken.transferFrom(
531              msg.sender,
532              address(this),
533              discountedPaymentAmount
534:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L488-L494

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

420              (uint256 tOLPSglAssetId, , ) = ITapiocaOptionLiquidityProvision(
421                  lockData.target
422              ).activeSingularities(address(singularity));
423              IERC20(address(singularity)).safeTransferFrom(
424                  user,
425                  address(this),
426                  fraction
427:             );

794          address _token,
795          uint256 _amount
796      ) private {
797:         IERC20(_token).safeTransferFrom(_from, address(this), _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L420-L427

File: contracts/Swapper/BaseSwapper.sol

159              );
160              return amount;
161          }
162:         IERC20(token).safeTransferFrom(msg.sender, address(this), amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L159-L162

File: contracts/Swapper/CurveSwapper.sol

137                  0
138              );
139          } else {
140:             IERC20(tokenOut).safeTransfer(to, amountOut);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L137-L140

File: contracts/glp/GlpStrategy.sol

145              glpVester.withdraw();
146          }
147          // Call this first; `_vestByGlp()` will lock the GLP again
148:         IERC20(contractAddress).safeTransfer(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L145-L148

File: contracts/YieldBox.sol

141          // Interactions
142          if (asset.tokenType == TokenType.ERC20) {
143              // For ERC20 tokens, use the safe helper function to deal with broken ERC20 implementations. This actually calls transferFrom on the ERC20 contract.
144:             IERC20(asset.contractAddress).safeTransferFrom(from, address(asset.strategy), amount);

206          // Interactions
207          wrappedNative.deposit{ value: amount }();
208          // Strategies always receive wrappedNative (supporting both wrapped and raw native tokens adds too much complexity)
209:         wrappedNative.safeTransfer(address(asset.strategy), amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L141-L144

[L‑02] calc_token_amount() has slippage added on top of Curve's calculated slippage

According to the Curve docs, StableSwap.calc_token_amount() already includes slippage but not fees, so adding extra slippage on top of the returned result, as is done by the caller of functions higher up the caller chain, is an incorrect operation.

There is one instance of this issue:

File: contracts/curve/TricryptoLPGetter.sol

/// @audit TricryptoNativeStrategy._addLiquidityAndStake()
200      function _calcDepositInOneCoin(
201          uint256[3] memory arr
202      ) private view returns (uint256) {
203:         return liquidityPool.calc_token_amount(arr, true);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPGetter.sol#L200-L203

[L‑03] approve()/safeApprove() may revert if the current approval is not zero

Calling approve() without first calling approve(0) if the current approval is non-zero will revert with some tokens, such as Tether (USDT). While Tether is known to do this, it applies to other tokens as well, which are trying to protect against this attack vector. safeApprove() itself also implements this protection. Always reset the approval to zero before changing it to a new value, or use safeIncreaseAllowance()/safeDecreaseAllowance()

There are 20 instances of this issue:

see instances
File: contracts/markets/bigBang/BigBang.sol

450:             asset.approve(address(yieldBox), totalFees);

761:         asset.approve(address(yieldBox), amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L450-L450

File: contracts/Balancer.sol

321:         erc20.approve(address(router), _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L321-L321

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

215:         IERC20(erc20).approve(externalData.swapper, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L215-L215

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

184:         _erc20.approve(address(yieldBox), _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L184-L184

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

157:             IERC20(collateralAddress).approve(

234:             IERC20(assetAddress).approve(address(yieldBox), depositAmount);

339:                 IERC20(bbCollateralAddress).approve(

386:             IERC20(sglAssetAddress).approve(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L157-L157

File: contracts/aave/AaveStrategy.sol

76:          rewardToken.approve(_multiSwapper, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L76-L76

File: contracts/convex/ConvexTricryptoStrategy.sol

108:         rewardToken.approve(_multiSwapper, type(uint256).max);

172:         rewardToken.approve(address(swapper), 0);

174:         rewardToken.approve(_swapper, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L108-L108

File: contracts/curve/TricryptoLPStrategy.sol

79:          lpToken.approve(_lpGauge, type(uint256).max);

81:          rewardToken.approve(_multiSwapper, type(uint256).max);

143:         rewardToken.approve(address(swapper), 0);

144:         rewardToken.approve(_swapper, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L79-L79

File: contracts/curve/TricryptoNativeStrategy.sol

80:          rewardToken.approve(_multiSwapper, type(uint256).max);

134:         rewardToken.approve(address(swapper), 0);

135:         rewardToken.approve(_swapper, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L80-L80

[L‑04] Missing contract-existence checks before low-level calls

Low-level calls return success if there is no code present at the specified address. In addition to the zero-address checks, add a check to verify that <address>.code.length > 0

There are 29 instances of this issue:

see instances
File: contracts/Penrose.sol

444              (success[i], result[i]) = mc[i].call(data[i]);
445              if (forceSuccess) {
446                  require(success[i], _getRevertMsg(result[i]));
447              }
448              ++i;
449:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L444-L449

File: contracts/markets/bigBang/BigBang.sol

216              (bool success, bytes memory result) = address(this).delegatecall(
217                  calls[i]
218              );
219              require(success || !revertOnFail, _getRevertMsg(result));
220              successes[i] = success;
221:             results[i] = _getRevertMsg(result);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L216-L221

File: contracts/markets/singularity/Singularity.sol

188              (bool success, bytes memory result) = address(this).delegatecall(
189                  calls[i]
190              );
191              require(success || !revertOnFail, _getRevertMsg(result));
192              successes[i] = success;
193:             results[i] = _getRevertMsg(result);

625          (success, returnData) = module.delegatecall(_data);
626          if (!success) {
627              revert(_getRevertMsg(returnData));
628          }
629:     }

638          (success, returnData) = module.staticcall(_data);
639          if (!success) {
640              revert(_getRevertMsg(returnData));
641          }
642:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L188-L193

File: contracts/usd0/BaseUSDO.sol

369          (success, returnData) = module.delegatecall(_data);
370          if (!success && !_forwardRevert) {
371              revert(_getRevertMsg(returnData));
372          }
373:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L369-L373

File: contracts/usd0/modules/USDOLeverageModule.sol

169          (bool success, bytes memory reason) = module.delegatecall(
170              abi.encodeWithSelector(
171                  this.leverageUpInternal.selector,
172                  amount,
173                  swapData,
174:                 externalData,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L169-L174

File: contracts/usd0/modules/USDOMarketModule.sol

168          (bool success, bytes memory reason) = module.delegatecall(
169              abi.encodeWithSelector(
170                  this.lendInternal.selector,
171                  to,
172                  lendParams,
173:                 approvals,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L168-L173

File: contracts/usd0/modules/USDOOptionsModule.sol

174          (bool success, bytes memory reason) = module.delegatecall(
175              abi.encodeWithSelector(
176                  this.exerciseInternal.selector,
177                  optionsData.from,
178                  optionsData.oTAPTokenID,
179:                 optionsData.paymentToken,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L174-L179

File: contracts/TapiocaWrapper.sol

120          (success, result) = payable(_toft).call{value: msg.value}(_bytecode);
121          if (_revertOnFailure && !success) {
122              revert TapiocaWrapper__TOFTExecutionFailed(result);
123          }
124:     }

141              (success, results[i]) = payable(_call[i].toft).call{
142                  value: msg.value
143              }(_call[i].bytecode);
144              if (_call[i].revertOnFailure && !success) {
145                  revert TapiocaWrapper__TOFTExecutionFailed(results[i]);
146:             }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L120-L124

File: contracts/tOFT/BaseTOFT.sol

380          (bool sent, ) = to.call{value: amount}("");
381          require(sent, "TOFT_failed");
382:     }

411          (success, returnData) = module.delegatecall(_data);
412          if (!success && !_forwardRevert) {
413              revert(_getRevertMsg(returnData));
414          }
415:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L380-L382

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

184          (bool success, bytes memory reason) = module.delegatecall(
185              abi.encodeWithSelector(
186                  this.leverageDownInternal.selector,
187                  amount,
188                  swapData,
189:                 externalData,

280          (bool sent, ) = to.call{value: amount}("");
281          require(sent, "TOFT_failed");
282:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L184-L189

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

160          (bool success, bytes memory reason) = module.delegatecall(
161              abi.encodeWithSelector(
162                  this.borrowInternal.selector,
163                  _to,
164                  borrowParams,
165:                 withdrawParams,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L160-L165

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

189          (bool success, bytes memory reason) = module.delegatecall(
190              abi.encodeWithSelector(
191                  this.exerciseInternal.selector,
192                  optionsData.from,
193                  optionsData.oTAPTokenID,
194:                 optionsData.paymentToken,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L189-L194

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

152          (bool success, bytes memory reason) = module.delegatecall(
153              abi.encodeWithSelector(
154                  this.depositToYieldbox.selector,
155                  assetId,
156                  amount,
157:                 share,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L152-L157

File: contracts/tokens/BaseTapOFT.sol

236                      rewardClaimSendParams[i].callParams
237                  );
238                  ++i;
239              }
240          } catch Error(string memory _reason) {
241:             emit CallFailedStr(_srcChainId, _payload, _reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L236-L241

File: contracts/Magnetar/MagnetarV2.sol

1045         (bool success, bytes memory returnData) = target.call(actionCalldata);
1046         if (!success && !allowFailure) {
1047             _getRevertMsg(returnData);
1048         }
1049:    }

1071         (success, returnData) = module.delegatecall(_data);
1072         if (!success) {
1073             _getRevertMsg(returnData);
1074         }
1075:    }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L1045-L1049

File: contracts/Multicall/Multicall3.sol

52                   calli.callData
53               );
54               if (!result.success) {
55                   _getRevertMsg(result.returnData);
56               }
57:              unchecked {

51               (result.success, result.returnData) = calli.target.call(
52                   calli.callData
53               );
54               if (!result.success) {
55                   _getRevertMsg(result.returnData);
56:              }

80                   calli.callData
81               );
82               if (!result.success) {
83                   _getRevertMsg(result.returnData);
84               }
85:              unchecked {

79               (result.success, result.returnData) = calli.target.call{value: val}(
80                   calli.callData
81               );
82               if (!result.success) {
83                   _getRevertMsg(result.returnData);
84:              }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L52-L57

File: contracts/Swapper/BaseSwapper.sol

99           (bool success, bytes memory data) = token.call(
100              abi.encodeWithSelector(0x095ea7b3, to, value)
101          );
102          require(
103              success && (data.length == 0 || abi.decode(data, (bool))),
104:             "BaseSwapper::safeApprove: approve failed"

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L99-L104

File: contracts/convex/ConvexTricryptoStrategy.sol

356          (bool successEmtptyApproval, ) = token.call(
357              abi.encodeWithSelector(
358                  bytes4(keccak256("approve(address,uint256)")),
359                  to,
360                  0
361:             )

369          (bool success, bytes memory data) = token.call(
370              abi.encodeWithSelector(
371                  bytes4(keccak256("approve(address,uint256)")),
372                  to,
373                  value
374:             )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L356-L361

File: contracts/curve/TricryptoLPStrategy.sol

105          (bool success, bytes memory response) = address(lpGauge).staticcall(
106              abi.encodeWithSignature("claimable_tokens(address)", address(this))
107          );
108          result = 0;
109          uint256 claimable = 0;
110:         if (success) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L105-L110

[L‑05] External call recipient may consume all transaction gas

There is no limit specified on the amount of gas used, so the recipient can use up all of the transaction's gas, causing it to revert. Use addr.call{gas: <amount>}("") or this library instead.

There are 12 instances of this issue:

see instances
File: contracts/Penrose.sol

/// @audit `executeMarketFn()`
444:             (success[i], result[i]) = mc[i].call(data[i]);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L444-L444

File: contracts/TapiocaWrapper.sol

/// @audit `executeTOFT()`
120:         (success, result) = payable(_toft).call{value: msg.value}(_bytecode);

/// @audit `executeCalls()`
141:             (success, results[i]) = payable(_call[i].toft).call{

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L120-L120

File: contracts/tOFT/BaseTOFT.sol

/// @audit `_safeTransferETH()`
380:         (bool sent, ) = to.call{value: amount}("");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L380-L380

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

/// @audit `_safeTransferETH()`
280:         (bool sent, ) = to.call{value: amount}("");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L280-L280

File: contracts/Magnetar/MagnetarV2.sol

/// @audit `burst()`
206:                     _action.call.length > 0,

/// @audit `_permit()`
1045:        (bool success, bytes memory returnData) = target.call(actionCalldata);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L206-L206

File: contracts/Multicall/Multicall3.sol

/// @audit `multicall()`
51:              (result.success, result.returnData) = calli.target.call(

/// @audit `multicallValue()`
79:              (result.success, result.returnData) = calli.target.call{value: val}(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L51-L51

File: contracts/Swapper/BaseSwapper.sol

/// @audit `_safeApprove()`
99:          (bool success, bytes memory data) = token.call(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L99-L99

File: contracts/convex/ConvexTricryptoStrategy.sol

/// @audit `_safeApprove()`
356:         (bool successEmtptyApproval, ) = token.call(

/// @audit `_safeApprove()`
369:         (bool success, bytes memory data) = token.call(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L356-L356

[L‑06] Multiplication on the result of a division

Dividing an integer by another integer will often result in loss of precision. When the result is multiplied by another number, the loss of precision is magnified, often to material magnitudes. (X / Z) * Y should be re-written as (X * Y) / Z

There are 8 instances of this issue:

File: contracts/markets/Market.sol

290          uint256 denominator = ((10 ** ratesPrecision) -
291              (collateralizationRate *
292                  ((10 ** ratesPrecision) + liquidationMultiplier)) /
293:             (10 ** ratesPrecision)) * (10 ** (18 - ratesPrecision));

392                  (userCollateralShare[user] *
393                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
394:                     collateralizationRate),

392                  (userCollateralShare[user] *
393:                     (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

417                  collateralShare *
418                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
419:                     collateralizationRate,

417                  collateralShare *
418:                     (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L290-L293

File: contracts/markets/singularity/SGLLiquidation.sol

83               (collateralShare *
84                   (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
85:                  lqCollateralizationRate),

83               (collateralShare *
84:                  (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L83-L85

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

137:         uint256 _discount = Math.max((_g ** 2 / 1 ether) * _a, 1e34); // handle qbrt nonconvergence

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L137-L137

[L‑07] Division by zero not prevented

The divisions below take an input parameter which does not have any zero-value checks, which may lead to the functions reverting when zero is passed.

There are 13 instances of this issue:

see instances
File: contracts/markets/Market.sol

387          uint256 _exchangeRate
388      ) internal view returns (uint256 collateralAmountInAsset) {
389          collateralAmountInAsset =
390              yieldBox.toAmount(
391                  collateralId,
392                  (userCollateralShare[user] *
393                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
394                      collateralizationRate),
395                  false
396              ) /
397:             _exchangeRate;

435              false
436          );
437  
438:         max = (collateralAmount * EXCHANGE_RATE_PRECISION) / _exchangeRate;

486              return 0;
487          }
488          uint256 _numerator = numerator * 10 ** (precision + 1);
489:         uint256 _quotient = ((_numerator / denominator) + 5) / 10;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L387-L397

File: contracts/markets/bigBang/BigBang.sol

778              uint256 collateralShare
779          )
780      {
781          uint256 collateralPartInAsset = (yieldBox.toAmount(
782              collateralId,
783              userCollateralShare[user],
784              false
785:         ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L778-L785

File: contracts/markets/singularity/SGLLiquidation.sol

78   
79           Rebase memory _totalBorrow = totalBorrow;
80   
81           uint256 collateralAmountInAsset = yieldBox.toAmount(
82               collateralId,
83               (collateralShare *
84                   (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
85                   lqCollateralizationRate),
86               false
87:          ) / _exchangeRate;

213              uint256 collateralShare
214          )
215      {
216          uint256 collateralPartInAsset = (yieldBox.toAmount(
217              collateralId,
218              userCollateralShare[user],
219              false
220:         ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L78-L87

File: contracts/option-airdrop/AirdropBroker.sol

527          uint256 _paymentTokenDecimals
528      ) internal pure returns (uint256 paymentAmount) {
529          // Calculate payment amount
530:         uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L527-L530

File: contracts/options/TapiocaOptionBroker.sol

548          uint256 _paymentTokenDecimals
549      ) internal pure returns (uint256 paymentAmount) {
550          // Calculate payment amount
551:         uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L548-L551

File: contracts/twAML.sol

138          if (_cumulative == 0) {
139              return _dMax;
140          }
141:         uint256 target = (_magnitude * _dMax) / _cumulative;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L138-L141

File: contracts/YieldBoxRebase.sol

29           totalShares_ += 1e8;
30   
31           // Calculte the shares using te current amount to share ratio
32:          share = (amount * totalShares_) / totalAmount;

32           share = (amount * totalShares_) / totalAmount;
33   
34           // Default is to round down (Solidity), round up if required
35:          if (roundUp && (share * totalAmount) / totalShares_ < amount) {

52           totalShares_ += 1e8;
53   
54           // Calculte the amount using te current amount to share ratio
55:          amount = (share * totalAmount) / totalShares_;

55           amount = (share * totalAmount) / totalShares_;
56   
57           // Default is to round down (Solidity), round up if required
58:          if (roundUp && (amount * totalShares_) / totalAmount < share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L29-L32

[L‑08] External calls in an un-bounded for-loop may result in a DOS

Consider limiting the number of iterations in for-loops that make external calls

There are 61 instances of this issue:

see instances
File: contracts/markets/singularity/SGLLiquidation.sol

128                  uint256 collateralShare = yieldBox.toShare(
129                      collateralId,
130                      (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,
131                      false
132:                 );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L128-L132

File: contracts/usd0/modules/USDOLeverageModule.sol

289                      IERC20Permit(approvals[i].target).permit(
290                          approvals[i].owner,
291                          approvals[i].spender,
292                          approvals[i].value,
293                          approvals[i].deadline,
294                          approvals[i].v,
295                          approvals[i].r,
296                          approvals[i].s
297:                     )

274                      IPermitAll(approvals[i].target).permitAll(
275                          approvals[i].owner,
276                          approvals[i].spender,
277                          approvals[i].deadline,
278                          approvals[i].v,
279                          approvals[i].r,
280                          approvals[i].s
281:                     )

258                      IPermitBorrow(approvals[i].target).permitBorrow(
259                          approvals[i].owner,
260                          approvals[i].spender,
261                          approvals[i].value,
262                          approvals[i].deadline,
263                          approvals[i].v,
264                          approvals[i].r,
265                          approvals[i].s
266:                     )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L289-L297

File: contracts/usd0/modules/USDOMarketModule.sol

278                      IERC20Permit(approvals[i].target).permit(
279                          approvals[i].owner,
280                          approvals[i].spender,
281                          approvals[i].value,
282                          approvals[i].deadline,
283                          approvals[i].v,
284                          approvals[i].r,
285                          approvals[i].s
286:                     )

263                      IPermitAll(approvals[i].target).permitAll(
264                          approvals[i].owner,
265                          approvals[i].spender,
266                          approvals[i].deadline,
267                          approvals[i].v,
268                          approvals[i].r,
269                          approvals[i].s
270:                     )

247                      IPermitBorrow(approvals[i].target).permitBorrow(
248                          approvals[i].owner,
249                          approvals[i].spender,
250                          approvals[i].value,
251                          approvals[i].deadline,
252                          approvals[i].v,
253                          approvals[i].r,
254                          approvals[i].s
255:                     )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L278-L286

File: contracts/usd0/modules/USDOOptionsModule.sol

279                      IERC20Permit(approvals[i].target).permit(
280                          approvals[i].owner,
281                          approvals[i].spender,
282                          approvals[i].value,
283                          approvals[i].deadline,
284                          approvals[i].v,
285                          approvals[i].r,
286                          approvals[i].s
287:                     )

264                      IPermitAll(approvals[i].target).permitAll(
265                          approvals[i].owner,
266                          approvals[i].spender,
267                          approvals[i].deadline,
268                          approvals[i].v,
269                          approvals[i].r,
270                          approvals[i].s
271:                     )

248                      IPermitBorrow(approvals[i].target).permitBorrow(
249                          approvals[i].owner,
250                          approvals[i].spender,
251                          approvals[i].value,
252                          approvals[i].deadline,
253                          approvals[i].v,
254                          approvals[i].r,
255                          approvals[i].s
256:                     )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L279-L287

File: contracts/TapiocaWrapper.sol

99:              harvestableTapiocaOFTs[i].harvestFees();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L99-L99

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

319                      IERC20Permit(approvals[i].target).permit(
320                          approvals[i].owner,
321                          approvals[i].spender,
322                          approvals[i].value,
323                          approvals[i].deadline,
324                          approvals[i].v,
325                          approvals[i].r,
326                          approvals[i].s
327:                     )

304                      IPermitAll(approvals[i].target).permitAll(
305                          approvals[i].owner,
306                          approvals[i].spender,
307                          approvals[i].deadline,
308                          approvals[i].v,
309                          approvals[i].r,
310                          approvals[i].s
311:                     )

288                      IPermitBorrow(approvals[i].target).permitBorrow(
289                          approvals[i].owner,
290                          approvals[i].spender,
291                          approvals[i].value,
292                          approvals[i].deadline,
293                          approvals[i].v,
294                          approvals[i].r,
295                          approvals[i].s
296:                     )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L319-L327

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

295                      IERC20Permit(approvals[i].target).permit(
296                          approvals[i].owner,
297                          approvals[i].spender,
298                          approvals[i].value,
299                          approvals[i].deadline,
300                          approvals[i].v,
301                          approvals[i].r,
302                          approvals[i].s
303:                     )

280                      IPermitAll(approvals[i].target).permitAll(
281                          approvals[i].owner,
282                          approvals[i].spender,
283                          approvals[i].deadline,
284                          approvals[i].v,
285                          approvals[i].r,
286                          approvals[i].s
287:                     )

264                      IPermitBorrow(approvals[i].target).permitBorrow(
265                          approvals[i].owner,
266                          approvals[i].spender,
267                          approvals[i].value,
268                          approvals[i].deadline,
269                          approvals[i].v,
270                          approvals[i].r,
271                          approvals[i].s
272:                     )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L295-L303

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

294                      IERC20Permit(approvals[i].target).permit(
295                          approvals[i].owner,
296                          approvals[i].spender,
297                          approvals[i].value,
298                          approvals[i].deadline,
299                          approvals[i].v,
300                          approvals[i].r,
301                          approvals[i].s
302:                     )

279                      IPermitAll(approvals[i].target).permitAll(
280                          approvals[i].owner,
281                          approvals[i].spender,
282                          approvals[i].deadline,
283                          approvals[i].v,
284                          approvals[i].r,
285                          approvals[i].s
286:                     )

263                      IPermitBorrow(approvals[i].target).permitBorrow(
264                          approvals[i].owner,
265                          approvals[i].spender,
266                          approvals[i].value,
267                          approvals[i].deadline,
268                          approvals[i].v,
269                          approvals[i].r,
270                          approvals[i].s
271:                     )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L294-L302

File: contracts/option-airdrop/AirdropBroker.sol

377                  paymentToken.transfer(
378                      paymentTokenBeneficiary,
379                      paymentToken.balanceOf(address(this))
380:                 );

379:                     paymentToken.balanceOf(address(this))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L377-L380

File: contracts/options/TapiocaOptionBroker.sol

491                  paymentToken.transfer(
492                      paymentTokenBeneficiary,
493                      paymentToken.balanceOf(address(this))
494:                 );

493:                     paymentToken.balanceOf(address(this))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L491-L494

File: contracts/tokens/BaseTapOFT.sol

229                  ISendFrom(address(rewardTokens[i])).sendFrom{
230                      value: rewardClaimSendParams[i].ethValue
231                  }(
232                      address(this),
233                      _srcChainId,
234                      LzLib.addressToBytes32(to),
235                      IERC20(rewardTokens[i]).balanceOf(address(this)),
236                      rewardClaimSendParams[i].callParams
237:                 );

235:                     IERC20(rewardTokens[i]).balanceOf(address(this)),

335                  IERC20Permit(approvals[i].target).permit(
336                      approvals[i].owner,
337                      approvals[i].spender,
338                      approvals[i].value,
339                      approvals[i].deadline,
340                      approvals[i].v,
341                      approvals[i].r,
342                      approvals[i].s
343:                 )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L229-L237

File: contracts/Magnetar/MagnetarV2.sol

699                  IUSDOBase(_action.target).removeAsset(
700                      data.from,
701                      data.to,
702                      data.lzDstChainId,
703                      data.zroPaymentAddress,
704                      data.adapterParams,
705                      data.externalData,
706                      data.removeAndRepayData,
707                      data.approvals
708:                 );

683                  IUSDOBase(_action.target).initMultiHopBuy(
684                      data.from,
685                      data.collateralAmount,
686                      data.borrowAmount,
687                      data.swapData,
688                      data.lzData,
689                      data.externalData,
690                      data.airdropAdapterParams,
691                      data.approvals
692:                 );

667                  IUSDOBase(_action.target).initMultiHopBuy(
668                      data.from,
669                      data.collateralAmount,
670                      data.borrowAmount,
671                      data.swapData,
672                      data.lzData,
673                      data.externalData,
674                      data.airdropAdapterParams,
675                      data.approvals
676:                 );

655                  ITapiocaOptionsBrokerCrossChain(_action.target).exerciseOption(
656                      data.optionsData,
657                      data.lzData,
658                      data.tapSendData,
659                      data.approvals
660:                 );

642                  IMarket(data.market).sellCollateral(
643                      data.from,
644                      data.share,
645                      data.minAmountOut,
646                      address(data.swapper),
647                      data.dexData
648:                 );

628                  IMarket(data.market).buyCollateral(
629                      data.from,
630                      data.borrowAmount,
631                      data.supplyAmount,
632                      data.minAmountOut,
633                      address(data.swapper),
634                      data.dexData
635:                 );

517                  ITapiocaOFT(_action.target).retrieveFromStrategy{
518                      value: _action.value
519                  }(
520                      msg.sender,
521                      amount,
522                      share,
523                      assetId,
524                      lzDstChainId,
525                      zroPaymentAddress,
526                      airdropAdapterParam
527:                 );

482                  ITapiocaOFT(_action.target).sendToStrategy{
483                      value: _action.value
484                  }(
485                      msg.sender,
486                      data.to,
487                      data.amount,
488                      data.share,
489                      data.assetId,
490                      data.lzDstChainId,
491                      data.options
492:                 );

463                  IUSDOBase(_action.target).sendAndLendOrRepay{
464                      value: _action.value
465                  }(
466                      msg.sender,
467                      to,
468                      dstChainId,
469                      zroPaymentAddress,
470                      lendParams,
471                      approvals,
472                      withdrawParams,
473                      adapterParams
474:                 );

426                  ITapiocaOFT(_action.target).sendToYBAndBorrow{
427                      value: _action.value
428                  }(
429                      msg.sender,
430                      to,
431                      lzDstChainId,
432                      airdropAdapterParams,
433                      borrowParams,
434                      withdrawParams,
435                      options,
436                      approvals
437:                 );

391                  uint256 amount = IMarket(_action.target).repay(
392                      msg.sender,
393                      data.to,
394                      data.skim,
395                      data.part
396:                 );

374                  uint256 fraction = IMarket(_action.target).addAsset(
375                      msg.sender,
376                      data.to,
377                      data.skim,
378                      data.share
379:                 );

316                  (uint256 part, uint256 share) = IMarket(_action.target).borrow(
317                      msg.sender,
318                      data.to,
319                      data.amount
320:                 );

302                  IMarket(_action.target).addCollateral(
303                      msg.sender,
304                      data.to,
305                      data.skim,
306                      data.amount,
307                      data.share
308:                 );

282                  (uint256 amountOut, uint256 shareOut) = IYieldBoxBase(
283                      _action.target
284                  ).depositAsset(
285                          data.assetId,
286                          msg.sender,
287                          data.to,
288                          data.amount,
289                          data.share
290:                     );

268                  ISendFrom(_action.target).sendFrom{value: _action.value}(
269                      msg.sender,
270                      dstChainId,
271                      to,
272                      amount,
273                      lzCallParams
274:                 );

243                      ITapiocaOFT(_action.target).wrap(
244                          msg.sender,
245                          data.to,
246                          data.amount
247:                     );

239                      ITapiocaOFT(_action.target).wrapNative{
240                          value: _action.value
241:                     }(data.to);

978              (uint128 totalAssetElastic, uint128 totalAssetBase) = sgl //
979:                 .totalAsset(); //

982:             result[i].userAssetFraction = sgl.balanceOf(who); //

987:             ) = sgl.getInterestDetails();

1008:            (uint64 debtRate, uint64 lastAccrued) = bigBang.accrueInfo();

1011:            result[i].minDebtRate = bigBang.minDebtRate();

1012:            result[i].maxDebtRate = bigBang.maxDebtRate();

1013             result[i].debtRateAgainstEthMarket = bigBang
1014:                .debtRateAgainstEthMarket();

1015:            result[i].currentDebtRate = bigBang.getDebtRate();

1017:            IPenrose penrose = IPenrose(bigBang.penrose());

1018:            result[i].mainBBMarket = penrose.bigBangEthMarket();

1019:            result[i].mainBBDebtRate = penrose.bigBangEthDebtRate();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L699-L708

File: contracts/convex/ConvexTricryptoStrategy.sol

198                  ISwapper.SwapData memory swapData = swapper.buildSwapData(
199                      tokens[i],
200                      address(wrappedNative),
201                      rewards[i],
202                      0,
203                      false,
204                      false
205:                 );

206:                 uint256 calcAmount = swapper.getOutputAmount(swapData, "");

208:                 swapper.swap(swapData, minAmount, address(this), "");

256              balancesBefore[i] = IERC20(tempData.tokens[i]).balanceOf(
257                  address(this)
258:             );

274              balancesAfter[i] = IERC20(tempData.tokens[i]).balanceOf(
275                  address(this)
276:             );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L198-L205

[L‑09] State variables not capped at reasonable values

Consider adding minimum/maximum value checks to ensure that the state variables below can never be used to excessively harm users, including via griefing

There are 3 instances of this issue:

File: contracts/markets/bigBang/BigBang.sol

159:             maxDebtRate = _debtRateMax;

160:             minDebtRate = _debtRateMin;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L159-L159

File: contracts/tokens/LTap.sol

38:          maxLockedUntil = _maxLockedUntil;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L38-L38

[L‑10] Missing checks for address(0x0) when assigning values to address state variables

There are 46 instances of this issue:

see instances
File: contracts/Penrose.sol

92:          yieldBox = _yieldBox;

93:          tapToken = tapToken_;

94:          owner = _owner;

113:         wethToken = wethToken_;

264:         bigBangEthMarket = _market;

456:         feeTo = feeTo_;

570:                     markets[marketIndex] = clonesOf[mcLocation][j];

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L92-L92

File: contracts/markets/bigBang/BigBang.sol

127:         penrose = tapiocaBar_;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L127-L127

File: contracts/markets/singularity/Singularity.sol

96:          penrose = tapiocaBar_;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L96-L96

File: contracts/usd0/BaseUSDOStorage.sol

80:          yieldBox = _yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L80-L80

File: contracts/tOFT/BaseTOFTStorage.sol

61:          erc20 = _erc20;

64:          yieldBox = _yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L61-L61

File: contracts/Vesting.sol

72:          owner = _owner;

156:         token = _token;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L72-L72

File: contracts/option-airdrop/AirdropBroker.sol

105:         paymentTokenBeneficiary = _paymentTokenBeneficiary;

109:         owner = _owner;

312:         tapOracle = _tapOracle;

349:         paymentTokens[_paymentToken].oracle = _oracle;

360:         paymentTokenBeneficiary = _paymentTokenBeneficiary;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L105-L105

File: contracts/option-airdrop/aoTAP.sol

42:          owner = _owner;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L42-L42

File: contracts/options/TapiocaOptionBroker.sol

89:          paymentTokenBeneficiary = _paymentTokenBeneficiary;

94:          owner = _owner;

450:         tapOracle = _tapOracle;

463:         paymentTokens[_paymentToken].oracle = _oracle;

474:         paymentTokenBeneficiary = _paymentTokenBeneficiary;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L89-L89

File: contracts/options/TapiocaOptionLiquidityProvision.sol

75:          owner = _owner;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L75-L75

File: contracts/tokens/LTap.sol

36:          tapToken = _tapToken;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L36-L36

File: contracts/Swapper/CurveSwapper.sol

40:          curvePool = _curvePool;

41:          yieldBox = _yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L40-L40

File: contracts/Swapper/UniswapV2Swapper.sol

41:          yieldBox = _yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L41-L41

File: contracts/Swapper/UniswapV3Swapper.sol

54:          yieldBox = _yieldBox;

55:          swapRouter = _swapRouter;

56:          factory = _factory;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L54-L54

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

55:          TRI_CRYPTO = pool;

56:          BTC_FEED = btcFeed;

57:          ETH_FEED = ethFeed;

58:          USDT_FEED = usdtFeed;

59:          WBTC_FEED = wbtcFeed;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L55-L55

File: contracts/oracle/implementations/GLPOracle.sol

11:          glpManager = glpManager_;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L11-L11

File: contracts/oracle/implementations/SGOracle.sol

38:          SG_POOL = pool;

39:          UNDERLYING = _underlying;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L38-L38

File: contracts/glp/GlpStrategy.sol

82:          feeRecipient = owner;

114:         feeRecipient = recipient;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L82-L82

File: contracts/stargate/StargateStrategy.sol

79:          stgEthPool = _stgEthPool;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L79-L79

File: contracts/YieldBox.sol

92:          wrappedNative = wrappedNative_;

93:          uriBuilder = uriBuilder_;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L92-L92

[L‑11] Allowed fees/rates should be capped by smart contracts

Fees/rates should be required to be below 100%, preferably at a much lower limit, to ensure users don't have to monitor the blockchain for changes prior to using the protocol

There are 2 instances of this issue:

File: contracts/Penrose.sol

256      function setBigBangEthMarketDebtRate(uint256 _rate) external onlyOwner {
257          bigBangEthDebtRate = _rate;
258          emit BigBangEthMarketDebtRate(_rate);
259:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L256-L259

File: contracts/Swapper/UniswapV3Swapper.sol

61       function setPoolFee(uint24 _newFee) external onlyOwner {
62           emit PoolFee(poolFee, _newFee);
63           poolFee = _newFee;
64:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L61-L64

[L‑12] Solidity version 0.8.20 may not work on other chains due to PUSH0

The compiler for Solidity 0.8.20 switches the default target EVM version to Shanghai, which includes the new PUSH0 op code. This op code may not yet be implemented on all L2s, so deployment on these chains will fail. To work around this issue, use an earlier EVM version. While the project itself may or may not compile with 0.8.20, other projects with which it integrates, or which extend this project may, and those projects will have problems deploying these contracts/libraries.

There are 67 instances of this issue:

see instances
File: contracts/Penrose.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L2-L2

File: contracts/markets/Market.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L2-L2

File: contracts/markets/MarketERC20.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L2-L2

File: contracts/markets/bigBang/BigBang.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L2-L2

File: contracts/markets/singularity/SGLBorrow.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L2-L2

File: contracts/markets/singularity/SGLCollateral.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L2-L2

File: contracts/markets/singularity/SGLCommon.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L2-L2

File: contracts/markets/singularity/SGLLendingCommon.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L2-L2

File: contracts/markets/singularity/SGLLeverage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L2-L2

File: contracts/markets/singularity/SGLLiquidation.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L2-L2

File: contracts/markets/singularity/SGLStorage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L2-L2

File: contracts/markets/singularity/Singularity.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L2-L2

File: contracts/usd0/BaseUSDO.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L2-L2

File: contracts/usd0/BaseUSDOStorage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L2-L2

File: contracts/usd0/USDO.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L2-L2

File: contracts/usd0/modules/USDOLeverageModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L2-L2

File: contracts/usd0/modules/USDOMarketModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L2-L2

File: contracts/usd0/modules/USDOOptionsModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L2-L2

File: contracts/Balancer.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L2-L2

File: contracts/TapiocaWrapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L2-L2

File: contracts/tOFT/BaseTOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L2-L2

File: contracts/tOFT/BaseTOFTStorage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L2-L2

File: contracts/tOFT/TapiocaOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L2-L2

File: contracts/tOFT/mTapiocaOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L2-L2

File: contracts/Vesting.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L2-L2

File: contracts/option-airdrop/AirdropBroker.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L2-L2

File: contracts/option-airdrop/aoTAP.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L2-L2

File: contracts/options/TapiocaOptionBroker.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L2-L2

File: contracts/options/TapiocaOptionLiquidityProvision.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L2-L2

File: contracts/options/oTAP.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L2-L2

File: contracts/tokens/BaseTapOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L2-L2

File: contracts/tokens/LTap.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L2-L2

File: contracts/tokens/TapOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L2-L2

File: contracts/twAML.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L2-L2

File: contracts/Magnetar/MagnetarV2.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L2-L2

File: contracts/Magnetar/MagnetarV2Storage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L2-L2

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L2-L2

File: contracts/Multicall/Multicall3.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L2-L2

File: contracts/Swapper/BaseSwapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L2-L2

File: contracts/Swapper/CurveSwapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L2-L2

File: contracts/Swapper/UniswapV2Swapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L2-L2

File: contracts/Swapper/UniswapV3Swapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L2-L2

File: contracts/TapiocaDeployer/TapiocaDeployer.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L2-L2

File: contracts/oracle/Seer.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L2-L2

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L2-L2

File: contracts/oracle/implementations/GLPOracle.sol

2:   pragma solidity >=0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L2-L2

File: contracts/oracle/implementations/SGOracle.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L2-L2

File: contracts/aave/AaveStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L2-L2

File: contracts/balancer/BalancerStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L2-L2

File: contracts/compound/CompoundStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L2-L2

File: contracts/convex/ConvexTricryptoStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L2-L2

File: contracts/curve/TricryptoLPStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L2-L2

File: contracts/curve/TricryptoNativeStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L2-L2

File: contracts/glp/GlpStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L2-L2

File: contracts/lido/LidoEthStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L2-L2

File: contracts/stargate/StargateStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L2-L2

File: contracts/yearn/YearnStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L2-L2

File: contracts/BoringMath.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L2-L2

File: contracts/NativeTokenFactory.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L2-L2

File: contracts/YieldBox.sol

24:  pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L24-L24

File: contracts/YieldBoxPermit.sol

3:   pragma solidity ^0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L3-L3

File: contracts/YieldBoxRebase.sol

3:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L3-L3

File: contracts/YieldBoxURIBuilder.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L2-L2

[L‑13] Consider implementing two-step procedure for updating protocol addresses

A copy-paste error or a typo may end up bricking protocol functionality, or sending tokens to an address with no known private key. Consider implementing a two-step procedure for updating protocol addresses, where the recipient is set as pending, and must 'accept' the assignment by making an affirmative call. A straight forward way of doing this would be to have the target contracts implement EIP-165, and to have the 'set' functions ensure that the recipient is of the right interface type.

There are 7 instances of this issue:

File: contracts/Penrose.sol

263      function setBigBangEthMarket(address _market) external onlyOwner {
264          bigBangEthMarket = _market;
265          emit BigBangEthMarketSet(_market);
266:     }

455      function setFeeTo(address feeTo_) external onlyOwner {
456          feeTo = feeTo_;
457          emit FeeToUpdate(feeTo_);
458:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L263-L266

File: contracts/option-airdrop/AirdropBroker.sol

308      function setTapOracle(
309          IOracle _tapOracle,
310          bytes calldata _tapOracleData
311      ) external onlyOwner {
312          tapOracle = _tapOracle;
313          tapOracleData = _tapOracleData;
314  
315          emit SetTapOracle(_tapOracle, _tapOracleData);
316:     }

357      function setPaymentTokenBeneficiary(
358          address _paymentTokenBeneficiary
359      ) external onlyOwner {
360          paymentTokenBeneficiary = _paymentTokenBeneficiary;
361:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L308-L316

File: contracts/options/TapiocaOptionBroker.sol

446      function setTapOracle(
447          IOracle _tapOracle,
448          bytes calldata _tapOracleData
449      ) external onlyOwner {
450          tapOracle = _tapOracle;
451          tapOracleData = _tapOracleData;
452  
453          emit SetTapOracle(_tapOracle, _tapOracleData);
454:     }

471      function setPaymentTokenBeneficiary(
472          address _paymentTokenBeneficiary
473      ) external onlyOwner {
474          paymentTokenBeneficiary = _paymentTokenBeneficiary;
475:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L446-L454

File: contracts/glp/GlpStrategy.sol

113      function setFeeRecipient(address recipient) external onlyOwner {
114          feeRecipient = recipient;
115:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L113-L115

[L‑14] Unsafe downcast

When a type is downcast to a smaller type, the higher order bits are truncated, effectively applying a modulo to the original value. Without any other checks, this wrapping will lead to unexpected behavior and bugs

There are 64 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit uint64
521:          _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second

/// @audit uint64
523:          _accrueInfo.lastAccrued = uint64(block.timestamp);

/// @audit uint256 extraAmount -> uint128
535:          _totalBorrow.elastic += uint128(extraAmount);

/// @audit uint256 borrowAmount -> uint128
822:          totalBorrow.elastic -= uint128(borrowAmount);

/// @audit uint256 borrowPart -> uint128
823:          totalBorrow.base -= uint128(borrowPart);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L521

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit uint64
79:           _accrueInfo.lastAccrued = uint64(block.timestamp);

/// @audit uint256 extraAmount -> uint128
104:          _totalBorrow.elastic += uint128(extraAmount);

/// @audit uint256 feeFraction -> uint128
108:          _accrueInfo.feesEarnedFraction += uint128(feeFraction);

/// @audit uint256 feeFraction -> uint128
109:          _totalAsset.base = _totalAsset.base + uint128(feeFraction);

/// @audit uint64
117               _accrueInfo.interestPerSecond = uint64(
118                   (uint256(_accrueInfo.interestPerSecond) * interestElasticity) /
119                       scale
120:              );

/// @audit uint256 newInterestPerSecond -> uint64
135:              _accrueInfo.interestPerSecond = uint64(newInterestPerSecond);

/// @audit uint256 fraction -> uint128
210:          if (_totalAsset.base + uint128(fraction) < 1000) {

/// @audit uint256 share -> uint128
238:          _totalAsset.elastic -= uint128(share);

/// @audit uint256 fraction -> uint128
239:          _totalAsset.base -= uint128(fraction);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L79

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

/// @audit uint256 share -> uint128
76:           _totalAsset.elastic -= uint128(share);

/// @audit uint256 share -> uint128
96:           totalAsset.elastic = totalShare + uint128(share);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L76

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

/// @audit uint256 allBorrowAmount -> uint128
154:          _totalBorrow.elastic -= uint128(allBorrowAmount);

/// @audit uint256 allBorrowPart -> uint128
155:          _totalBorrow.base -= uint128(allBorrowPart);

/// @audit uint128
195:          totalAsset.elastic += uint128(returnedShare - callerShare);

/// @audit uint256 borrowAmount -> uint128
266:          totalBorrow.elastic -= uint128(borrowAmount);

/// @audit uint256 borrowPart -> uint128
267:          totalBorrow.base -= uint128(borrowPart);

/// @audit uint128
284:          totalAsset.elastic += uint128(returnedShare - feeShare - callerShare);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L154

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit uint64
117:          accrueInfo.interestPerSecond = uint64(startingInterestPerSecond); // 1% APR, with 1e18 being 100%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L117

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit uint96
104           tapAssetId = uint96(
105               _yieldBox.registerAsset(
106                   TokenType.ERC20,
107                   address(tapToken_),
108                   emptyStrategies[address(tapToken_)],
109                   0
110               )
111:          );

/// @audit uint96
122           wethAssetId = uint96(
123               _yieldBox.registerAsset(
124                   TokenType.ERC20,
125                   address(wethToken_),
126                   emptyStrategies[address(wethToken_)],
127                   0
128               )
129:          );

/// @audit uint96
302           usdoAssetId = uint96(
303               yieldBox.registerAsset(
304                   TokenType.ERC20,
305                   _usdoToken,
306                   emptyStrategies[_usdoToken],
307                   0
308               )
309:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L104-L111

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit uint256 expiry -> uint56
333:              expiry: uint56(expiry),

/// @audit uint256 _amount -> uint88
334:              tapAmount: uint88(_amount),

/// @audit uint256 multiplier -> uint24
335:              multiplier: uint24(multiplier),

/// @audit uint256 w0 -> uint40
336:              lastInactive: uint40(w0),

/// @audit uint256 w1 -> uint40
337:              lastActive: uint40(w1)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L333

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit uint64
287:          lastEpochUpdate = uint64(block.timestamp);

/// @audit uint256 _epochTAPValuation -> uint128
292:          epochTAPValuation = uint128(_epochTAPValuation);

/// @audit uint128
398:          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch

/// @audit uint256 PHASE_1_DISCOUNT -> uint128
402:              uint128(PHASE_1_DISCOUNT),

/// @audit uint128
433:          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch

/// @audit uint128
435:          uint128 discount = uint128(PHASE_2_DISCOUNT_PER_USER[_role]) * 1e4;

/// @audit uint256 _tokenID -> uint160
448:          address tokenIDToAddress = address(uint160(_tokenID));

/// @audit uint128
458:          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch

/// @audit uint256 PHASE_3_DISCOUNT -> uint128
460:          uint128 discount = uint128(PHASE_3_DISCOUNT);

/// @audit uint128
473:          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch

/// @audit uint256 PHASE_4_DISCOUNT -> uint128
477:              uint128(PHASE_4_DISCOUNT),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L287

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit uint256 target -> uint128
282:              uint128(target),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L282

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit uint128
195:          lockPosition.lockTime = uint128(block.timestamp);

/// @audit uint256 sglAssetID -> uint128
196:          lockPosition.sglAssetID = uint128(sglAssetID);

/// @audit uint256 sglAssetID -> uint128
200:          emit Mint(_to, uint128(sglAssetID), lockPosition);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L195

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit int128 -> int256
/// @audit int256
72:               int128(int256(tokenIndexes[0])),

/// @audit int128 -> int256
/// @audit int256
73:               int128(int256(tokenIndexes[1])),

/// @audit int128 -> int256
/// @audit int256
125:              int128(int256(tokenIndexes[0])),

/// @audit int128 -> int256
/// @audit int256
126:              int128(int256(tokenIndexes[1])),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L72

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit uint256 amountIn -> uint128
101:              uint128(amountIn),

/// @audit uint256 amountOut -> uint128
129:              uint128(amountOut),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L101

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit uint256 lpRouterPid -> uint16
202:              uint16(lpRouterPid),

/// @audit uint256 lpRouterPid -> uint16
254:                  uint16(lpRouterPid),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L202

File: YieldBox/contracts/BoringMath.sol

/// @audit uint256 a -> uint128
7:            c = uint128(a);

/// @audit uint256 a -> uint64
12:           c = uint64(a);

/// @audit uint256 a -> uint32
17:           c = uint32(a);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L7

File: YieldBox/contracts/YieldBoxURIBuilder.sol

/// @audit uint160
37:                                       uint256(uint160(asset.contractAddress)).toHexString(20),

/// @audit uint160
90:                   abi.encodePacked("ERC1155:", uint256(uint160(asset.contractAddress)).toHexString(20), "/", asset.tokenId.toString())

/// @audit uint160
106:                  ? abi.encodePacked(',"tokenAddress":"', uint256(uint160(asset.contractAddress)).toHexString(20), '"')

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L37

[L‑15] Loss of precision

Division by large numbers may result in the result being zero, due to solidity not supporting fractions. Consider requiring a minimum amount for the numerator to ensure that it is always larger than the denominator

There are 121 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

187           uint256 _maxDebtPoint = (_ethMarketTotalDebt *
188:              debtRateAgainstEthMarket) / 1e18;

192           uint256 debtPercentage = ((_currentDebt - debtStartPoint) *
193:              DEBT_PRECISION) / (_maxDebtPoint - debtStartPoint);

194           uint256 debt = ((maxDebtRate - minDebtRate) * debtPercentage) /
195:              DEBT_PRECISION +

521:          _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second

531               (uint256(_totalBorrow.elastic) *
532                   _accrueInfo.debtRate *
533                   elapsedTime) /
534:              1e18;

645:          feeShare = (extraShare * protocolFee) / FEE_PRECISION; // x% of profit goes to fee.

646:          callerShare = (extraShare * callerReward) / FEE_PRECISION; //  y%  of profit goes to caller.

747:          uint256 feeAmount = (amount * borrowOpeningFee) / FEE_PRECISION; // A flat % fee is charged for any borrow

781           uint256 collateralPartInAsset = (yieldBox.toAmount(
782               collateralId,
783               userCollateralShare[user],
784               false
785:          ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;

809               (borrowAmount * liquidationMultiplier) /
810:              FEE_PRECISION;

813:              (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L187-L188

File: tapioca-bar-audit/contracts/markets/Market.sol

265:              borrowPartScaled = borrowPart / (10 ** (borrowPartDecimals - 18));

274                   collateralPartInAsset /
275:                  (10 ** (collateralPartDecimals - 18));

283           uint256 liquidationStartsAt = (collateralPartInAssetScaled *
284:              collateralizationRate) / (10 ** ratesPrecision);

288               ((collateralizationRate * collateralPartInAssetScaled) /
289:                  (10 ** ratesPrecision));

291               (collateralizationRate *
292                   ((10 ** ratesPrecision) + liquidationMultiplier)) /
293:              (10 ** ratesPrecision)) * (10 ** (18 - ratesPrecision));

295:          uint256 x = (numerator * 1e18) / denominator;

323:          borrowPart = (borrowPart * _totalBorrow.elastic) / _totalBorrow.base;

390               yieldBox.toAmount(
391                   collateralId,
392                   (userCollateralShare[user] *
393                       (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
394                       collateralizationRate),
395                   false
396               ) /
397:              _exchangeRate;

393:                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

418:                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

423               (borrowPart * _totalBorrow.elastic * _exchangeRate) /
424:                  _totalBorrow.base;

438:          max = (collateralAmount * EXCHANGE_RATE_PRECISION) / _exchangeRate;

439:          min = (max * collateralizationRate) / FEE_PRECISION;

453           uint256 rewardPercentage = ((borrowed - startTVLInAsset) *
454:              FEE_PRECISION) / (maxTVLInAsset - startTVLInAsset);

457           int256 reward = (diff * int256(rewardPercentage)) /
458:              int256(FEE_PRECISION) +

477:          return (shareRatio * userCollateralShare[user]) / (10 ** assetDecimals);

489:          uint256 _quotient = ((_numerator / denominator) + 5) / 10;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L265

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

63                : (uint256(_totalBorrow.elastic) * UTILIZATION_PRECISION) /
64:                   fullAssetAmount;

100               (uint256(_totalBorrow.elastic) *
101                   _accrueInfo.interestPerSecond *
102                   elapsedTime) /
103:              1e18;

106:          uint256 feeAmount = (extraAmount * protocolFee) / FEE_PRECISION; // % of interest paid goes to fee

107:          feeFraction = (feeAmount * _totalAsset.base) / fullAssetAmount;

113               uint256 underFactor = ((minimumTargetUtilization - utilization) *
114:                  FACTOR_PRECISION) / minimumTargetUtilization;

118                   (uint256(_accrueInfo.interestPerSecond) * interestElasticity) /
119:                      scale

125               uint256 overFactor = ((utilization - maximumTargetUtilization) *
126:                  FACTOR_PRECISION) / fullUtilizationMinusMax;

129               uint256 newInterestPerSecond = (uint256(
130                   _accrueInfo.interestPerSecond
131:              ) * scale) / interestElasticity;

209:              : (share * _totalAsset.base) / allShare;

235:          share = (fraction * allShare) / _totalAsset.base;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L63-L64

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

63:           uint256 feeAmount = (amount * borrowOpeningFee) / FEE_PRECISION; // A flat % fee is charged for any borrow

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L63

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

81            uint256 collateralAmountInAsset = yieldBox.toAmount(
82                collateralId,
83                (collateralShare *
84                    (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
85                    lqCollateralizationRate),
86                false
87:           ) / _exchangeRate;

84:                   (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

89:           borrowPart = (borrowPart * _totalBorrow.elastic) / _totalBorrow.base;

126                       (borrowAmount * liquidationMultiplier) /
127:                      FEE_PRECISION;

130:                      (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

182:          uint256 callerShare = (extraShare * callerFee) / FEE_PRECISION; // 1% goes to caller

216           uint256 collateralPartInAsset = (yieldBox.toAmount(
217               collateralId,
218               userCollateralShare[user],
219               false
220:          ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;

236                   (availableBorrowPart * liquidationBonusAmount) /
237:                  FEE_PRECISION;

253               (borrowAmount * liquidationMultiplier) /
254:              FEE_PRECISION;

257:              (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

278:          feeShare = (extraShare * protocolFee) / FEE_PRECISION; // x% of profit goes to fee.

279:          callerShare = (extraShare * callerReward) / FEE_PRECISION; //  y%  of profit goes to caller.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L81-L87

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

157:          share = (amount * allShare) / totalAsset.base;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L157

File: tapioca-bar-audit/contracts/usd0/USDO.sol

69:           return (amount * flashMintFee) / FLASH_MINT_FEE_PRECISION;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L69

File: tapiocaz-audit/contracts/Balancer.sol

339:          return _amount - ((_amount * _slippage) / SLIPPAGE_PRECISION);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L339

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

57:               _decimal / 2,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L57

File: tap-token-audit/contracts/governance/twTAP.sol

151:          return (block.timestamp - creation) / EPOCH_DURATION;

236:              result[i] = ((votes * net) / DIST_PRECISION) - claimed[_tokenId][i];

280                   (pool.averageMagnitude + magnitude) /
281:                  pool.totalParticipants; // compute new average magnitude

323:          uint256 w1 = (expiry - creation) / EPOCH_DURATION;

446               (_amount * DIST_PRECISION) /
447:              uint256(totals.netActiveVotes);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L151

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

530:          uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

535:          paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L530

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

245                   (pool.averageMagnitude + magnitude) /
246:                  pool.totalParticipants; // compute new average magnitude

551:          uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

555:          paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L245-L246

File: tap-token-audit/contracts/tokens/TapOFT.sol

242:          return ((timestamp - emissionsStartTime) / WEEK) + 1; // Starts at week 1

254:          result = (dso_supply * decay_rate) / DECAY_RATE_DECIMAL;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L242

File: tap-token-audit/contracts/twAML.sol

120:          return mul >= 1e4 ? mul / 1e4 : _totalWeight;

141:          uint256 target = (_magnitude * _dMax) / _cumulative;

150:              uint256 x = y / 2 + 1;

153:                  x = (y / x + x) / 2;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L120

File: tap-token-audit/contracts/Vesting.sol

172:          return (total * (block.timestamp - start)) / duration;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L172

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

105                   (borrowAmount *
106                       market.liquidationMultiplier() *
107                       market.exchangeRate()) /
108:                      (liquidationMultiplierPrecision * exchangeRatePrecision),

161:                  (fraction * totalAssetElastic) / totalAssetBase,

186:          fraction = allShare == 0 ? share : (share * totalAssetBase) / allShare;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L105-L108

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

127:              ? (_wbtcPrice * _btcPrice) / 1e18

132:          _maxPrice = (3 * _vp * FixedPointMathLib.cbrt(_basePrices)) / 1 ether;

135:          uint256 _g = (TRI_CRYPTO.gamma() * 1 ether) / GAMMA0;

136:          uint256 _a = (TRI_CRYPTO.A() * 1 ether) / A0;

137:          uint256 _discount = Math.max((_g ** 2 / 1 ether) * _a, 1e34); // handle qbrt nonconvergence

139:          _discount = (FixedPointMathLib.sqrt(_discount) * DISCOUNT0) / 1 ether;

141:          _maxPrice -= (_maxPrice * _discount) / 1 ether;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L127

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

50            uint256 lpPrice = (SG_POOL.totalLiquidity() *
51:               uint256(UNDERLYING.latestAnswer())) / SG_POOL.totalSupply();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L50-L51

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

113:              result = result - (result * 50) / 10_000; //0.5%

193:              uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L113

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

122:          toWithdraw = toWithdraw - (toWithdraw * 50) / 10_000; //0.5%

177:          bptOut = bptOut - (bptOut * 50) / 10_000; //0.5%

202               uint256 toWithdraw = (((amount - queued) * (10 ** decimals)) /
203:                  pricePerShare);

250:          bptIn = bptIn + (bptIn * 250) / 10_000; //2.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L122

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

116:          uint256 invested = (shares * pricePerShare) / (10 ** 18);

146               uint256 toWithdraw = (((amount - queued) * (10 ** 18)) /
147:                  pricePerShare);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L116

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

143:              result = result - (result * 50) / 10_000; //0.5%

154:          uint256 minAmount = (calcWithdraw * 50) / 10_000; //0.5%

207:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

313:              uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

336:              uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L143

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

179:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

186:                  minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L179

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

116:              result = result - (result * 50) / 10_000; //0.5%

170:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

188:          uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

232:              uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

249:          uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L116

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

171:              uint256 fee = (wethAmount * FEE_BPS) / 10_000;

207           uint256 minTokenReserve = ((vestingNow + vestable) * avgTokenStake) /
208:              totalVestable;

244                   (totalVestable * tokenAvailable) /
245:                  avgTokenStake -

310:          uint256 buffer = (freeEsGmx + stakedEsGmx) / 20;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L171

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

108:          uint256 minAmount = (toWithdraw * 50) / 10_000; //0.5%

151:              uint256 minAmount = toWithdraw - (toWithdraw * 250) / 10_000; //2.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L108

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

133:              result = result - (result * 50) / 10_000; //0.5%

182:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L133

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

114:          uint256 invested = (shares * pricePerShare) / (10 ** vault.decimals());

142               uint256 toWithdraw = (((amount - queued) *
143:                  (10 ** vault.decimals())) / pricePerShare);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L114

File: YieldBox/contracts/BoringMath.sol

26:           result = (value * mul) / div;

27:           if (roundUp && (result * div) / mul < value) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L26

File: YieldBox/contracts/YieldBoxRebase.sol

32:           share = (amount * totalShares_) / totalAmount;

35:           if (roundUp && (share * totalAmount) / totalShares_ < amount) {

55:           amount = (share * totalAmount) / totalShares_;

58:           if (roundUp && (amount * totalShares_) / totalAmount < share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L32

[L‑16] Array lengths not checked

If the length of the arrays are not required to be of the same length, user operations may not be fully executed due to a mismatch in the number of items iterated over, versus the number of items provided in the second array

There are 9 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

309       function liquidate(
310           address[] calldata users,
311           uint256[] calldata maxBorrowParts,
312           ISwapper swapper,
313           bytes calldata collateralToAssetSwapData
314:      ) external notPaused {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L309-L314

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

29        function liquidate(
30            address[] calldata users,
31            uint256[] calldata maxBorrowParts,
32            ISwapper swapper,
33            bytes calldata collateralToAssetSwapData,
34            bytes calldata usdoToBorrowedSwapData
35:       ) external notPaused {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L29-L35

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

440       function liquidate(
441           address[] calldata users,
442           uint256[] calldata maxBorrowParts,
443           ISwapper swapper,
444           bytes calldata collateralToAssetSwapData,
445:          bytes calldata usdoToBorrowedSwapData

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L440-L445

File: tapioca-bar-audit/contracts/Penrose.sol

424       function executeMarketFn(
425           address[] calldata mc,
426           bytes[] memory data,
427           bool forceSuccess
428       )
429           external
430           onlyOwner
431           notPaused
432:          returns (bool[] memory success, bytes[] memory result)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L424-L432

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

163       function claimRewards(
164           address to,
165           uint256 tokenID,
166           address[] memory rewardTokens,
167           uint16 lzDstChainId,
168           address zroPaymentAddress,
169           bytes calldata adapterParams,
170:          IRewardClaimSendFromParams[] calldata rewardClaimSendParams

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L163-L170

File: YieldBox/contracts/NativeTokenFactory.sol

127:      function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {

138:      function batchBurn(uint256 tokenId, address[] calldata froms, uint256[] calldata amounts) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L127

File: YieldBox/contracts/YieldBox.sol

307:      function batchTransfer(address from, address to, uint256[] calldata assetIds_, uint256[] calldata shares_) public {

336:      function transferMultiple(address from, address[] calldata tos, uint256 assetId, uint256[] calldata shares) public allowed(from, assetId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L307

[L‑17] Empty receive()/payable fallback() function does not authorize requests

If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth))). Having no access control on the function means that someone may send Ether to the contract, and have no way to get anything back out, which is a loss of funds. If the concern is having to spend a small amount of gas to check the sender against an immutable address, the code should at least have a function to rescue unused Ether.

There are 10 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

644:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L644

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

68:       receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L68

File: tapiocaz-audit/contracts/Balancer.sol

342:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L342

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

43:       receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L43

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

330:      receive() external payable virtual {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L330

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

340:      receive() external payable virtual {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L340

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

301:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L301

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

164:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L164

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

169:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L169

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

271:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L271

[L‑18] Draft imports may break in new minor versions

While OpenZeppelin draft contracts are safe to use and have been audited, their 'draft' status means that the EIPs they're based on are not finalized, and thus there may be breaking changes in even minor releases. If a bug is found in this version of OpenZeppelin, and the version that you're forced to upgrade to has breaking changes in the new version, you'll encounter unnecessary delays in porting and testing replacement contracts. Ensure that you have extensive test coverage of this area so that differences can be automatically detected, and have a plan in place for how you would fully test a new version of these contracts if they do indeed change unexpectedly. Consider creating a forked version of the file rather than importing it from the package, and manually patch your fork as changes are made.

There are 7 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

5:    import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L5

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

9:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L9

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

9:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L9

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

9:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L9

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

5:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L5

File: tap-token-audit/contracts/tokens/LTap.sol

5:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L5

File: tap-token-audit/contracts/tokens/TapOFT.sol

4:    import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L4

[L‑19] Functions calling contracts/addresses with transfer hooks are missing reentrancy guards

Even if the function follows the best practice of check-effects-interaction, not using a reentrancy guard when there may be transfer hooks will open the users of this protocol up to read-only reentrancies with no way to protect against it, except by block-listing the whole protocol.

There are 8 instances of this issue:

File: contracts/tOFT/mTapiocaOFT.sol

/// @audit `extractUnderlying()`
148:             IERC20(erc20).safeTransfer(msg.sender, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L148-L148

File: contracts/governance/twTAP.sol

/// @audit `distributeReward()`
448:         rewardToken.safeTransferFrom(msg.sender, address(this), _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L448-L448

File: contracts/option-airdrop/AirdropBroker.sol

/// @audit `collectPaymentTokens()`
377:                 paymentToken.transfer(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L377-L377

File: contracts/options/TapiocaOptionBroker.sol

/// @audit `collectPaymentTokens()`
491:                 paymentToken.transfer(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L491-L491

File: contracts/Swapper/CurveSwapper.sol

/// @audit `swap()`
140:             IERC20(tokenOut).safeTransfer(to, amountOut);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L140-L140

File: contracts/YieldBox.sol

/// @audit `depositAsset()`
151:                 IERC1155(asset.contractAddress).safeTransferFrom(from, address(asset.strategy), asset.tokenId, amount, "");

/// @audit `depositAsset()`
144:             IERC20(asset.contractAddress).safeTransferFrom(from, address(asset.strategy), amount);

/// @audit `depositNFTAsset()`
181:         IERC721(asset.contractAddress).safeTransferFrom(from, address(asset.strategy), asset.tokenId);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L151-L151

[L‑20] Use Ownable2Step rather than Ownable

Ownable2Step and Ownable2StepUpgradeable prevent the contract ownership from mistakenly being transferred to an address that cannot handle it (e.g. due to a typo in the address), by requiring that the recipient of the owner permissions actively accept via a contract call of its own.

There are 4 instances of this issue:

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

26    contract TapiocaWrapper is Ownable {
27        struct ExecutionCall {
28            address toft;
29            bytes bytecode;
30:           bool revertOnFailure;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L26-L30

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

30:   contract MagnetarV2 is Ownable, MagnetarV2Storage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L30

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

22    contract Multicall3 is Ownable {
23        struct Call {
24            address target;
25            bool allowFailure;
26:           bytes callData;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L22-L26

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

11:   abstract contract BaseSwapper is Ownable, ReentrancyGuard, ISwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L11

[L‑21] addRewardToken() does note remove old entries before adding new ones

Each time addRewardToken() is called, new entries are added to the array, but doing so does not remove any old entries. By calling the function multiple times, an attacker can can increase their voting power indefinitely, without having to acquire new tokens.

There are 2 instances of this issue:

File: contracts/governance/twTAP.sol

455      function addRewardToken(IERC20 token) external onlyOwner returns (uint256) {
456          uint256 i = rewardTokens.length;
457          rewardTokens.push(token);
458          rewardTokenIndex[token] = i;
459          return i;
460:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L455-L460

File: contracts/options/TapiocaOptionLiquidityProvision.sol

280      ) external onlyOwner updateTotalSGLPoolWeights {
281          require(assetID > 0, "tOLP: invalid asset ID");
282          require(
283              activeSingularities[singularity].sglAssetID == 0,
284              "tOLP: already registered"
285          );
286  
287          activeSingularities[singularity].sglAssetID = assetID;
288          activeSingularities[singularity].poolWeight = weight > 0 ? weight : 1;
289          sglAssetIDToAddress[assetID] = singularity;
290          singularities.push(assetID);
291  
292          emit RegisterSingularity(address(singularity), assetID);
293:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L280-L293

[L‑22] Signature use at deadlines should be allowed

According to EIP-2612, signatures used on exactly the deadline timestamp are supposed to be allowed. While the signature may or may not be used for the exact EIP-2612 use case (transfer approvals), for consistency's sake, all deadlines should follow this semantic. If the timestamp is an expiration rather than a deadline, consider whether it makes more sense to include the expiration timestamp as a valid timestamp, as is done for deadlines.

There are 3 instances of this issue:

File: contracts/governance/twTAP.sol

159:         if (participant.expiry < block.timestamp) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L159-L159

File: contracts/option-airdrop/AirdropBroker.sol

158:         require(aoTapOption.expiry > block.timestamp, "adb: Option expired");

233:         require(aoTapOption.expiry > block.timestamp, "adb: Option expired");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L158-L158

[L‑23] NFT doesn't handle hard forks

When there are hard forks, users often have to go through many hoops to ensure that they control ownership on every fork. Consider adding require(1 == chain.chainId), or the chain ID of whichever chain you prefer, to the functions below, or at least include the chain ID in the URI, so that there is no confusion about which chain is the owner of the NFT.

There are 2 instances of this issue:

File: contracts/option-airdrop/aoTAP.sol

68       function tokenURI(
69           uint256 _tokenId
70       ) public view override returns (string memory) {
71           return tokenURIs[_tokenId];
72:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L68-L72

File: contracts/options/oTAP.sol

54       function tokenURI(
55           uint256 _tokenId
56       ) public view override returns (string memory) {
57           return tokenURIs[_tokenId];
58:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L54-L58

[L‑24] decimals() is not a part of the ERC-20 standard

The decimals() function is not a part of the ERC-20 standard, and was added later as an optional extension. As such, some valid ERC20 tokens do not support this interface, so it is unsafe to blindly cast all tokens to this interface, and then call this function.

There are 4 instances of this issue:

File: contracts/option-airdrop/AirdropBroker.sol

189:             _paymentToken.decimals()

506:             _paymentToken.decimals()

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L189-L189

File: contracts/options/TapiocaOptionBroker.sol

202:             _paymentToken.decimals()

527:             _paymentToken.decimals()

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L202-L202

[L‑25] tokenURI() does not follow EIP-721

The EIP states that tokenURI() "Throws if _tokenId is not a valid NFT", which the code below does not do. If the NFT has not yet been minted, tokenURI() should revert

There are 2 instances of this issue:

File: contracts/option-airdrop/aoTAP.sol

68       function tokenURI(
69           uint256 _tokenId
70       ) public view override returns (string memory) {
71           return tokenURIs[_tokenId];
72:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L68-L72

File: contracts/options/oTAP.sol

54       function tokenURI(
55           uint256 _tokenId
56       ) public view override returns (string memory) {
57           return tokenURIs[_tokenId];
58:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L54-L58

[L‑26] Open TODOs

Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment

There are 10 instances of this issue:

File: tap-token-audit/contracts/governance/twTAP.sol

233:              //    (TODO: Word better?)

289:                  // TODO: Strongly suspect this is never less. Prove it.

347:          // TODO: Mint event?

398:          // TODO: Make whole function unchecked

411:              // TODO: Prove that math is safe

444:          // TODO: Word this better

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L233

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

200:          // uint256 compoundAmount = compoundAmount();//TODO: not view

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L200

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

238:              // (TODO: Check that the multiplication does not overflow!)

241:              // (TODO: Check edge case where the average calculation drops to

331:          // TODO: Check the cast?

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L238

[L‑27] Calls to _get() will revert when totalSupply() returns zero

totalSupply() being zero will result in a division by zero, causing the transaction to fail. The function should instead special-case this scenario, and avoid reverting.

There is one instance of this issue:

File: contracts/oracle/implementations/SGOracle.sol

/// @audit _get()
50           uint256 lpPrice = (SG_POOL.totalLiquidity() *
51:              uint256(UNDERLYING.latestAnswer())) / SG_POOL.totalSupply();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L50-L51

[L‑28] latestAnswer() is deprecated

Use latestRoundData() instead so that you can tell whether the answer is stale or not. The latestAnswer() function returns zero if it is unable to fetch data, which may be the case if ChainLink stops supporting this API. The API and its deprecation message no longer even appear on the ChainLink website, so it is dangerous to continue using it.

There are 5 instances of this issue:

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

121:          uint256 _btcPrice = uint256(BTC_FEED.latestAnswer()) * 1e10;

122:          uint256 _wbtcPrice = uint256(WBTC_FEED.latestAnswer()) * 1e10;

123:          uint256 _ethPrice = uint256(ETH_FEED.latestAnswer()) * 1e10;

124:          uint256 _usdtPrice = uint256(USDT_FEED.latestAnswer()) * 1e10;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L121

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

51:               uint256(UNDERLYING.latestAnswer())) / SG_POOL.totalSupply();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L51

[L‑29] safeApprove() is deprecated

Deprecated in favor of safeIncreaseAllowance() and safeDecreaseAllowance(). If only setting the initial allowance to the value that means infinite, safeIncreaseAllowance() can be used instead. The function may currently work, but if a bug is found in this version of OpenZeppelin, and the version that you're forced to upgrade to no longer has this function, you'll encounter unnecessary delays in porting and testing replacement contracts.

There is one instance of this issue:

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

172:          TransferHelper.safeApprove(tokenIn, address(swapRouter), amountIn);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L172

[L‑30] Use of a single-step ownership transfer

The existing transferOwnership function immediately transfers ownership to the new addres. Consider implementing a two-step variant, where the 'acceptor' of the ownership must call a separate function in order for the transfer to take effect. This can help to prevent mistakes where the wrong address is used, and ownership is irrecoverably lost.

There is one instance of this issue:

File: contracts/NativeTokenFactory.sol

56       function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {
57           if (direct) {
58               // Checks
59               require(newOwner != address(0) || renounce, "NTF: zero address");
60   
61               // Effects
62               emit OwnershipTransferred(tokenId, owner[tokenId], newOwner);
63               owner[tokenId] = newOwner;
64               pendingOwner[tokenId] = address(0);
65           } else {
66               // Effects
67               pendingOwner[tokenId] = newOwner;
68           }
69:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L56-L69

Non-critical Issues

[N‑01] Events are missing sender information

When an action is triggered based on a user's action, not being able to filter based on who triggered the action makes event processing a lot more cumbersome. Including the msg.sender the events of these types of action will make events much more useful to end users, especially when msg.sender is not tx.origin.

There are 21 instances of this issue:

see instances
File: contracts/Penrose.sol

274:         emit PausedUpdated(paused, val);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L274-L274

File: contracts/markets/Market.sol

248:         emit PausedUpdated(paused, val);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L248-L248

File: contracts/markets/MarketERC20.sol

185:         emit Transfer(from, to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L185-L185

File: contracts/markets/bigBang/BigBang.sol

587:         emit LogRemoveCollateral(user, address(swapper), collateralShare);

588:         emit LogRepay(address(swapper), user, borrowAmount, borrowPart);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L587-L587

File: contracts/markets/singularity/SGLLiquidation.sol

134                  emit LogRemoveCollateral(
135                      user,
136                      address(liquidationQueue),
137                      collateralShare
138:                 );

139                  emit LogRepay(
140                      address(liquidationQueue),
141                      user,
142                      borrowAmount,
143                      borrowPart
144:                 );

196          emit LogAddAsset(
197              address(liquidationQueue),
198              address(this),
199              returnedShare - callerShare,
200              0
201:         );

286          emit LogAddAsset(
287              swapper,
288              address(this),
289              extraShare - feeShare - callerShare,
290              0
291:         );

321:         emit LogRemoveCollateral(user, address(swapper), collateralShare);

322:         emit LogRepay(address(swapper), user, borrowAmount, borrowPart);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L134-L138

File: contracts/usd0/BaseUSDO.sol

117:         emit PausedUpdated(paused, val);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L117-L117

File: contracts/usd0/USDO.sol

112:         emit Minted(_to, _amount);

121:         emit Burned(_from, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L112-L112

File: contracts/governance/twTAP.sol

301              emit AMLDivergence(
302                  pool.cumulative,
303                  pool.averageMagnitude,
304                  pool.totalParticipants
305:             );

346:         emit Participate(_participant, _amount, multiplier);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L301-L305

File: contracts/options/TapiocaOptionBroker.sol

264              emit AMLDivergence(
265                  epoch,
266                  pool.cumulative,
267                  pool.averageMagnitude,
268                  pool.totalParticipants
269:             ); // Register new voting power event

285          emit Participate(
286              epoch,
287              lock.sglAssetID,
288              pool.totalDeposited,
289              lock,
290              target
291:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L264-L269

File: contracts/options/TapiocaOptionLiquidityProvision.sol

200:         emit Mint(_to, uint128(sglAssetID), lockPosition);

249:         emit Burn(_to, lockPosition.sglAssetID, lockPosition);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L200-L200

File: contracts/NativeTokenFactory.sol

80:          emit OwnershipTransferred(tokenId, owner[tokenId], _pendingOwner);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L80-L80

[N‑02] Variables need not be initialized to zero

The default value for variables is zero, so initializing them to zero is superfluous.

There are 129 instances of this issue:

see instances
File: contracts/Penrose.sol

437:         for (uint256 i = 0; i < len; ) {

492:             for (uint256 i = 0; i < length; ) {

512:         uint256 amount = 0;

546:         uint256 marketsLength = 0;

550:             for (uint256 i = 0; i < _masterContractLength; ) {

569:                 for (uint256 j = 0; j < clonesOfLength; ) {

564:             for (uint256 i = 0; i < _masterContractLength; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L437-L437

File: contracts/markets/bigBang/BigBang.sol

215:         for (uint256 i = 0; i < calls.length; i++) {

527:         uint256 extraAmount = 0;

603:         uint256 minAssetMount = 0;

665:         uint256 liquidatedCount = 0;

666:         for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L215-L215

File: contracts/markets/singularity/SGLLiquidation.sol

44:                  uint256 needed = 0;

45:                  for (uint256 i = 0; i < maxBorrowParts.length; i++) {

107:         for (uint256 i = 0; i < users.length; i++) {

337:         uint256 minAssetAmount = 0;

383:         uint256 liquidatedCount = 0;

384:         for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L44-L44

File: contracts/markets/singularity/Singularity.sol

187:         for (uint256 i = 0; i < calls.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L187-L187

File: contracts/usd0/modules/USDOLeverageModule.sol

255:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L255-L255

File: contracts/usd0/modules/USDOMarketModule.sol

244:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L244-L244

File: contracts/usd0/modules/USDOOptionsModule.sol

245:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L245-L245

File: contracts/Penrose.sol

437:         for (uint256 i = 0; i < len; ) {

492:             for (uint256 i = 0; i < length; ) {

512:         uint256 amount = 0;

546:         uint256 marketsLength = 0;

550:             for (uint256 i = 0; i < _masterContractLength; ) {

569:                 for (uint256 j = 0; j < clonesOfLength; ) {

564:             for (uint256 i = 0; i < _masterContractLength; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L437-L437

File: contracts/markets/bigBang/BigBang.sol

215:         for (uint256 i = 0; i < calls.length; i++) {

527:         uint256 extraAmount = 0;

603:         uint256 minAssetMount = 0;

665:         uint256 liquidatedCount = 0;

666:         for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L215-L215

File: contracts/markets/singularity/SGLLiquidation.sol

44:                  uint256 needed = 0;

45:                  for (uint256 i = 0; i < maxBorrowParts.length; i++) {

107:         for (uint256 i = 0; i < users.length; i++) {

337:         uint256 minAssetAmount = 0;

383:         uint256 liquidatedCount = 0;

384:         for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L44-L44

File: contracts/markets/singularity/Singularity.sol

187:         for (uint256 i = 0; i < calls.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L187-L187

File: contracts/usd0/modules/USDOLeverageModule.sol

255:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L255-L255

File: contracts/usd0/modules/USDOMarketModule.sol

244:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L244-L244

File: contracts/usd0/modules/USDOOptionsModule.sol

245:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L245-L245

File: contracts/TapiocaWrapper.sol

98:          for (uint256 i = 0; i < harvestableTapiocaOFTs.length; i++) {

140:         for (uint256 i = 0; i < _call.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L98-L98

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

285:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L285-L285

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

261:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L261-L261

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

260:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L260-L260

File: contracts/TapiocaWrapper.sol

98:          for (uint256 i = 0; i < harvestableTapiocaOFTs.length; i++) {

140:         for (uint256 i = 0; i < _call.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L98-L98

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

285:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L285-L285

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

261:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L261-L261

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

260:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L260-L260

File: contracts/Vesting.sol

29:      uint256 public seeded = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L29-L29

File: contracts/governance/twTAP.sol

196:         for (uint256 i = 0; i < len; ) {

413:             for (uint256 i = 0; i < len; ) {

487:             for (uint256 i = 0; i < len; ++i) {

507:             for (uint256 i = 0; i < len; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L196-L196

File: contracts/option-airdrop/AirdropBroker.sol

336:             for (uint256 i = 0; i < _users.length; i++) {

332:             for (uint256 i = 0; i < _users.length; i++) {

375:             for (uint256 i = 0; i < len; ++i) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L336-L336

File: contracts/options/TapiocaOptionBroker.sol

489:             for (uint256 i = 0; i < len; ++i) {

565:             for (uint256 i = 0; i < len; ++i) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L489-L489

File: contracts/options/TapiocaOptionLiquidityProvision.sol

136:             for (uint256 i = 0; i < len; ++i) {

308:             for (uint256 i = 0; i < sglLength; i++) {

339:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L136-L136

File: contracts/tokens/BaseTapOFT.sol

228:             for (uint i = 0; i < len; ) {

333:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L228-L228

File: contracts/governance/twTAP.sol

196:         for (uint256 i = 0; i < len; ) {

413:             for (uint256 i = 0; i < len; ) {

487:             for (uint256 i = 0; i < len; ++i) {

507:             for (uint256 i = 0; i < len; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L196-L196

File: contracts/option-airdrop/AirdropBroker.sol

336:             for (uint256 i = 0; i < _users.length; i++) {

332:             for (uint256 i = 0; i < _users.length; i++) {

375:             for (uint256 i = 0; i < len; ++i) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L336-L336

File: contracts/options/TapiocaOptionBroker.sol

489:             for (uint256 i = 0; i < len; ++i) {

565:             for (uint256 i = 0; i < len; ++i) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L489-L489

File: contracts/options/TapiocaOptionLiquidityProvision.sol

136:             for (uint256 i = 0; i < len; ++i) {

308:             for (uint256 i = 0; i < sglLength; i++) {

339:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L136-L136

File: contracts/tokens/BaseTapOFT.sol

228:             for (uint i = 0; i < len; ) {

333:         for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L228-L228

File: contracts/Magnetar/MagnetarV2.sol

202:         for (uint256 i = 0; i < length; i++) {

973:         for (uint256 i = 0; i < len; i++) {

1004:        for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L202-L202

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

401:         uint256 fraction = 0;

414:         uint256 tOLPTokenId = 0;

508:         uint256 tOLPId = 0;

571:         uint256 _removeAmount = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L401-L401

File: contracts/Multicall/Multicall3.sol

47:          for (uint256 i = 0; i < length; ) {

70:          for (uint256 i = 0; i < length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L47-L47

File: contracts/Magnetar/MagnetarV2.sol

202:         for (uint256 i = 0; i < length; i++) {

973:         for (uint256 i = 0; i < len; i++) {

1004:        for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L202-L202

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

401:         uint256 fraction = 0;

414:         uint256 tOLPTokenId = 0;

508:         uint256 tOLPId = 0;

571:         uint256 _removeAmount = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L401-L401

File: contracts/Multicall/Multicall3.sol

47:          for (uint256 i = 0; i < length; ) {

70:          for (uint256 i = 0; i < length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L47-L47

File: contracts/balancer/BalancerStrategy.sol

156:         for (uint256 i = 0; i < poolTokens.length; i++) {

225:         for (uint256 i = 0; i < poolTokens.length; i++) {

277:         for (uint256 i = 0; i < poolTokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L156-L156

File: contracts/convex/ConvexTricryptoStrategy.sol

195:         for (uint256 i = 0; i < tokens.length; i++) {

255:         for (uint256 i = 0; i < tempData.tokens.length; i++) {

273:         for (uint256 i = 0; i < tempData.tokens.length; i++) {

280:         for (uint256 i = 0; i < tempData.tokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L195-L195

File: contracts/curve/TricryptoLPStrategy.sol

109:         uint256 claimable = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L109-L109

File: contracts/balancer/BalancerStrategy.sol

156:         for (uint256 i = 0; i < poolTokens.length; i++) {

225:         for (uint256 i = 0; i < poolTokens.length; i++) {

277:         for (uint256 i = 0; i < poolTokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L156-L156

File: contracts/convex/ConvexTricryptoStrategy.sol

195:         for (uint256 i = 0; i < tokens.length; i++) {

255:         for (uint256 i = 0; i < tempData.tokens.length; i++) {

273:         for (uint256 i = 0; i < tempData.tokens.length; i++) {

280:         for (uint256 i = 0; i < tempData.tokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L195-L195

File: contracts/curve/TricryptoLPStrategy.sol

109:         uint256 claimable = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L109-L109

File: contracts/NativeTokenFactory.sol

129:         for (uint256 i = 0; i < len; i++) {

141:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L129-L129

File: contracts/YieldBox.sol

309:         for (uint256 i = 0; i < len; i++) {

320:         for (uint256 i = 0; i < len; i++) {

339:         for (uint256 i = 0; i < len; i++) {

345:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L309-L309

File: contracts/NativeTokenFactory.sol

129:         for (uint256 i = 0; i < len; i++) {

141:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L129-L129

File: contracts/YieldBox.sol

309:         for (uint256 i = 0; i < len; i++) {

320:         for (uint256 i = 0; i < len; i++) {

339:         for (uint256 i = 0; i < len; i++) {

345:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L309-L309

[N‑03] Consider using named mappings

Consider moving to solidity version 0.8.18 or later, and using named mappings to make it easier to understand the purpose of each mapping

There are 57 instances of this issue:

see instances
File: contracts/Penrose.sol

61:      mapping(address => bool) public isSingularityMasterContractRegistered;

63:      mapping(address => bool) public isBigBangMasterContractRegistered;

65:      mapping(address => bool) public isMarketRegistered;

79:      mapping(address => IStrategy) public emptyStrategies;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L61-L61

File: contracts/markets/Market.sol

57:      mapping(address => uint256) public userBorrowPart;

59:      mapping(address => uint256) public userCollateralShare;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L57-L57

File: contracts/markets/MarketERC20.sol

48:      mapping(address => uint256) public override balanceOf;

50:      mapping(address => mapping(address => uint256)) public override allowance;

52:      mapping(address => mapping(address => uint256)) public allowanceBorrow;

54:      mapping(address => uint256) private _nonces;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L48-L48

File: contracts/markets/bigBang/BigBang.sol

46:      mapping(address => mapping(address => bool)) public operators;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L46-L46

File: contracts/markets/singularity/SGLStorage.sol

49:      mapping(address => mapping(bytes32 => uint256)) internal _yieldBoxShares;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L49-L49

File: contracts/usd0/BaseUSDOStorage.sol

25:      mapping(uint256 => mapping(address => bool)) public allowedMinter;

28:      mapping(uint256 => mapping(address => bool)) public allowedBurner;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L25-L25

File: contracts/Balancer.sol

49:      mapping(address => mapping(uint16 => OFTData)) public connectedOFTs;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L49-L49

File: contracts/TapiocaWrapper.sol

41:      mapping(address => ITapiocaOFT) public tapiocaOFTsByErc20;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L41-L41

File: contracts/tOFT/mTapiocaOFT.sol

17:      mapping(uint256 => bool) public connectedChains;

21:      mapping(address => bool) public balancers;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L17-L17

File: contracts/Vesting.sol

38:      mapping(address => UserData) public users;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L38-L38

File: contracts/governance/twTAP.sol

59:      mapping(uint256 => uint256) totalDistPerVote;

79:      mapping(uint256 => Participation) public participants; // tokenId => part.

100:     mapping(uint256 => mapping(uint256 => uint256)) public claimed;

109:     mapping(uint256 => WeekTotals) public weekTotals;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L59-L59

File: contracts/option-airdrop/AirdropBroker.sol

57:      mapping(uint256 => mapping(uint256 => uint256)) public aoTAPCalls; // oTAPTokenID => epoch => amountExercised

61:      mapping(address => mapping(uint256 => bool)) public userParticipation; // user address => phase => participated

68:      mapping(address => uint256) public phase1Users;

92:      mapping(address => uint256) public phase4Users;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L57-L57

File: contracts/option-airdrop/aoTAP.sol

36:      mapping(uint256 => AirdropTapOption) public options; // tokenId => Option

37:      mapping(uint256 => string) public tokenURIs; // tokenId => tokenURI

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L36-L36

File: contracts/options/TapiocaOptionBroker.sol

64:      mapping(uint256 => Participation) public participants; // tOLPTokenID => Participation

65:      mapping(uint256 => mapping(uint256 => uint256)) public oTAPCalls; // oTAPTokenID => epoch => amountExercised

67:      mapping(uint256 => mapping(uint256 => uint256)) public singularityGauges; // epoch => sglAssetId => availableTAP

73:      mapping(uint256 => TWAMLPool) public twAML; // sglAssetId => twAMLPool

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L64-L64

File: contracts/options/TapiocaOptionLiquidityProvision.sol

56:      mapping(uint256 => LockPosition) public lockPositions; // TokenID => LockPosition

62:      mapping(uint256 => IERC20) public sglAssetIDToAddress; // Singularity market YieldBox asset ID => Singularity market address

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L56-L56

File: contracts/options/oTAP.sol

34:      mapping(uint256 => TapOption) public options; // tokenId => Option

35:      mapping(uint256 => string) public tokenURIs; // tokenId => tokenURI

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L34-L34

File: contracts/tokens/TapOFT.sol

57:      mapping(uint256 => uint256) public emissionForWeek;

61:      mapping(uint256 => uint256) public mintedInWeek;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L57-L57

File: contracts/Magnetar/MagnetarV2Storage.sol

29:      mapping(address => mapping(address => bool)) public isApprovedForAll;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L29-L29

File: contracts/NativeTokenFactory.sol

24:      mapping(uint256 => NativeToken) public nativeTokens;

25:      mapping(uint256 => address) public owner;

26:      mapping(uint256 => address) public pendingOwner;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L24-L24

File: contracts/YieldBoxPermit.sol

24:      mapping(address => Counters.Counter) private _nonces;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L24-L24

[N‑04] Contract uses both require()/revert() as well as custom errors

Consider using just one method in a single file

There are 4 instances of this issue:

File: contracts/markets/MarketERC20.sol

24   contract MarketERC20 is IERC20, IERC20Permit, EIP712 {
25       // ************ //
26       // *** VARS *** //
27       // ************ //
28:      // solhint-disable-next-line var-name-mixedcase

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L24-L28

File: contracts/Vesting.sol

10:  contract Vesting is BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L10-L10

File: contracts/Swapper/BaseSwapper.sol

11:  abstract contract BaseSwapper is Ownable, ReentrancyGuard, ISwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L11-L11

File: contracts/Swapper/CurveSwapper.sol

23:  contract CurveSwapper is BaseSwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L23-L23

[N‑05] Consider adding a block/deny-list

Doing so will significantly increase centralization, but will help to prevent hackers from using stolen tokens

There are 55 instances of this issue:

see instances
File: contracts/Penrose.sol

32   contract Penrose is BoringOwnable, BoringFactory {
33       // ************ //
34       // *** VARS *** //
35       // ************ //
36:      /// @notice returns the Conservator address

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L32-L36

File: contracts/markets/MarketERC20.sol

24   contract MarketERC20 is IERC20, IERC20Permit, EIP712 {
25       // ************ //
26       // *** VARS *** //
27       // ************ //
28:      // solhint-disable-next-line var-name-mixedcase

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L24-L28

File: contracts/markets/bigBang/BigBang.sol

39:  contract BigBang is BoringOwnable, Market {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L39-L39

File: contracts/markets/singularity/SGLBorrow.sol

8:   contract SGLBorrow is SGLLendingCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L8-L8

File: contracts/markets/singularity/SGLCollateral.sol

8:   contract SGLCollateral is SGLLendingCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L8-L8

File: contracts/markets/singularity/SGLCommon.sol

9:   contract SGLCommon is SGLStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L9-L9

File: contracts/markets/singularity/SGLLendingCommon.sol

8:   contract SGLLendingCommon is SGLCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L8-L8

File: contracts/markets/singularity/SGLLeverage.sol

10:  contract SGLLeverage is SGLLendingCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L10-L10

File: contracts/markets/singularity/SGLLiquidation.sol

10:  contract SGLLiquidation is SGLCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L10-L10

File: contracts/markets/singularity/SGLStorage.sol

34:  contract SGLStorage is BoringOwnable, Market {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L34-L34

File: contracts/markets/singularity/Singularity.sol

37:  contract Singularity is SGLCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L37-L37

File: contracts/usd0/BaseUSDO.sol

46:  contract BaseUSDO is BaseUSDOStorage, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L46-L46

File: contracts/usd0/BaseUSDOStorage.sol

17   contract BaseUSDOStorage is OFTV2 {
18:      /// @notice the YieldBox address.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L17-L18

File: contracts/usd0/USDO.sol

24:  contract USDO is BaseUSDO, IERC3156FlashLender {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L24-L24

File: contracts/usd0/modules/USDOLeverageModule.sol

19:  contract USDOLeverageModule is BaseUSDOStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L19-L19

File: contracts/usd0/modules/USDOMarketModule.sol

21:  contract USDOMarketModule is BaseUSDOStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L21-L21

File: contracts/usd0/modules/USDOOptionsModule.sol

16:  contract USDOOptionsModule is BaseUSDOStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L16-L16

File: contracts/Balancer.sol

34   contract Balancer is Owned {
35       // ************ //
36       // *** VARS *** //
37       // ************ //
38       /// @notice current OFT => chain => destination OFT
39       /// @dev chain ids (https://stargateprotocol.gitbook.io/stargate/developers/chain-ids):
40       ///         - Ethereum: 101
41       ///         - BNB: 102
42       ///         - Avalanche: 106
43       ///         - Polygon: 109
44       ///         - Arbitrum: 110
45       ///         - Optimism: 111
46       ///         - Fantom: 112
47       ///         - Metis: 151
48:      ///     pool ids https://stargateprotocol.gitbook.io/stargate/developers/pool-ids

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L34-L48

File: contracts/TapiocaWrapper.sol

26:  contract TapiocaWrapper is Ownable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L26-L26

File: contracts/tOFT/BaseTOFT.sol

15:  contract BaseTOFT is BaseTOFTStorage, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L15-L15

File: contracts/tOFT/BaseTOFTStorage.sol

21   contract BaseTOFTStorage is OFTV2 {
22       // ************ //
23       // *** VARS *** //
24       // ************ //
25:      /// @notice The YieldBox address.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L21-L25

File: contracts/tOFT/TapiocaOFT.sol

21:  contract TapiocaOFT is BaseTOFT {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L21-L21

File: contracts/tOFT/mTapiocaOFT.sol

9:   contract mTapiocaOFT is BaseTOFT {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L9-L9

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

21:  contract BaseTOFTLeverageModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L21-L21

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

20:  contract BaseTOFTMarketModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L20-L20

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

16:  contract BaseTOFTOptionsModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L16-L16

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

16:  contract BaseTOFTStrategyModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L16-L16

File: contracts/Vesting.sol

10:  contract Vesting is BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L10-L10

File: contracts/governance/twTAP.sol

71:  contract TwTAP is TWAML, ONFT721, ERC721Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L71-L71

File: contracts/option-airdrop/AirdropBroker.sol

43:  contract AirdropBroker is Pausable, BoringOwnable, FullMath {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L43-L43

File: contracts/option-airdrop/aoTAP.sol

32:  contract AOTAP is ERC721, ERC721Permit, BaseBoringBatchable, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L32-L32

File: contracts/options/TapiocaOptionBroker.sol

53:  contract TapiocaOptionBroker is Pausable, BoringOwnable, TWAML {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L53-L53

File: contracts/options/TapiocaOptionLiquidityProvision.sol

48   contract TapiocaOptionLiquidityProvision is
49       ERC721,
50       ERC721Permit,
51       BaseBoringBatchable,
52       Pausable,
53       BoringOwnable
54:  {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L48-L54

File: contracts/options/oTAP.sol

30:  contract OTAP is ERC721, ERC721Permit, BaseBoringBatchable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L30-L30

File: contracts/tokens/LTap.sol

23:  contract LTap is BoringOwnable, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L23-L23

File: contracts/tokens/TapOFT.sol

26   contract TapOFT is BaseTapOFT, ERC20Permit {
27       // ==========
28       // *DATA*
29       // ==========
30   
31       //  Allocation:
32       // =========
33       // * DSO: 53,313,405
34       // * DAO: 8m
35       // * Contributors: 15m
36       // * Early supporters: 3,686,595
37       // * Supporters: 12.5m
38       // * LBP: 5m
39       // * Airdrop: 2.5m
40:      // == 100M ==

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L26-L40

File: contracts/Magnetar/MagnetarV2.sol

30:  contract MagnetarV2 is Ownable, MagnetarV2Storage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L30-L30

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

20:  contract MagnetarMarketModule is MagnetarV2Storage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L20-L20

File: contracts/Swapper/CurveSwapper.sol

23:  contract CurveSwapper is BaseSwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L23-L23

File: contracts/Swapper/UniswapV2Swapper.sol

21:  contract UniswapV2Swapper is BaseSwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L21-L21

File: contracts/Swapper/UniswapV3Swapper.sol

28:  contract UniswapV3Swapper is BaseSwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L28-L28

File: contracts/oracle/Seer.sol

7:   contract Seer is ITOracle, OracleMulti {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L7-L7

File: contracts/aave/AaveStrategy.sol

29:  contract AaveStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L29-L29

File: contracts/balancer/BalancerStrategy.sol

28:  contract BalancerStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L28-L28

File: contracts/compound/CompoundStrategy.sol

28:  contract CompoundStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L28-L28

File: contracts/convex/ConvexTricryptoStrategy.sol

31   contract ConvexTricryptoStrategy is
32       BaseERC20Strategy,
33       BoringOwnable,
34       ReentrancyGuard
35:  {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L31-L35

File: contracts/curve/TricryptoLPStrategy.sol

30   contract TricryptoLPStrategy is
31       BaseERC20Strategy,
32       BoringOwnable,
33       ReentrancyGuard
34:  {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L30-L34

File: contracts/curve/TricryptoNativeStrategy.sol

30   contract TricryptoNativeStrategy is
31       BaseERC20Strategy,
32       BoringOwnable,
33       ReentrancyGuard
34:  {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L30-L34

File: contracts/glp/GlpStrategy.sol

23:  contract GlpStrategy is BaseERC20Strategy, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L23-L23

File: contracts/lido/LidoEthStrategy.sol

30:  contract LidoEthStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L30-L30

File: contracts/stargate/StargateStrategy.sol

35:  contract StargateStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L35-L35

File: contracts/yearn/YearnStrategy.sol

30:  contract YearnStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L30-L30

File: contracts/NativeTokenFactory.sol

21:  contract NativeTokenFactory is AssetRegister {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L21-L21

File: contracts/YieldBox.sol

50   contract YieldBox is YieldBoxPermit, BoringBatchable, NativeTokenFactory, ERC721TokenReceiver, ERC1155TokenReceiver {
51       // ******************* //
52       // *** CONSTRUCTOR *** //
53:      // ******************* //

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L50-L53

File: contracts/YieldBoxURIBuilder.sol

11:  contract YieldBoxURIBuilder {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L11-L11

[N‑06] Non-external/public variable and function names should begin with an underscore

According to the Solidity Style Guide, Non-external/public variable and function names should begin with an underscore

There are 89 instances of this issue:

see instances
File: contracts/markets/Market.sol

82:      uint256 internal EXCHANGE_RATE_PRECISION; //not costant, but can only be set in the 'init' method

83:      uint256 internal constant FEE_PRECISION = 1e5;

84:      uint256 internal constant FEE_PRECISION_DECIMALS = 5;

129:     bool internal initialized;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L82-L82

File: contracts/markets/bigBang/BigBang.sol

57:      uint256 private constant DEBT_PRECISION = 1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L57-L57

File: contracts/markets/singularity/SGLStorage.sol

50       bytes32 internal ASSET_SIG =
51:          0x0bd4060688a1800ae986e4840aebc924bb40b5bf44de4583df2257220b54b77c; // keccak256("asset")

52       bytes32 internal COLLATERAL_SIG =
53:          0x7d1dc38e60930664f8cbf495da6556ca091d2f92d6550877750c049864b18230; // keccak256("collateral")

143:     uint256 internal constant FULL_UTILIZATION = 1e18;

144:     uint256 internal constant UTILIZATION_PRECISION = 1e18;

146:     uint256 internal constant FACTOR_PRECISION = 1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L50-L51

File: contracts/usd0/BaseUSDOStorage.sol

37:      uint256 internal constant FLASH_MINT_FEE_PRECISION = 1e6;

38       bytes32 internal constant FLASH_MINT_CALLBACK_SUCCESS =
39:          keccak256("ERC3156FlashBorrower.onFlashLoan");

41:      uint16 internal constant PT_MARKET_MULTIHOP_BUY = 772;

42:      uint16 internal constant PT_MARKET_REMOVE_ASSET = 773;

43:      uint16 internal constant PT_YB_SEND_SGL_LEND_OR_REPAY = 774;

44:      uint16 internal constant PT_LEVERAGE_MARKET_UP = 775;

45:      uint16 internal constant PT_TAP_EXERCISE = 777;

46:      uint16 internal constant PT_SEND_FROM = 778;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L37-L37

File: contracts/Balancer.sol

63:      uint256 private constant SLIPPAGE_PRECISION = 1e5;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L63-L63

File: contracts/TapiocaWrapper.sol

39:      ITapiocaOFT[] private harvestableTapiocaOFTs;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L39-L39

File: contracts/tOFT/BaseTOFTStorage.sol

34:      uint16 internal constant PT_YB_SEND_STRAT = 770;

35:      uint16 internal constant PT_YB_RETRIEVE_STRAT = 771;

36:      uint16 internal constant PT_MARKET_REMOVE_COLLATERAL = 772;

37:      uint16 internal constant PT_MARKET_MULTIHOP_SELL = 773;

38:      uint16 internal constant PT_YB_SEND_SGL_BORROW = 775;

39:      uint16 internal constant PT_LEVERAGE_MARKET_DOWN = 776;

40:      uint16 internal constant PT_TAP_EXERCISE = 777;

41:      uint16 internal constant PT_SEND_FROM = 778;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L34-L34

File: contracts/governance/twTAP.sol

81:      uint256 constant MIN_WEIGHT_FACTOR = 10; // In BPS, 0.1%

82:      uint256 constant dMAX = 100 * 1e4; // 10% - 100% voting power multiplier

83:      uint256 constant dMIN = 10 * 1e4;

95:      uint256 constant DIST_PRECISION = 2 ** 128;

112:     string private baseURI;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L81-L81

File: contracts/options/TapiocaOptionBroker.sol

75:      uint256 constant MIN_WEIGHT_FACTOR = 10; // In BPS, 0.1%

76:      uint256 constant dMAX = 50 * 1e4; // 5% - 50% discount

77:      uint256 constant dMIN = 5 * 1e4;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L75-L75

File: contracts/tokens/BaseTapOFT.sol

37:      uint16 internal constant PT_LOCK_TWTAP = 870;

38:      uint16 internal constant PT_UNLOCK_TWTAP = 871;

39:      uint16 internal constant PT_CLAIM_REWARDS = 872;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L37-L37

File: contracts/tokens/LTap.sol

24:      IERC20 tapToken;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L24-L24

File: contracts/tokens/TapOFT.sol

45:      uint256 constant decay_rate = 8800000000000000; // 0.88%

46:      uint256 constant DECAY_RATE_DECIMAL = 1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L45-L45

File: contracts/twAML.sol

6        function muldiv(
7            uint256 a,
8            uint256 b,
9            uint256 denominator
10:      ) internal pure returns (uint256 result) {

115      function computeMinWeight(
116          uint256 _totalWeight,
117          uint256 _minWeightFactor
118:     ) internal pure returns (uint256) {

123      function computeMagnitude(
124          uint256 _timeWeight,
125          uint256 _cumulative
126:     ) internal pure returns (uint256) {

132      function computeTarget(
133          uint256 _dMin,
134          uint256 _dMax,
135          uint256 _magnitude,
136          uint256 _cumulative
137:     ) internal pure returns (uint256) {

147:     function sqrt(uint256 y) internal pure returns (uint256 z) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L6-L10

File: contracts/Magnetar/MagnetarV2Storage.sol

298:     uint16 internal constant PERMIT_ALL = 1;

299:     uint16 internal constant PERMIT = 2;

301:     uint16 internal constant YB_DEPOSIT_ASSET = 100;

302:     uint16 internal constant YB_WITHDRAW_TO = 102;

304:     uint16 internal constant MARKET_ADD_COLLATERAL = 200;

305:     uint16 internal constant MARKET_BORROW = 201;

306:     uint16 internal constant MARKET_LEND = 203;

307:     uint16 internal constant MARKET_REPAY = 204;

308:     uint16 internal constant MARKET_YBDEPOSIT_AND_LEND = 205;

309:     uint16 internal constant MARKET_YBDEPOSIT_COLLATERAL_AND_BORROW = 206;

310:     uint16 internal constant MARKET_REMOVE_ASSET = 207;

311:     uint16 internal constant MARKET_DEPOSIT_REPAY_REMOVE_COLLATERAL = 208;

312:     uint16 internal constant MARKET_BUY_COLLATERAL = 209;

313:     uint16 internal constant MARKET_SELL_COLLATERAL = 210;

314:     uint16 internal constant MARKET_MULTIHOP_BUY = 211;

315:     uint16 internal constant MARKET_MULTIHOP_SELL = 212;

317:     uint16 internal constant TOFT_WRAP = 300;

318:     uint16 internal constant TOFT_SEND_FROM = 301;

319:     uint16 internal constant TOFT_SEND_APPROVAL = 302;

320:     uint16 internal constant TOFT_SEND_AND_BORROW = 303;

321:     uint16 internal constant TOFT_SEND_AND_LEND = 304;

322:     uint16 internal constant TOFT_DEPOSIT_TO_STRATEGY = 305;

323:     uint16 internal constant TOFT_RETRIEVE_FROM_STRATEGY = 306;

324:     uint16 internal constant TOFT_REMOVE_AND_REPAY = 307;

326:     uint16 internal constant TAP_EXERCISE_OPTION = 400;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L298-L298

File: contracts/Swapper/UniswapV3Swapper.sol

34:      IYieldBox private immutable yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L34-L34

File: contracts/oracle/implementations/GLPOracle.sol

8:       IGmxGlpManager private immutable glpManager;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L8-L8

File: contracts/glp/GlpStrategy.sol

30:      IERC20 private immutable gmx;

31:      IERC20 private immutable esGmx;

32:      IERC20 private immutable weth;

34:      IGmxRewardTracker private immutable feeGmxTracker;

35:      IGlpManager private immutable glpManager;

36:      IGmxRewardRouterV2 private immutable glpRewardRouter;

37:      IGmxRewardRouterV2 private immutable gmxRewardRouter;

38:      IGmxVester private immutable glpVester;

39:      IGmxVester private immutable gmxVester;

40:      IGmxRewardTracker private immutable stakedGlpTracker;

41:      IGmxRewardTracker private immutable stakedGmxTracker;

43       IUniswapV3Pool private constant gmxWethPool =
44:          IUniswapV3Pool(0x80A9ae39310abf666A87C743d6ebBD0E8C42158E);

45:      uint160 internal constant UNI_MIN_SQRT_RATIO = 4295128739;

46       uint160 internal constant UNI_MAX_SQRT_RATIO =
47:          1461446703485210103287273052203988822378723970342;

49:      uint256 internal constant FEE_BPS = 100;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L30-L30

[N‑07] Large numeric literals should use underscores for readability

There are 15 instances of this issue:

File: contracts/markets/Market.sol

77:      uint256 public liquidationMultiplier = 12000; //12%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L77-L77

File: contracts/markets/bigBang/BigBang.sol

148:         callerFee = 90000; // 90%

149:         protocolFee = 10000; // 10%

150:         collateralizationRate = 75000; // 75%

168:         liquidationMultiplier = 12000; //12%

521:         _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L148-L148

File: contracts/markets/singularity/SGLStorage.sol

55:      uint256 public lqCollateralizationRate = 25000; // 25%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L55-L55

File: contracts/markets/singularity/Singularity.sol

112:         minimumInterestPerSecond = 951293760; // approx 3% APR

113:         maximumInterestPerSecond = 2536783360; // approx 8% APR

123:         protocolFee = 10000; // 10%

127:         liquidationMultiplier = 12000; //12%

129:         collateralizationRate = 75000;

130:         lqCollateralizationRate = 25000;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L112-L112

File: contracts/tokens/TapOFT.sol

45:      uint256 constant decay_rate = 8800000000000000; // 0.88%

49:      uint256 public constant WEEK = 604800;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L45-L45

[N‑08] Unused contract variables

Note that there may be cases where a variable appears to be used, but this is only because there are multiple definitions of the varible in different files. In such cases, the variable definition should be moved into a separate file. The instances below are the unused variables.

There are 4 instances of this issue:

File: contracts/markets/MarketERC20.sol

45:      bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L45-L45

File: contracts/governance/twTAP.sol

112:     string private baseURI;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L112-L112

File: contracts/Magnetar/MagnetarV2Storage.sol

315:     uint16 internal constant MARKET_MULTIHOP_SELL = 212;

319:     uint16 internal constant TOFT_SEND_APPROVAL = 302;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L315-L315

[N‑09] Use abi.encodeCall() instead of abi.encodeSignature()/abi.encodeSelector()

abi.encodeCall() has compiler type safety, whereas the other two functions do not

There are 58 instances of this issue:

see instances
File: contracts/markets/singularity/Singularity.sol

244:             abi.encodeWithSelector(

262:             abi.encodeWithSelector(

284:             abi.encodeWithSelector(SGLBorrow.borrow.selector, from, to, amount)

304:             abi.encodeWithSelector(

331:             abi.encodeWithSelector(

361:             abi.encodeWithSelector(

391:             abi.encodeWithSelector(

418:             abi.encodeWithSelector(

449:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L244-L244

File: contracts/usd0/BaseUSDO.sol

168:             abi.encodeWithSelector(

196:             abi.encodeWithSelector(

227:             abi.encodeWithSelector(

263:             abi.encodeWithSelector(

293:             abi.encodeWithSelector(

325:             abi.encodeWithSelector(

482:                 abi.encodeWithSelector(

466:                 abi.encodeWithSelector(

454:                 abi.encodeWithSelector(

442:                 abi.encodeWithSelector(

426:                 abi.encodeWithSelector(

410:                 abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L168-L168

File: contracts/usd0/modules/USDOLeverageModule.sol

170:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L170-L170

File: contracts/usd0/modules/USDOMarketModule.sol

169:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L169-L169

File: contracts/usd0/modules/USDOOptionsModule.sol

175:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L175-L175

File: contracts/tOFT/BaseTOFT.sol

109:             abi.encodeWithSelector(

137:             abi.encodeWithSelector(

167:             abi.encodeWithSelector(

202:             abi.encodeWithSelector(

235:             abi.encodeWithSelector(

267:             abi.encodeWithSelector(

302:             abi.encodeWithSelector(

332:             abi.encodeWithSelector(

554:                 abi.encodeWithSelector(

539:                 abi.encodeWithSelector(

527:                 abi.encodeWithSelector(

515:                 abi.encodeWithSelector(

499:                 abi.encodeWithSelector(

483:                 abi.encodeWithSelector(

470:                 abi.encodeWithSelector(

453:                 abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L109-L109

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

185:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L185-L185

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

161:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L161-L161

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

190:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L190-L190

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

153:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L153-L153

File: contracts/Magnetar/MagnetarV2.sol

609:                     abi.encodeWithSelector(

592:                     abi.encodeWithSelector(

571:                     abi.encodeWithSelector(

536:                     abi.encodeWithSelector(

353:                     abi.encodeWithSelector(

746:             abi.encodeWithSelector(

787:             abi.encodeWithSelector(

825:             abi.encodeWithSelector(

867:             abi.encodeWithSelector(

897:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L609-L609

File: contracts/Swapper/BaseSwapper.sol

100:             abi.encodeWithSelector(0x095ea7b3, to, value)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L100-L100

File: contracts/convex/ConvexTricryptoStrategy.sol

357:             abi.encodeWithSelector(

370:             abi.encodeWithSelector(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L357-L357

File: contracts/curve/TricryptoLPStrategy.sol

106:             abi.encodeWithSignature("claimable_tokens(address)", address(this))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L106-L106

[N‑10] Constants in comparisons should appear on the left side

Doing so will prevent typo bugs

There are 92 instances of this issue:

see instances
File: contracts/Penrose.sol

175:             isSingularityMasterContractRegistered[mc] == true,

183:             isBigBangMasterContractRegistered[mc] == true,

322:             isSingularityMasterContractRegistered[mcAddress] == false,

344:             isBigBangMasterContractRegistered[mcAddress] == false,

509:         if (feeShares == 0) return;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L175-L175

File: contracts/markets/Market.sol

314:         if (borrowPart == 0) return (0, 0, 0);

408:         if (borrowPart == 0) return true;

410:         if (collateralShare == 0) return false;

447:         if (borrowed == 0) return 0;

448:         if (startTVLInAsset == 0) return 0;

485:         if (numerator == 0 || denominator == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L314-L314

File: contracts/markets/MarketERC20.sol

140:         if (amount != 0 || msg.sender == to) {

165:         if (amount != 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L140-L140

File: contracts/markets/bigBang/BigBang.sol

182:         if (totalBorrow.elastic == 0) return minDebtRate;

516:         if (elapsedTime == 0) {

550:         if (share == 0) {

751:             totalBorrowCap == 0 || totalBorrow.elastic <= totalBorrowCap,

820:         require(borrowAmount != 0, "SGL: solvent");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L182-L182

File: contracts/markets/singularity/SGLBorrow.sol

26:          if (amount == 0) return (0, 0);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L26-L26

File: contracts/markets/singularity/SGLCommon.sol

61:          utilization = fullAssetAmount == 0

68:          if (elapsedTime == 0) {

81:          if (_totalBorrow.base == 0) {

207:         fraction = allShare == 0

229:         if (totalAsset.base == 0) {

240:         require(_totalAsset.base >= 1000, "SGL: min limit");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L61-L61

File: contracts/markets/singularity/SGLLendingCommon.sol

23:          if (share == 0) {

67:              totalBorrowCap == 0 || totalBorrow.base <= totalBorrowCap,

75:          require(_totalAsset.base >= 1000, "SGL: min limit");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L23-L23

File: contracts/markets/singularity/SGLLiquidation.sol

76:          if (borrowPart == 0) return 0;

115:                 if (borrowAmount == 0) {

152:         require(allBorrowAmount != 0, "SGL: solvent");

264:         require(borrowAmount != 0, "SGL: solvent");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L76-L76

File: contracts/Balancer.sol

118:         if (_slippage >= 1e5) revert SlippageNotValid();

206:             if (msg.value == 0) revert FeeAmountNotSet();

226:         if (!isNative && _ercData.length == 0) revert PoolInfoRequired();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L118-L118

File: contracts/TapiocaWrapper.sol

86:          if (tapiocaOFTs.length == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L86-L86

File: contracts/tOFT/BaseTOFT.sol

85:          if (_decimalCache == 0) return 18; //temporary fix for LZ _sharedDecimals check

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L85-L85

File: contracts/Vesting.sol

111:         if (start == 0 || seeded == 0) revert NotStarted();

113:         if (_claimable == 0) revert NothingToClaim();

133:         if (_amount == 0) revert AmountNotValid();

153:         if (_seededAmount == 0) revert NoTokens();

168:         if (start == 0) return 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L111-L111

File: contracts/governance/twTAP.sol

179:         if (votes == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L179-L179

File: contracts/option-airdrop/AirdropBroker.sol

176:         tapAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;

177:         require(tapAmount >= 1e18, "adb: Too low");

204:         require(cachedEpoch <= 4, "adb: Airdrop ended");

207:         if (cachedEpoch == 1) {

209:         } else if (cachedEpoch == 2) {

211:         } else if (cachedEpoch == 3) {

213:         } else if (cachedEpoch == 4) {

257:         uint256 chosenAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;

258:         require(chosenAmount >= 1e18, "adb: Too low");

331:         if (_phase == 1) {

335:         } else if (_phase == 4) {

426:             userParticipation[msg.sender][subPhase] == false,

450:             userParticipation[tokenIDToAddress][3] == false,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L176-L176

File: contracts/options/TapiocaOptionBroker.sol

189:         tapAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;

190:         require(tapAmount >= 1e18, "tOB: Too low");

390:         uint256 chosenAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;

391:         require(chosenAmount >= 1e18, "tOB: Too low");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L189-L189

File: contracts/options/TapiocaOptionLiquidityProvision.sol

283:             activeSingularities[singularity].sglAssetID == 0,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L283-L283

File: contracts/tokens/TapOFT.sol

176:         if (timestamp == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L176-L176

File: contracts/twAML.sol

32:          if (prod1 == 0) {

120:         return mul >= 1e4 ? mul / 1e4 : _totalWeight;

138:         if (_cumulative == 0) {

155:         } else if (y != 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L32-L32

File: contracts/Magnetar/MagnetarV2.sol

186:         fraction = allShare == 0 ? share : (share * totalAssetBase) / allShare;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L186-L186

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

402:         if (lendAmount == 0 && depositData.deposit) {

454:             if (participateData.tOLPTokenId != 0) {

455:                 if (tOLPTokenId != 0) {

468:             require(tOLPTokenId != 0, "Magnetar: tOLPTokenId 0");

554:             if (removeAndRepayData.unlockData.tokenId != 0) {

555:                 if (tOLPId != 0) {

690:         if (dstChainId == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L402-L402

File: contracts/Swapper/BaseSwapper.sol

103:             success && (data.length == 0 || abi.decode(data, (bool))),

132:                 amountIn = amounts.amountIn == 0

137:                 amountOut = amounts.amountOut == 0

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L103-L103

File: contracts/Swapper/UniswapV2Swapper.sol

147:         if (data.length == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L147-L147

File: contracts/Swapper/UniswapV3Swapper.sol

175:         if (data.length == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L175-L175

File: contracts/TapiocaDeployer/TapiocaDeployer.sol

33:              bytecode.length != 0,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L33-L33

File: contracts/convex/ConvexTricryptoStrategy.sol

190:         if (data.length == 0) return;

312:         if (calcAmount >= 1e18) {

377:             success && (data.length == 0 || abi.decode(data, (bool))),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L190-L190

File: contracts/glp/GlpStrategy.sol

186:         if (available == 0) {

194:         if (vestable == 0) {

265:         if (vestable == 0) {

294:         if (vestable == 0) {

318:         if (gmxAmount == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L186-L186

File: contracts/YieldBox.sol

131:         if (share == 0) {

280:         if (share == 0) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L131-L131

[N‑11] Consider disabling renounceOwnership()

If the plan for your project does not include eventually giving up all ownership control, consider overwriting OpenZeppelin's Ownable's renounceOwnership() function in order to disable it.

There are 24 instances of this issue:

see instances
File: contracts/Penrose.sol

32:  contract Penrose is BoringOwnable, BoringFactory {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L32-L32

File: contracts/markets/Market.sol

14:  abstract contract Market is MarketERC20, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L14-L14

File: contracts/markets/bigBang/BigBang.sol

39:  contract BigBang is BoringOwnable, Market {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L39-L39

File: contracts/markets/singularity/SGLStorage.sol

34:  contract SGLStorage is BoringOwnable, Market {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L34-L34

File: contracts/TapiocaWrapper.sol

26:  contract TapiocaWrapper is Ownable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L26-L26

File: contracts/Vesting.sol

10:  contract Vesting is BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L10-L10

File: contracts/option-airdrop/AirdropBroker.sol

43:  contract AirdropBroker is Pausable, BoringOwnable, FullMath {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L43-L43

File: contracts/option-airdrop/aoTAP.sol

32:  contract AOTAP is ERC721, ERC721Permit, BaseBoringBatchable, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L32-L32

File: contracts/options/TapiocaOptionBroker.sol

53:  contract TapiocaOptionBroker is Pausable, BoringOwnable, TWAML {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L53-L53

File: contracts/options/TapiocaOptionLiquidityProvision.sol

53:      BoringOwnable

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L53-L53

File: contracts/tokens/LTap.sol

23:  contract LTap is BoringOwnable, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L23-L23

File: contracts/Magnetar/MagnetarV2.sol

30:  contract MagnetarV2 is Ownable, MagnetarV2Storage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L30-L30

File: contracts/Multicall/Multicall3.sol

22:  contract Multicall3 is Ownable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L22-L22

File: contracts/Swapper/BaseSwapper.sol

11:  abstract contract BaseSwapper is Ownable, ReentrancyGuard, ISwapper {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L11-L11

File: contracts/aave/AaveStrategy.sol

29:  contract AaveStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L29-L29

File: contracts/balancer/BalancerStrategy.sol

28:  contract BalancerStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L28-L28

File: contracts/compound/CompoundStrategy.sol

28:  contract CompoundStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L28-L28

File: contracts/convex/ConvexTricryptoStrategy.sol

33:      BoringOwnable,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L33-L33

File: contracts/curve/TricryptoLPStrategy.sol

32:      BoringOwnable,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L32-L32

File: contracts/curve/TricryptoNativeStrategy.sol

32:      BoringOwnable,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L32-L32

File: contracts/glp/GlpStrategy.sol

23:  contract GlpStrategy is BaseERC20Strategy, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L23-L23

File: contracts/lido/LidoEthStrategy.sol

30:  contract LidoEthStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L30-L30

File: contracts/stargate/StargateStrategy.sol

35:  contract StargateStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L35-L35

File: contracts/yearn/YearnStrategy.sol

30:  contract YearnStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L30-L30

[N‑12] Consider adding emergency-stop functionality

Adding a way to quickly halt protocol functionality in an emergency, rather than having to pause individual contracts one-by-one, will make in-progress hack mitigation faster and much less stressful.

There are 18 instances of this issue:

see instances
File: contracts/Penrose.sol

32   contract Penrose is BoringOwnable, BoringFactory {
33       // ************ //
34       // *** VARS *** //
35       // ************ //
36       /// @notice returns the Conservator address
37       address public conservator;
38       /// @notice returns the pause state of the contract
39       bool public paused;
40       /// @notice returns the YieldBox contract
41       YieldBox public immutable yieldBox;
42       /// @notice returns the TAP contract
43       IERC20 public immutable tapToken;
44       /// @notice returns TAP asset id registered in the YieldBox contract
45       uint256 public immutable tapAssetId;
46       /// @notice returns USDO contract
47       IERC20 public usdoToken;
48       /// @notice returns USDO asset id registered in the YieldBox contract
49       uint256 public usdoAssetId;
50       /// @notice returns the WETH contract
51       IERC20 public immutable wethToken;
52       /// @notice returns WETH asset id registered in the YieldBox contract
53       uint256 public immutable wethAssetId;
54   
55       /// @notice Singularity master contracts
56       IPenrose.MasterContract[] public singularityMasterContracts;
57       /// @notice BigBang master contracts
58       IPenrose.MasterContract[] public bigbangMasterContracts;
59   
60       // Used to check if a Singularity master contract is registered
61       mapping(address => bool) public isSingularityMasterContractRegistered;
62       // Used to check if a BigBang master contract is registered
63       mapping(address => bool) public isBigBangMasterContractRegistered;
64       // Used to check if a SGL/BB is a real market
65       mapping(address => bool) public isMarketRegistered;
66   
67       /// @notice protocol fees
68       address public feeTo;
69   
70       /// @notice whitelisted swappers
71       mapping(ISwapper => bool) public swappers;
72   
73       /// @notice BigBang ETH market address
74       address public bigBangEthMarket;
75       /// @notice BigBang ETH market debt rate
76       uint256 public bigBangEthDebtRate;
77   
78       /// @notice registered empty strategies
79       mapping(address => IStrategy) public emptyStrategies;
80   
81       /// @notice creates a Penrose contract
82       /// @param _yieldBox YieldBox contract address
83       /// @param tapToken_ TapOFT contract address
84       /// @param wethToken_ WETH contract address
85       /// @param _owner owner address
86       constructor(
87           YieldBox _yieldBox,
88           IERC20 tapToken_,
89           IERC20 wethToken_,
90           address _owner
91       ) {
92           yieldBox = _yieldBox;
93           tapToken = tapToken_;
94           owner = _owner;
95   
96           emptyStrategies[address(tapToken_)] = IStrategy(
97               address(
98                   new ERC20WithoutStrategy(
99                       IYieldBox(address(_yieldBox)),
100                      tapToken_
101                  )
102              )
103          );
104          tapAssetId = uint96(
105              _yieldBox.registerAsset(
106                  TokenType.ERC20,
107                  address(tapToken_),
108                  emptyStrategies[address(tapToken_)],
109                  0
110              )
111          );
112  
113          wethToken = wethToken_;
114          emptyStrategies[address(wethToken_)] = IStrategy(
115              address(
116                  new ERC20WithoutStrategy(
117                      IYieldBox(address(_yieldBox)),
118                      wethToken_
119                  )
120              )
121          );
122          wethAssetId = uint96(
123              _yieldBox.registerAsset(
124                  TokenType.ERC20,
125                  address(wethToken_),
126                  emptyStrategies[address(wethToken_)],
127                  0
128              )
129          );
130  
131          bigBangEthDebtRate = 5e15;
132      }
133  
134      // **************//
135      // *** EVENTS *** //
136      // ************** //
137      /// @notice event emitted when fees are extracted
138      event ProtocolWithdrawal(IMarket[] markets, uint256 timestamp);
139      /// @notice event emitted when Singularity master contract is registered
140      event RegisterSingularityMasterContract(
141          address location,
142          IPenrose.ContractType risk
143      );
144      /// @notice event emitted when BigBang master contract is registered
145      event RegisterBigBangMasterContract(
146          address location,
147          IPenrose.ContractType risk
148      );
149      /// @notice event emitted when Singularity is registered
150      event RegisterSingularity(address location, address masterContract);
151      /// @notice event emitted when BigBang is registered
152      event RegisterBigBang(address location, address masterContract);
153      /// @notice event emitted when feeTo address is updated
154      event FeeToUpdate(address newFeeTo);
155      /// @notice event emitted when ISwapper address is updated
156      event SwapperUpdate(address swapper, bool isRegistered);
157      /// @notice event emitted when USDO address is updated
158      event UsdoTokenUpdated(address indexed usdoToken, uint256 assetId);
159      /// @notice event emitted when conservator is updated
160      event ConservatorUpdated(address indexed old, address indexed _new);
161      /// @notice event emitted when pause state is updated
162      event PausedUpdated(bool oldState, bool newState);
163      /// @notice event emitted when BigBang ETH market address is updated
164      event BigBangEthMarketSet(address indexed _newAddress);
165      /// @notice event emitted when BigBang ETH market debt rate is updated
166      event BigBangEthMarketDebtRate(uint256 _rate);
167      /// @notice event emitted when fees are deposited to YieldBox
168      event LogYieldBoxFeesDeposit(uint256 feeShares, uint256 ethAmount);
169  
170      // ******************//
171      // *** MODIFIERS *** //
172      // ***************** //
173      modifier registeredSingularityMasterContract(address mc) {
174          require(
175              isSingularityMasterContractRegistered[mc] == true,
176              "Penrose: MC not registered"
177          );
178          _;
179      }
180  
181      modifier registeredBigBangMasterContract(address mc) {
182          require(
183              isBigBangMasterContractRegistered[mc] == true,
184              "Penrose: MC not registered"
185          );
186          _;
187      }
188  
189      modifier notPaused() {
190          require(!paused, "Penrose: paused");
191          _;
192      }
193  
194      // ********************** //
195      // *** VIEW FUNCTIONS *** //
196      // ********************** //
197      /// @notice Get all the Singularity contract addresses
198      /// @return markets list of available markets
199      function singularityMarkets()
200          public
201          view
202          returns (address[] memory markets)
203      {
204          markets = _getMasterContractLength(singularityMasterContracts);
205      }
206  
207      /// @notice Get all the BigBang contract addresses
208      /// @return markets list of available markets
209      function bigBangMarkets() public view returns (address[] memory markets) {
210          markets = _getMasterContractLength(bigbangMasterContracts);
211      }
212  
213      /// @notice Get the length of `singularityMasterContracts`
214      function singularityMasterContractLength() public view returns (uint256) {
215          return singularityMasterContracts.length;
216      }
217  
218      /// @notice Get the length of `bigbangMasterContracts`
219      function bigBangMasterContractLength() public view returns (uint256) {
220          return bigbangMasterContracts.length;
221      }
222  
223      // ************************ //
224      // *** PUBLIC FUNCTIONS *** //
225      // ************************ //
226      /// @notice Loop through the master contracts and call `_depositFeesToYieldBox()` to each one of their clones.
227      /// @dev `swappers_` can have one element that'll be used for all clones. Or one swapper per MasterContract.
228      /// @dev Fees are withdrawn in TAP and sent to the FeeDistributor contract
229      /// @param markets_ Singularity &/ BigBang markets array
230      /// @param swappers_ one or more swappers to convert the asset to TAP.
231      /// @param swapData_ swap data for each swapper
232      function withdrawAllMarketFees(
233          IMarket[] calldata markets_,
234          ISwapper[] calldata swappers_,
235          IPenrose.SwapData[] calldata swapData_
236      ) public notPaused {
237          require(
238              markets_.length == swappers_.length &&
239                  swappers_.length == swapData_.length,
240              "Penrose: length mismatch"
241          );
242          require(address(swappers_[0]) != address(0), "Penrose: zero address");
243          require(address(markets_[0]) != address(0), "Penrose: zero address");
244  
245          _withdrawAllProtocolFees(swappers_, swapData_, markets_);
246  
247          emit ProtocolWithdrawal(markets_, block.timestamp);
248      }
249  
250      // *********************** //
251      // *** OWNER FUNCTIONS *** //
252      // *********************** //
253      /// @notice sets the main BigBang market debt rate
254      /// @dev can only be called by the owner
255      /// @param _rate the new rate
256      function setBigBangEthMarketDebtRate(uint256 _rate) external onlyOwner {
257          bigBangEthDebtRate = _rate;
258          emit BigBangEthMarketDebtRate(_rate);
259      }
260  
261      /// @notice sets the main BigBang market
262      /// @dev needed for the variable debt computation
263      function setBigBangEthMarket(address _market) external onlyOwner {
264          bigBangEthMarket = _market;
265          emit BigBangEthMarketSet(_market);
266      }
267  
268      /// @notice updates the pause state of the contract
269      /// @dev can only be called by the conservator
270      /// @param val the new value
271      function updatePause(bool val) external {
272          require(msg.sender == conservator, "Penrose: unauthorized");
273          require(val != paused, "Penrose: same state");
274          emit PausedUpdated(paused, val);
275          paused = val;
276      }
277  
278      /// @notice Set the Conservator address
279      /// @dev Conservator can pause the contract
280      /// @param _conservator The new address
281      function setConservator(address _conservator) external onlyOwner {
282          require(_conservator != address(0), "Penrose: address not valid");
283          emit ConservatorUpdated(conservator, _conservator);
284          conservator = _conservator;
285      }
286  
287      /// @notice Set the USDO token
288      /// @dev sets usdoToken and usdoAssetId
289      ///      can only by called by the owner
290      /// @param _usdoToken the USDO token address
291      function setUsdoToken(address _usdoToken) external onlyOwner {
292          usdoToken = IERC20(_usdoToken);
293  
294          emptyStrategies[_usdoToken] = IStrategy(
295              address(
296                  new ERC20WithoutStrategy(
297                      IYieldBox(address(yieldBox)),
298                      IERC20(_usdoToken)
299                  )
300              )
301          );
302          usdoAssetId = uint96(
303              yieldBox.registerAsset(
304                  TokenType.ERC20,
305                  _usdoToken,
306                  emptyStrategies[_usdoToken],
307                  0
308              )
309          );
310          emit UsdoTokenUpdated(_usdoToken, usdoAssetId);
311      }
312  
313      /// @notice Register a Singularity master contract
314      /// @dev can only be called by the owner
315      /// @param mcAddress The address of the contract
316      /// @param contractType_ The risk type of the contract
317      function registerSingularityMasterContract(
318          address mcAddress,
319          IPenrose.ContractType contractType_
320      ) external onlyOwner {
321          require(
322              isSingularityMasterContractRegistered[mcAddress] == false,
323              "Penrose: MC registered"
324          );
325  
326          IPenrose.MasterContract memory mc;
327          mc.location = mcAddress;
328          mc.risk = contractType_;
329          singularityMasterContracts.push(mc);
330          isSingularityMasterContractRegistered[mcAddress] = true;
331  
332          emit RegisterSingularityMasterContract(mcAddress, contractType_);
333      }
334  
335      /// @notice Register a BigBang master contract
336      /// @dev can only be called by the owner
337      /// @param mcAddress The address of the contract
338      /// @param contractType_ The risk type of the contract
339      function registerBigBangMasterContract(
340          address mcAddress,
341          IPenrose.ContractType contractType_
342      ) external onlyOwner {
343          require(
344              isBigBangMasterContractRegistered[mcAddress] == false,
345              "Penrose: MC registered"
346          );
347  
348          IPenrose.MasterContract memory mc;
349          mc.location = mcAddress;
350          mc.risk = contractType_;
351          bigbangMasterContracts.push(mc);
352          isBigBangMasterContractRegistered[mcAddress] = true;
353  
354          emit RegisterBigBangMasterContract(mcAddress, contractType_);
355      }
356  
357      /// @notice Registers a Singularity market
358      /// @dev can only be called by the owner
359      /// @param mc The address of the master contract which must be already registered
360      /// @param data The init data of the Singularity
361      /// @param useCreate2 Whether to use create2 or not
362      function registerSingularity(
363          address mc,
364          bytes calldata data,
365          bool useCreate2
366      )
367          external
368          payable
369          onlyOwner
370          registeredSingularityMasterContract(mc)
371          returns (address _contract)
372      {
373          _contract = deploy(mc, data, useCreate2);
374          isMarketRegistered[_contract] = true;
375          emit RegisterSingularity(_contract, mc);
376      }
377  
378      /// @notice Registers an existing Singularity market (without deployment)
379      /// @dev can only be called by the owner
380      /// @param mc The address of the master contract which must be already registered
381      function addSingularity(
382          address mc,
383          address _contract
384      ) external onlyOwner registeredSingularityMasterContract(mc) {
385          isMarketRegistered[_contract] = true;
386          clonesOf[mc].push(_contract);
387          emit RegisterSingularity(_contract, mc);
388      }
389  
390      /// @notice Registers a BigBang market
391      /// @dev can only be called by the owner
392      /// @param mc The address of the master contract which must be already registered
393      /// @param data The init data of the BigBang contract
394      /// @param useCreate2 Whether to use create2 or not
395      function registerBigBang(
396          address mc,
397          bytes calldata data,
398          bool useCreate2
399      )
400          external
401          payable
402          onlyOwner
403          registeredBigBangMasterContract(mc)
404          returns (address _contract)
405      {
406          _contract = deploy(mc, data, useCreate2);
407          isMarketRegistered[_contract] = true;
408          emit RegisterBigBang(_contract, mc);
409      }
410  
411      /// @notice Registers an existing BigBang market (without deployment)
412      /// @dev can only be called by the owner
413      /// @param mc The address of the master contract which must be already registered
414      function addBigBang(
415          address mc,
416          address _contract
417      ) external onlyOwner registeredBigBangMasterContract(mc) {
418          isMarketRegistered[_contract] = true;
419          clonesOf[mc].push(_contract);
420          emit RegisterBigBang(_contract, mc);
421      }
422  
423      /// @notice Execute an only owner function inside of a Singularity or a BigBang market
424      function executeMarketFn(
425          address[] calldata mc,
426          bytes[] memory data,
427          bool forceSuccess
428      )
429          external
430          onlyOwner
431          notPaused
432          returns (bool[] memory success, bytes[] memory result)
433      {
434          uint256 len = mc.length;
435          success = new bool[](len);
436          result = new bytes[](len);
437          for (uint256 i = 0; i < len; ) {
438              require(
439                  isSingularityMasterContractRegistered[
440                      masterContractOf[mc[i]]
441                  ] || isBigBangMasterContractRegistered[masterContractOf[mc[i]]],
442                  "Penrose: MC not registered"
443              );
444              (success[i], result[i]) = mc[i].call(data[i]);
445              if (forceSuccess) {
446                  require(success[i], _getRevertMsg(result[i]));
447              }
448              ++i;
449          }
450      }
451  
452      /// @notice Set protocol fees address
453      /// @dev can only be called by the owner
454      /// @param feeTo_ the new feeTo address
455      function setFeeTo(address feeTo_) external onlyOwner {
456          feeTo = feeTo_;
457          emit FeeToUpdate(feeTo_);
458      }
459  
460      /// @notice Used to register and enable or disable swapper contracts used in closed liquidations.
461      /// @dev can only be called by the owner
462      /// @param swapper The address of the swapper contract that conforms to `ISwapper`.
463      /// @param enable True to enable the swapper. To disable use False.
464      function setSwapper(ISwapper swapper, bool enable) external onlyOwner {
465          swappers[swapper] = enable;
466          emit SwapperUpdate(address(swapper), enable);
467      }
468  
469      // ************************* //
470      // *** PRIVATE FUNCTIONS *** //
471      // ************************* //
472      function _getRevertMsg(
473          bytes memory _returnData
474      ) private pure returns (string memory) {
475          // If the _res length is less than 68, then the transaction failed silently (without a revert message)
476          if (_returnData.length < 68) return "SGL: no return data";
477          // solhint-disable-next-line no-inline-assembly
478          assembly {
479              // Slice the sighash.
480              _returnData := add(_returnData, 0x04)
481          }
482          return abi.decode(_returnData, (string)); // All that remains is the revert string
483      }
484  
485      function _withdrawAllProtocolFees(
486          ISwapper[] calldata swappers_,
487          IPenrose.SwapData[] calldata swapData_,
488          IMarket[] memory markets_
489      ) private {
490          uint256 length = markets_.length;
491          unchecked {
492              for (uint256 i = 0; i < length; ) {
493                  _depositFeesToYieldBox(markets_[i], swappers_[i], swapData_[i]);
494                  ++i;
495              }
496          }
497      }
498  
499      /// @notice Withdraw the balance of `feeTo`, swap asset into TAP and deposit it to yieldBox of `feeTo`
500      function _depositFeesToYieldBox(
501          IMarket market,
502          ISwapper swapper,
503          IPenrose.SwapData calldata dexData
504      ) private {
505          require(swappers[swapper], "Penrose: Invalid swapper");
506          require(isMarketRegistered[address(market)], "Penrose: Invalid market");
507  
508          uint256 feeShares = market.refreshPenroseFees(feeTo);
509          if (feeShares == 0) return;
510  
511          uint256 assetId = market.assetId();
512          uint256 amount = 0;
513          if (assetId != wethAssetId) {
514              yieldBox.transfer(
515                  address(this),
516                  address(swapper),
517                  assetId,
518                  feeShares
519              );
520  
521              ISwapper.SwapData memory swapData = swapper.buildSwapData(
522                  assetId,
523                  wethAssetId,
524                  0,
525                  feeShares,
526                  true,
527                  true
528              );
529              (amount, ) = swapper.swap(
530                  swapData,
531                  dexData.minAssetAmount,
532                  feeTo,
533                  ""
534              );
535          } else {
536              yieldBox.transfer(address(this), feeTo, assetId, feeShares);
537          }
538  
539          emit LogYieldBoxFeesDeposit(feeShares, amount);
540      }
541  
542      function _getMasterContractLength(
543          IPenrose.MasterContract[] memory array
544      ) public view returns (address[] memory markets) {
545          uint256 _masterContractLength = array.length;
546          uint256 marketsLength = 0;
547  
548          unchecked {
549              // We first compute the length of the markets array
550              for (uint256 i = 0; i < _masterContractLength; ) {
551                  marketsLength += clonesOfCount(array[i].location);
552  
553                  ++i;
554              }
555          }
556  
557          markets = new address[](marketsLength);
558  
559          uint256 marketIndex;
560          uint256 clonesOfLength;
561  
562          unchecked {
563              // We populate the array
564              for (uint256 i = 0; i < _masterContractLength; ) {
565                  address mcLocation = array[i].location;
566                  clonesOfLength = clonesOfCount(mcLocation);
567  
568                  // Loop through clones of the current MC.
569                  for (uint256 j = 0; j < clonesOfLength; ) {
570                      markets[marketIndex] = clonesOf[mcLocation][j];
571                      ++marketIndex;
572                      ++j;
573                  }
574                  ++i;
575              }
576          }
577      }
578: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L32-L578

File: contracts/markets/Market.sol

14   abstract contract Market is MarketERC20, BoringOwnable {
15       using RebaseLibrary for Rebase;
16   
17       // ************ //
18       // *** VARS *** //
19       // ************ //
20       /// @notice returns YieldBox address
21       YieldBox public yieldBox;
22       /// @notice returns Penrose address
23       IPenrose public penrose;
24   
25       /// @notice collateral token address
26       IERC20 public collateral;
27       /// @notice collateral token YieldBox id
28       uint256 public collateralId;
29       /// @notice asset token address
30       IERC20 public asset;
31       /// @notice asset token YieldBox id
32       uint256 public assetId;
33   
34       /// @notice contract's pause state
35       bool public paused;
36       /// @notice conservator's addresss
37       /// @dev conservator can pause/unpause the contract
38       address public conservator;
39   
40       /// @notice oracle address
41       IOracle public oracle;
42       /// @notice oracleData
43       bytes public oracleData;
44       /// @notice Exchange and interest rate tracking.
45       /// This is 'cached' here because calls to Oracles can be very expensive.
46       /// Asset -> collateral = assetAmount * exchangeRate.
47       uint256 public exchangeRate;
48   
49       /// @notice total amount borrowed
50       /// @dev elastic = Total token amount to be repayed by borrowers, base = Total parts of the debt held by borrowers
51       Rebase public totalBorrow;
52       /// @notice total collateral supplied
53       uint256 public totalCollateralShare;
54       /// @notice max borrow cap
55       uint256 public totalBorrowCap;
56       /// @notice borrow amount per user
57       mapping(address => uint256) public userBorrowPart;
58       /// @notice collateral share per user
59       mapping(address => uint256) public userCollateralShare;
60   
61       /// @notice liquidation caller rewards
62       uint256 public callerFee; // 90%
63       /// @notice liquidation protocol rewards
64       uint256 public protocolFee; // 10%
65       /// @notice min % a liquidator can receive in rewards
66       uint256 public minLiquidatorReward = 1e3; //1%
67       /// @notice max % a liquidator can receive in rewards
68       uint256 public maxLiquidatorReward = 1e4; //10%
69       /// @notice max liquidatable bonus amount
70       /// @dev max % added to the amount that can be liquidated
71       uint256 public liquidationBonusAmount = 1e4; //10%
72       /// @notice collateralization rate
73       uint256 public collateralizationRate; // 75%
74       /// @notice borrowing opening fee
75       uint256 public borrowOpeningFee = 50; //0.05%
76       /// @notice liquidation multiplier used to compute liquidator rewards
77       uint256 public liquidationMultiplier = 12000; //12%
78   
79       // ***************** //
80       // *** CONSTANTS *** //
81       // ***************** //
82       uint256 internal EXCHANGE_RATE_PRECISION; //not costant, but can only be set in the 'init' method
83       uint256 internal constant FEE_PRECISION = 1e5;
84       uint256 internal constant FEE_PRECISION_DECIMALS = 5;
85   
86       // ************** //
87       // *** EVENTS *** //
88       // ************** //
89       /// @notice event emitted when conservator is updated
90       event ConservatorUpdated(address indexed old, address indexed _new);
91       /// @notice event emitted when pause state is changed
92       event PausedUpdated(bool oldState, bool newState);
93       /// @notice event emitted when cached exchange rate is updated
94       event LogExchangeRate(uint256 rate);
95       /// @notice event emitted when borrow cap is updated
96       event LogBorrowCapUpdated(uint256 _oldVal, uint256 _newVal);
97       /// @notice event emitted when oracle data is updated
98       event OracleDataUpdated();
99       /// @notice event emitted when oracle is updated
100      event OracleUpdated();
101      /// @notice event emitted when a position is liquidated
102      event Liquidated(
103          address liquidator,
104          address[] users,
105          uint256 liquidatorReward,
106          uint256 protocolReward,
107          uint256 repayedAmount,
108          uint256 collateralShareRemoved
109      );
110      /// @notice event emitted when borrow opening fee is updated
111      event LogBorrowingFee(uint256 _oldVal, uint256 _newVal);
112      /// @notice event emitted when the liquidation multiplier rate is updated
113      event LiquidationMultiplierUpdated(uint256 oldVal, uint256 newVal);
114  
115      modifier notPaused() {
116          require(!paused, "Market: paused");
117          _;
118      }
119      /// @dev Checks if the user is solvent in the closed liquidation case at the end of the function body.
120      modifier solvent(address from) {
121          updateExchangeRate();
122          _accrue();
123  
124          _;
125  
126          require(_isSolvent(from, exchangeRate), "Market: insolvent");
127      }
128  
129      bool internal initialized;
130      modifier onlyOnce() {
131          require(!initialized, "Market: initialized");
132          _;
133          initialized = true;
134      }
135  
136      // *********************** //
137      // *** OWNER FUNCTIONS *** //
138      // *********************** //
139      /// @notice sets the borrowing opening fee
140      /// @dev can only be called by the owner
141      /// @param _val the new value
142      function setBorrowOpeningFee(uint256 _val) external onlyOwner {
143          require(_val <= FEE_PRECISION, "Market: not valid");
144          emit LogBorrowingFee(borrowOpeningFee, _val);
145          borrowOpeningFee = _val;
146      }
147  
148      /// @notice sets max borrowable amount
149      /// @dev can only be called by the owner
150      /// @param _cap the new value
151      function setBorrowCap(uint256 _cap) external notPaused onlyOwner {
152          emit LogBorrowCapUpdated(totalBorrowCap, _cap);
153          totalBorrowCap = _cap;
154      }
155  
156      /// @notice sets common market configuration
157      /// @dev values are updated only if > 0 or not address(0)
158      function setMarketConfig(
159          uint256 _borrowOpeningFee,
160          IOracle _oracle,
161          bytes calldata _oracleData,
162          address _conservator,
163          uint256 _callerFee,
164          uint256 _protocolFee,
165          uint256 _liquidationBonusAmount,
166          uint256 _minLiquidatorReward,
167          uint256 _maxLiquidatorReward,
168          uint256 _totalBorrowCap,
169          uint256 _collateralizationRate
170      ) external onlyOwner {
171          if (_borrowOpeningFee > 0) {
172              require(_borrowOpeningFee <= FEE_PRECISION, "Market: not valid");
173              emit LogBorrowingFee(borrowOpeningFee, _borrowOpeningFee);
174              borrowOpeningFee = _borrowOpeningFee;
175          }
176  
177          if (address(_oracle) != address(0)) {
178              oracle = _oracle;
179              emit OracleUpdated();
180          }
181  
182          if (_oracleData.length > 0) {
183              oracleData = _oracleData;
184              emit OracleDataUpdated();
185          }
186  
187          if (_conservator != address(0)) {
188              emit ConservatorUpdated(conservator, _conservator);
189              conservator = _conservator;
190          }
191  
192          if (_callerFee > 0) {
193              require(_callerFee <= FEE_PRECISION, "Market: not valid");
194              callerFee = _callerFee;
195          }
196  
197          if (_protocolFee > 0) {
198              require(_protocolFee <= FEE_PRECISION, "Market: not valid");
199              protocolFee = _protocolFee;
200          }
201  
202          if (_liquidationBonusAmount > 0) {
203              require(
204                  _liquidationBonusAmount < FEE_PRECISION,
205                  "Market: not valid"
206              );
207              liquidationBonusAmount = _liquidationBonusAmount;
208          }
209  
210          if (_minLiquidatorReward > 0) {
211              require(_minLiquidatorReward < FEE_PRECISION, "Market: not valid");
212              require(
213                  _minLiquidatorReward < maxLiquidatorReward,
214                  "Market: not valid"
215              );
216              minLiquidatorReward = _minLiquidatorReward;
217          }
218  
219          if (_maxLiquidatorReward > 0) {
220              require(_maxLiquidatorReward < FEE_PRECISION, "Market: not valid");
221              require(
222                  _maxLiquidatorReward > minLiquidatorReward,
223                  "Market: not valid"
224              );
225              maxLiquidatorReward = _maxLiquidatorReward;
226          }
227  
228          if (_totalBorrowCap > 0) {
229              emit LogBorrowCapUpdated(totalBorrowCap, _totalBorrowCap);
230              totalBorrowCap = _totalBorrowCap;
231          }
232  
233          if (_collateralizationRate > 0) {
234              require(
235                  _collateralizationRate <= FEE_PRECISION,
236                  "Market: not valid"
237              );
238              collateralizationRate = _collateralizationRate;
239          }
240      }
241  
242      /// @notice updates the pause state of the contract
243      /// @dev can only be called by the conservator
244      /// @param val the new value
245      function updatePause(bool val) external {
246          require(msg.sender == conservator, "Market: unauthorized");
247          require(val != paused, "Market: same state");
248          emit PausedUpdated(paused, val);
249          paused = val;
250      }
251  
252      // ********************** //
253      // *** VIEW FUNCTIONS *** //
254      // ********************** //
255      /// @notice returns the maximum liquidatable amount for user
256      function computeClosingFactor(
257          uint256 borrowPart,
258          uint256 collateralPartInAsset,
259          uint256 borrowPartDecimals,
260          uint256 collateralPartDecimals,
261          uint256 ratesPrecision
262      ) public view returns (uint256) {
263          uint256 borrowPartScaled = borrowPart;
264          if (borrowPartDecimals > 18) {
265              borrowPartScaled = borrowPart / (10 ** (borrowPartDecimals - 18));
266          }
267          if (borrowPartDecimals < 18) {
268              borrowPartScaled = borrowPart * (10 ** (18 - borrowPartDecimals));
269          }
270  
271          uint256 collateralPartInAssetScaled = collateralPartInAsset;
272          if (collateralPartDecimals > 18) {
273              collateralPartInAssetScaled =
274                  collateralPartInAsset /
275                  (10 ** (collateralPartDecimals - 18));
276          }
277          if (collateralPartDecimals < 18) {
278              collateralPartInAssetScaled =
279                  collateralPartInAsset *
280                  (10 ** (18 - collateralPartDecimals));
281          }
282  
283          uint256 liquidationStartsAt = (collateralPartInAssetScaled *
284              collateralizationRate) / (10 ** ratesPrecision);
285          if (borrowPartScaled < liquidationStartsAt) return 0;
286  
287          uint256 numerator = borrowPartScaled -
288              ((collateralizationRate * collateralPartInAssetScaled) /
289                  (10 ** ratesPrecision));
290          uint256 denominator = ((10 ** ratesPrecision) -
291              (collateralizationRate *
292                  ((10 ** ratesPrecision) + liquidationMultiplier)) /
293              (10 ** ratesPrecision)) * (10 ** (18 - ratesPrecision));
294  
295          uint256 x = (numerator * 1e18) / denominator;
296          return x;
297      }
298  
299      /// @notice return the amount of collateral for a `user` to be solvent, min TVL and max TVL. Returns 0 if user already solvent.
300      /// @dev we use a `CLOSED_COLLATERIZATION_RATE` that is a safety buffer when making the user solvent again,
301      ///      to prevent from being liquidated. This function is valid only if user is not solvent by `_isSolvent()`.
302      /// @param user The user to check solvency.
303      /// @param _exchangeRate the exchange rate asset/collateral.
304      /// @return amountToSolvency the amount of collateral to be solvent.
305      function computeTVLInfo(
306          address user,
307          uint256 _exchangeRate
308      )
309          public
310          view
311          returns (uint256 amountToSolvency, uint256 minTVL, uint256 maxTVL)
312      {
313          uint256 borrowPart = userBorrowPart[user];
314          if (borrowPart == 0) return (0, 0, 0);
315  
316          Rebase memory _totalBorrow = totalBorrow;
317  
318          uint256 collateralAmountInAsset = _computeMaxBorrowableAmount(
319              user,
320              _exchangeRate
321          );
322  
323          borrowPart = (borrowPart * _totalBorrow.elastic) / _totalBorrow.base;
324  
325          amountToSolvency = borrowPart >= collateralAmountInAsset
326              ? borrowPart - collateralAmountInAsset
327              : 0;
328  
329          (minTVL, maxTVL) = _computeMaxAndMinLTVInAsset(
330              userCollateralShare[user],
331              _exchangeRate
332          );
333      }
334  
335      /// @notice Gets the exchange rate. I.e how much collateral to buy 1e18 asset.
336      /// @dev This function is supposed to be invoked if needed because Oracle queries can be expensive.
337      ///      Oracle should consider USDO at 1$
338      /// @return updated True if `exchangeRate` was updated.
339      /// @return rate The new exchange rate.
340      function updateExchangeRate() public returns (bool updated, uint256 rate) {
341          (updated, rate) = oracle.get("");
342  
343          if (updated) {
344              require(rate > 0, "Market: invalid rate");
345              exchangeRate = rate;
346              emit LogExchangeRate(rate);
347          } else {
348              // Return the old rate if fetching wasn't successful
349              rate = exchangeRate;
350          }
351      }
352  
353      /// @notice computes the possible liquidator reward
354      /// @notice user the user for which a liquidation operation should be performed
355      /// @param _exchangeRate the exchange rate asset/collateral to use for internal computations
356      function computeLiquidatorReward(
357          address user,
358          uint256 _exchangeRate
359      ) public view returns (uint256) {
360          (uint256 minTVL, uint256 maxTVL) = _computeMaxAndMinLTVInAsset(
361              userCollateralShare[user],
362              _exchangeRate
363          );
364          return _getCallerReward(userBorrowPart[user], minTVL, maxTVL);
365      }
366  
367      // ************************** //
368      // *** INTERNAL FUNCTIONS *** //
369      // ************************** //
370      function _accrue() internal virtual;
371  
372      function _getRevertMsg(
373          bytes memory _returnData
374      ) internal pure returns (string memory) {
375          // If the _res length is less than 68, then the transaction failed silently (without a revert message)
376          if (_returnData.length < 68) return "Market: no return data";
377          // solhint-disable-next-line no-inline-assembly
378          assembly {
379              // Slice the sighash.
380              _returnData := add(_returnData, 0x04)
381          }
382          return abi.decode(_returnData, (string)); // All that remains is the revert string
383      }
384  
385      function _computeMaxBorrowableAmount(
386          address user,
387          uint256 _exchangeRate
388      ) internal view returns (uint256 collateralAmountInAsset) {
389          collateralAmountInAsset =
390              yieldBox.toAmount(
391                  collateralId,
392                  (userCollateralShare[user] *
393                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
394                      collateralizationRate),
395                  false
396              ) /
397              _exchangeRate;
398      }
399  
400      /// @notice Concrete implementation of `isSolvent`. Includes a parameter to allow caching `exchangeRate`.
401      /// @param _exchangeRate The exchange rate. Used to cache the `exchangeRate` between calls.
402      function _isSolvent(
403          address user,
404          uint256 _exchangeRate
405      ) internal view returns (bool) {
406          // accrue must have already been called!
407          uint256 borrowPart = userBorrowPart[user];
408          if (borrowPart == 0) return true;
409          uint256 collateralShare = userCollateralShare[user];
410          if (collateralShare == 0) return false;
411  
412          Rebase memory _totalBorrow = totalBorrow;
413  
414          return
415              yieldBox.toAmount(
416                  collateralId,
417                  collateralShare *
418                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
419                      collateralizationRate,
420                  false
421              ) >=
422              // Moved exchangeRate here instead of dividing the other side to preserve more precision
423              (borrowPart * _totalBorrow.elastic * _exchangeRate) /
424                  _totalBorrow.base;
425      }
426  
427      /// @notice Returns the min and max LTV for user in asset price
428      function _computeMaxAndMinLTVInAsset(
429          uint256 collateralShare,
430          uint256 _exchangeRate
431      ) internal view returns (uint256 min, uint256 max) {
432          uint256 collateralAmount = yieldBox.toAmount(
433              collateralId,
434              collateralShare,
435              false
436          );
437  
438          max = (collateralAmount * EXCHANGE_RATE_PRECISION) / _exchangeRate;
439          min = (max * collateralizationRate) / FEE_PRECISION;
440      }
441  
442      function _getCallerReward(
443          uint256 borrowed,
444          uint256 startTVLInAsset,
445          uint256 maxTVLInAsset
446      ) internal view returns (uint256) {
447          if (borrowed == 0) return 0;
448          if (startTVLInAsset == 0) return 0;
449  
450          if (borrowed < startTVLInAsset) return 0;
451          if (borrowed >= maxTVLInAsset) return minLiquidatorReward;
452  
453          uint256 rewardPercentage = ((borrowed - startTVLInAsset) *
454              FEE_PRECISION) / (maxTVLInAsset - startTVLInAsset);
455  
456          int256 diff = int256(minLiquidatorReward) - int256(maxLiquidatorReward);
457          int256 reward = (diff * int256(rewardPercentage)) /
458              int256(FEE_PRECISION) +
459              int256(maxLiquidatorReward);
460  
461          return uint256(reward);
462      }
463  
464      function _computeAllowanceAmountInAsset(
465          address user,
466          uint256 _exchangeRate,
467          uint256 borrowAmount,
468          uint256 assetDecimals
469      ) internal view returns (uint256) {
470          uint256 maxBorrowabe = _computeMaxBorrowableAmount(user, _exchangeRate);
471  
472          uint256 shareRatio = _getRatio(
473              borrowAmount,
474              maxBorrowabe,
475              assetDecimals
476          );
477          return (shareRatio * userCollateralShare[user]) / (10 ** assetDecimals);
478      }
479  
480      function _getRatio(
481          uint256 numerator,
482          uint256 denominator,
483          uint256 precision
484      ) private pure returns (uint256) {
485          if (numerator == 0 || denominator == 0) {
486              return 0;
487          }
488          uint256 _numerator = numerator * 10 ** (precision + 1);
489          uint256 _quotient = ((_numerator / denominator) + 5) / 10;
490          return (_quotient);
491      }
492: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L14-L492

File: contracts/markets/bigBang/BigBang.sol

39   contract BigBang is BoringOwnable, Market {
40       using RebaseLibrary for Rebase;
41       using BoringERC20 for IERC20;
42   
43       // ************ //
44       // *** VARS *** //
45       // ************ //
46       mapping(address => mapping(address => bool)) public operators;
47   
48       IBigBang.AccrueInfo public accrueInfo;
49   
50       uint256 public totalFees;
51   
52       bool private _isEthMarket;
53       uint256 public maxDebtRate;
54       uint256 public minDebtRate;
55       uint256 public debtRateAgainstEthMarket;
56       uint256 public debtStartPoint;
57       uint256 private constant DEBT_PRECISION = 1e18;
58   
59       // ************** //
60       // *** EVENTS *** //
61       // ************** //
62       /// @notice event emitted when accrue is called
63       event LogAccrue(uint256 accruedAmount, uint64 rate);
64       /// @notice event emitted when collateral is added
65       event LogAddCollateral(
66           address indexed from,
67           address indexed to,
68           uint256 share
69       );
70       /// @notice event emitted when collateral is removed
71       event LogRemoveCollateral(
72           address indexed from,
73           address indexed to,
74           uint256 share
75       );
76       /// @notice event emitted when borrow is performed
77       event LogBorrow(
78           address indexed from,
79           address indexed to,
80           uint256 amount,
81           uint256 feeAmount,
82           uint256 part
83       );
84       /// @notice event emitted when a repay operation is performed
85       event LogRepay(
86           address indexed from,
87           address indexed to,
88           uint256 amount,
89           uint256 part
90       );
91       /// @notice event emitted when the minimum debt rate is updated
92       event MinDebtRateUpdated(uint256 oldVal, uint256 newVal);
93       /// @notice event emitted when the maximum debt rate is updated
94       event MaxDebtRateUpdated(uint256 oldVal, uint256 newVal);
95       /// @notice event emitted when the debt rate against the main market is updated
96       event DebtRateAgainstEthUpdated(uint256 oldVal, uint256 newVal);
97   
98       constructor() MarketERC20("Tapioca BigBang") {}
99   
100      /// @notice The init function that acts as a constructor
101      function init(bytes calldata data) external onlyOnce {
102          (
103              IPenrose tapiocaBar_,
104              IERC20 _collateral,
105              uint256 _collateralId,
106              IOracle _oracle,
107              uint256 _exchangeRatePrecision,
108              uint256 _debtRateAgainstEth,
109              uint256 _debtRateMin,
110              uint256 _debtRateMax,
111              uint256 _debtStartPoint
112          ) = abi.decode(
113                  data,
114                  (
115                      IPenrose,
116                      IERC20,
117                      uint256,
118                      IOracle,
119                      uint256,
120                      uint256,
121                      uint256,
122                      uint256,
123                      uint256
124                  )
125              );
126  
127          penrose = tapiocaBar_;
128          yieldBox = YieldBox(tapiocaBar_.yieldBox());
129          owner = address(penrose);
130  
131          address _asset = penrose.usdoToken();
132  
133          require(
134              address(_collateral) != address(0) &&
135                  address(_asset) != address(0) &&
136                  address(_oracle) != address(0),
137              "BigBang: bad pair"
138          );
139  
140          asset = IERC20(_asset);
141          assetId = penrose.usdoAssetId();
142          collateral = _collateral;
143          collateralId = _collateralId;
144          oracle = _oracle;
145  
146          updateExchangeRate();
147  
148          callerFee = 90000; // 90%
149          protocolFee = 10000; // 10%
150          collateralizationRate = 75000; // 75%
151  
152          EXCHANGE_RATE_PRECISION = _exchangeRatePrecision > 0
153              ? _exchangeRatePrecision
154              : 1e18;
155  
156          _isEthMarket = collateralId == penrose.wethAssetId();
157          if (!_isEthMarket) {
158              debtRateAgainstEthMarket = _debtRateAgainstEth;
159              maxDebtRate = _debtRateMax;
160              minDebtRate = _debtRateMin;
161              debtStartPoint = _debtStartPoint;
162          }
163  
164          minLiquidatorReward = 1e3;
165          maxLiquidatorReward = 1e4;
166          liquidationBonusAmount = 1e4;
167          borrowOpeningFee = 50; // 0.05%
168          liquidationMultiplier = 12000; //12%
169      }
170  
171      // ********************** //
172      // *** VIEW FUNCTIONS *** //
173      // ********************** //
174      /// @notice returns total market debt
175      function getTotalDebt() external view returns (uint256) {
176          return totalBorrow.elastic;
177      }
178  
179      /// @notice returns the current debt rate
180      function getDebtRate() public view returns (uint256) {
181          if (_isEthMarket) return penrose.bigBangEthDebtRate(); // default 0.5%
182          if (totalBorrow.elastic == 0) return minDebtRate;
183  
184          uint256 _ethMarketTotalDebt = BigBang(penrose.bigBangEthMarket())
185              .getTotalDebt();
186          uint256 _currentDebt = totalBorrow.elastic;
187          uint256 _maxDebtPoint = (_ethMarketTotalDebt *
188              debtRateAgainstEthMarket) / 1e18;
189  
190          if (_currentDebt >= _maxDebtPoint) return maxDebtRate;
191  
192          uint256 debtPercentage = ((_currentDebt - debtStartPoint) *
193              DEBT_PRECISION) / (_maxDebtPoint - debtStartPoint);
194          uint256 debt = ((maxDebtRate - minDebtRate) * debtPercentage) /
195              DEBT_PRECISION +
196              minDebtRate;
197  
198          if (debt > maxDebtRate) return maxDebtRate;
199  
200          return debt;
201      }
202  
203      // ************************ //
204      // *** PUBLIC FUNCTIONS *** //
205      // ************************ //
206      /// @notice Allows batched call to BingBang.
207      /// @param calls An array encoded call data.
208      /// @param revertOnFail If True then reverts after a failed call and stops doing further calls.
209      function execute(
210          bytes[] calldata calls,
211          bool revertOnFail
212      ) external returns (bool[] memory successes, string[] memory results) {
213          successes = new bool[](calls.length);
214          results = new string[](calls.length);
215          for (uint256 i = 0; i < calls.length; i++) {
216              (bool success, bytes memory result) = address(this).delegatecall(
217                  calls[i]
218              );
219              require(success || !revertOnFail, _getRevertMsg(result));
220              successes[i] = success;
221              results[i] = _getRevertMsg(result);
222          }
223      }
224  
225      /// @notice allows 'operator' to act on behalf of the sender
226      /// @param status true/false
227      function updateOperator(address operator, bool status) external {
228          operators[msg.sender][operator] = status;
229      }
230  
231      /// @notice Accrues the interest on the borrowed tokens and handles the accumulation of fees.
232      function accrue() public {
233          _accrue();
234      }
235  
236      /// @notice Sender borrows `amount` and transfers it to `to`.
237      /// @param from Account to borrow for.
238      /// @param to The receiver of borrowed tokens.
239      /// @param amount Amount to borrow.
240      /// @return part Total part of the debt held by borrowers.
241      /// @return share Total amount in shares borrowed.
242      function borrow(
243          address from,
244          address to,
245          uint256 amount
246      ) public notPaused solvent(from) returns (uint256 part, uint256 share) {
247          uint256 allowanceShare = _computeAllowanceAmountInAsset(
248              from,
249              exchangeRate,
250              amount,
251              asset.safeDecimals()
252          );
253          _allowedBorrow(from, allowanceShare);
254          (part, share) = _borrow(from, to, amount);
255      }
256  
257      /// @notice Repays a loan.
258      /// @dev The bool param is not used but we added it to respect the ISingularity interface for MarketsHelper compatibility
259      /// @param from Address to repay from.
260      /// @param to Address of the user this payment should go.
261      /// @param part The amount to repay. See `userBorrowPart`.
262      /// @return amount The total amount repayed.
263      function repay(
264          address from,
265          address to,
266          bool,
267          uint256 part
268      ) public notPaused allowedBorrow(from, part) returns (uint256 amount) {
269          updateExchangeRate();
270  
271          accrue();
272  
273          amount = _repay(from, to, part);
274      }
275  
276      /// @notice Adds `collateral` from msg.sender to the account `to`.
277      /// @param from Account to transfer shares from.
278      /// @param to The receiver of the tokens.
279      /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
280      /// False if tokens from msg.sender in `yieldBox` should be transferred.
281      /// @param share The amount of shares to add for `to`.
282      function addCollateral(
283          address from,
284          address to,
285          bool skim,
286          uint256 amount,
287          uint256 share
288      ) public allowedBorrow(from, share) notPaused {
289          _addCollateral(from, to, skim, amount, share);
290      }
291  
292      /// @notice Removes `share` amount of collateral and transfers it to `to`.
293      /// @param from Account to debit collateral from.
294      /// @param to The receiver of the shares.
295      /// @param share Amount of shares to remove.
296      function removeCollateral(
297          address from,
298          address to,
299          uint256 share
300      ) public notPaused solvent(from) allowedBorrow(from, share) {
301          _removeCollateral(from, to, share);
302      }
303  
304      /// @notice Entry point for liquidations.
305      /// @param users An array of user addresses.
306      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.
307      /// @param swapper Contract address of the `MultiSwapper` implementation. See `setSwapper`.
308      /// @param collateralToAssetSwapData Extra swap data
309      function liquidate(
310          address[] calldata users,
311          uint256[] calldata maxBorrowParts,
312          ISwapper swapper,
313          bytes calldata collateralToAssetSwapData
314      ) external notPaused {
315          // Oracle can fail but we still need to allow liquidations
316          (, uint256 _exchangeRate) = updateExchangeRate();
317          _accrue();
318  
319          _closedLiquidation(
320              users,
321              maxBorrowParts,
322              swapper,
323              _exchangeRate,
324              collateralToAssetSwapData
325          );
326      }
327  
328      /// @notice Lever up: Borrow more and buy collateral with it.
329      /// @param from The user who buys
330      /// @param borrowAmount Amount of extra asset borrowed
331      /// @param supplyAmount Amount of asset supplied (down payment)
332      /// @param minAmountOut Mininal collateral amount to receive
333      /// @param swapper Swapper to execute the purchase
334      /// @param dexData Additional data to pass to the swapper
335      /// @return amountOut Actual collateral amount purchased
336      function buyCollateral(
337          address from,
338          uint256 borrowAmount,
339          uint256 supplyAmount,
340          uint256 minAmountOut,
341          ISwapper swapper,
342          bytes calldata dexData
343      ) external notPaused solvent(from) returns (uint256 amountOut) {
344          require(penrose.swappers(swapper), "SGL: Invalid swapper");
345  
346          // Let this fail first to save gas:
347          uint256 supplyShare = yieldBox.toShare(assetId, supplyAmount, true);
348          if (supplyShare > 0) {
349              yieldBox.transfer(from, address(swapper), assetId, supplyShare);
350          }
351  
352          uint256 borrowShare;
353          (, borrowShare) = _borrow(from, address(swapper), borrowAmount);
354  
355          ISwapper.SwapData memory swapData = swapper.buildSwapData(
356              assetId,
357              collateralId,
358              0,
359              supplyShare + borrowShare,
360              true,
361              true
362          );
363  
364          uint256 collateralShare;
365          (amountOut, collateralShare) = swapper.swap(
366              swapData,
367              minAmountOut,
368              from,
369              dexData
370          );
371          require(amountOut >= minAmountOut, "SGL: not enough");
372  
373          _allowedBorrow(from, collateralShare);
374          _addCollateral(from, from, false, 0, collateralShare);
375      }
376  
377      /// @notice Lever down: Sell collateral to repay debt; excess goes to YB
378      /// @param from The user who sells
379      /// @param share Collateral YieldBox-shares to sell
380      /// @param minAmountOut Mininal proceeds required for the sale
381      /// @param swapper Swapper to execute the sale
382      /// @param dexData Additional data to pass to the swapper
383      /// @return amountOut Actual asset amount received in the sale
384      function sellCollateral(
385          address from,
386          uint256 share,
387          uint256 minAmountOut,
388          ISwapper swapper,
389          bytes calldata dexData
390      ) external notPaused solvent(from) returns (uint256 amountOut) {
391          require(penrose.swappers(swapper), "SGL: Invalid swapper");
392  
393          _allowedBorrow(from, share);
394          _removeCollateral(from, address(swapper), share);
395          ISwapper.SwapData memory swapData = swapper.buildSwapData(
396              collateralId,
397              assetId,
398              0,
399              share,
400              true,
401              true
402          );
403          uint256 shareOut;
404          (amountOut, shareOut) = swapper.swap(
405              swapData,
406              minAmountOut,
407              from,
408              dexData
409          );
410          // As long as the ratio is correct, we trust `amountOut` resp.
411          // `shareOut`, because all money received by the swapper gets used up
412          // one way or another, or the transaction will revert.
413          require(amountOut >= minAmountOut, "SGL: not enough");
414          uint256 partOwed = userBorrowPart[from];
415          uint256 amountOwed = totalBorrow.toElastic(partOwed, true);
416          uint256 shareOwed = yieldBox.toShare(assetId, amountOwed, true);
417          if (shareOwed <= shareOut) {
418              _repay(from, from, partOwed);
419          } else {
420              //repay as much as we can
421              uint256 partOut = totalBorrow.toBase(amountOut, false);
422              _repay(from, from, partOut);
423          }
424      }
425  
426      function transfer(
427          address to,
428          uint256 amount
429      ) public override returns (bool) {}
430  
431      function transferFrom(
432          address from,
433          address to,
434          uint256 amount
435      ) public override returns (bool) {}
436  
437      // ************************* //
438      // *** OWNER FUNCTIONS ***** //
439      // ************************* //
440  
441      /// @notice Transfers fees to penrose
442      function refreshPenroseFees(
443          address
444      ) external onlyOwner notPaused returns (uint256 feeShares) {
445          uint256 balance = asset.balanceOf(address(this));
446          totalFees += balance;
447          feeShares = yieldBox.toShare(assetId, totalFees, false);
448  
449          if (totalFees > 0) {
450              asset.approve(address(yieldBox), totalFees);
451  
452              yieldBox.depositAsset(
453                  assetId,
454                  address(this),
455                  msg.sender,
456                  totalFees,
457                  0
458              );
459  
460              totalFees = 0;
461          }
462      }
463  
464      /// @notice sets BigBang specific configuration
465      /// @dev values are updated only if > 0 or not address(0)
466      function setBigBangConfig(
467          uint256 _minDebtRate,
468          uint256 _maxDebtRate,
469          uint256 _debtRateAgainstEthMarket,
470          uint256 _liquidationMultiplier
471      ) external onlyOwner {
472          _isEthMarket = collateralId == penrose.wethAssetId();
473  
474          if (!_isEthMarket) {
475              if (_minDebtRate > 0) {
476                  require(_minDebtRate < maxDebtRate, "BigBang: not valid");
477                  emit MinDebtRateUpdated(minDebtRate, _minDebtRate);
478                  minDebtRate = _minDebtRate;
479              }
480  
481              if (_maxDebtRate > 0) {
482                  require(_maxDebtRate > minDebtRate, "BigBang: not valid");
483                  emit MaxDebtRateUpdated(maxDebtRate, _maxDebtRate);
484                  maxDebtRate = _maxDebtRate;
485              }
486  
487              if (_debtRateAgainstEthMarket > 0) {
488                  emit DebtRateAgainstEthUpdated(
489                      debtRateAgainstEthMarket,
490                      _debtRateAgainstEthMarket
491                  );
492                  debtRateAgainstEthMarket = _debtRateAgainstEthMarket;
493              }
494  
495              if (_liquidationMultiplier > 0) {
496                  require(
497                      _liquidationMultiplier < FEE_PRECISION,
498                      "BigBang: not valid"
499                  );
500                  emit LiquidationMultiplierUpdated(
501                      liquidationMultiplier,
502                      _liquidationMultiplier
503                  );
504                  liquidationMultiplier = _liquidationMultiplier;
505              }
506          }
507      }
508  
509      // ************************* //
510      // *** PRIVATE FUNCTIONS *** //
511      // ************************* //
512      function _accrue() internal override {
513          IBigBang.AccrueInfo memory _accrueInfo = accrueInfo;
514          // Number of seconds since accrue was called
515          uint256 elapsedTime = block.timestamp - _accrueInfo.lastAccrued;
516          if (elapsedTime == 0) {
517              return;
518          }
519          //update debt rate
520          uint256 annumDebtRate = getDebtRate();
521          _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second
522  
523          _accrueInfo.lastAccrued = uint64(block.timestamp);
524  
525          Rebase memory _totalBorrow = totalBorrow;
526  
527          uint256 extraAmount = 0;
528  
529          // Calculate fees
530          extraAmount =
531              (uint256(_totalBorrow.elastic) *
532                  _accrueInfo.debtRate *
533                  elapsedTime) /
534              1e18;
535          _totalBorrow.elastic += uint128(extraAmount);
536  
537          totalBorrow = _totalBorrow;
538          accrueInfo = _accrueInfo;
539  
540          emit LogAccrue(extraAmount, _accrueInfo.debtRate);
541      }
542  
543      function _addCollateral(
544          address from,
545          address to,
546          bool skim,
547          uint256 amount,
548          uint256 share
549      ) internal {
550          if (share == 0) {
551              share = yieldBox.toShare(collateralId, amount, false);
552          }
553          userCollateralShare[to] += share;
554          uint256 oldTotalCollateralShare = totalCollateralShare;
555          totalCollateralShare = oldTotalCollateralShare + share;
556          _addTokens(from, collateralId, share, oldTotalCollateralShare, skim);
557          emit LogAddCollateral(skim ? address(yieldBox) : from, to, share);
558      }
559  
560      function _liquidateUser(
561          address user,
562          uint256 maxBorrowPart,
563          ISwapper swapper,
564          uint256 _exchangeRate,
565          bytes calldata _dexData
566      ) private {
567          if (_isSolvent(user, _exchangeRate)) return;
568  
569          (
570              uint256 startTVLInAsset,
571              uint256 maxTVLInAsset
572          ) = _computeMaxAndMinLTVInAsset(
573                  userCollateralShare[user],
574                  _exchangeRate
575              );
576          uint256 callerReward = _getCallerReward(
577              userBorrowPart[user],
578              startTVLInAsset,
579              maxTVLInAsset
580          );
581  
582          (
583              uint256 borrowAmount,
584              uint256 borrowPart,
585              uint256 collateralShare
586          ) = _updateBorrowAndCollateralShare(user, maxBorrowPart, _exchangeRate);
587          emit LogRemoveCollateral(user, address(swapper), collateralShare);
588          emit LogRepay(address(swapper), user, borrowAmount, borrowPart);
589  
590          uint256 borrowShare = yieldBox.toShare(assetId, borrowAmount, true);
591  
592          // Closed liquidation using a pre-approved swapper
593          require(penrose.swappers(swapper), "BigBang: Invalid swapper");
594  
595          // Swaps the users collateral for the borrowed asset
596          yieldBox.transfer(
597              address(this),
598              address(swapper),
599              collateralId,
600              collateralShare
601          );
602  
603          uint256 minAssetMount = 0;
604          if (_dexData.length > 0) {
605              minAssetMount = abi.decode(_dexData, (uint256));
606          }
607  
608          uint256 balanceBefore = yieldBox.balanceOf(address(this), assetId);
609  
610          ISwapper.SwapData memory swapData = swapper.buildSwapData(
611              collateralId,
612              assetId,
613              0,
614              collateralShare,
615              true,
616              true
617          );
618          swapper.swap(swapData, minAssetMount, address(this), "");
619          uint256 balanceAfter = yieldBox.balanceOf(address(this), assetId);
620  
621          uint256 returnedShare = balanceAfter - balanceBefore;
622          (uint256 feeShare, uint256 callerShare) = _extractLiquidationFees(
623              returnedShare,
624              borrowShare,
625              callerReward
626          );
627          address[] memory _users = new address[](1);
628          _users[0] = user;
629          emit Liquidated(
630              msg.sender,
631              _users,
632              callerShare,
633              feeShare,
634              borrowAmount,
635              collateralShare
636          );
637      }
638  
639      function _extractLiquidationFees(
640          uint256 returnedShare,
641          uint256 borrowShare,
642          uint256 callerReward
643      ) private returns (uint256 feeShare, uint256 callerShare) {
644          uint256 extraShare = returnedShare - borrowShare;
645          feeShare = (extraShare * protocolFee) / FEE_PRECISION; // x% of profit goes to fee.
646          callerShare = (extraShare * callerReward) / FEE_PRECISION; //  y%  of profit goes to caller.
647  
648          yieldBox.transfer(address(this), penrose.feeTo(), assetId, feeShare);
649          yieldBox.transfer(address(this), msg.sender, assetId, callerShare);
650      }
651  
652      /// @notice Handles the liquidation of users' balances, once the users' amount of collateral is too low.
653      /// @dev Closed liquidations Only, 90% of extra shares goes to caller and 10% to protocol
654      /// @param users An array of user addresses.
655      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.
656      /// @param swapper Contract address of the `MultiSwapper` implementation. See `setSwapper`.
657      /// @param swapData Swap necessar data
658      function _closedLiquidation(
659          address[] calldata users,
660          uint256[] calldata maxBorrowParts,
661          ISwapper swapper,
662          uint256 _exchangeRate,
663          bytes calldata swapData
664      ) private {
665          uint256 liquidatedCount = 0;
666          for (uint256 i = 0; i < users.length; i++) {
667              address user = users[i];
668              if (!_isSolvent(user, _exchangeRate)) {
669                  liquidatedCount++;
670                  _liquidateUser(
671                      user,
672                      maxBorrowParts[i],
673                      swapper,
674                      _exchangeRate,
675                      swapData
676                  );
677              }
678          }
679  
680          require(liquidatedCount > 0, "SGL: no users found");
681      }
682  
683      /// @dev Helper function to move tokens.
684      /// @param from Account to debit tokens from, in `yieldBox`.
685      /// @param _tokenId The ERC-20 token asset ID in yieldBox.
686      /// @param share The amount in shares to add.
687      /// @param total Grand total amount to deduct from this contract's balance. Only applicable if `skim` is True.
688      /// Only used for accounting checks.
689      /// @param skim If True, only does a balance check on this contract.
690      /// False if tokens from msg.sender in `yieldBox` should be transferred.
691      function _addTokens(
692          address from,
693          uint256 _tokenId,
694          uint256 share,
695          uint256 total,
696          bool skim
697      ) internal {
698          if (skim) {
699              require(
700                  share <= yieldBox.balanceOf(address(this), _tokenId) - total,
701                  "BigBang: too much"
702              );
703          } else {
704              yieldBox.transfer(from, address(this), _tokenId, share);
705          }
706      }
707  
708      /// @dev Concrete implementation of `removeCollateral`.
709      function _removeCollateral(
710          address from,
711          address to,
712          uint256 share
713      ) internal {
714          userCollateralShare[from] -= share;
715          totalCollateralShare -= share;
716          emit LogRemoveCollateral(from, to, share);
717          yieldBox.transfer(address(this), to, collateralId, share);
718      }
719  
720      /// @dev Concrete implementation of `repay`.
721      function _repay(
722          address from,
723          address to,
724          uint256 part
725      ) internal returns (uint256 amount) {
726          (totalBorrow, amount) = totalBorrow.sub(part, true);
727  
728          userBorrowPart[to] -= part;
729  
730          uint256 toWithdraw = (amount - part); //acrrued
731          uint256 toBurn = amount - toWithdraw;
732          yieldBox.withdraw(assetId, from, address(this), amount, 0);
733          //burn USDO
734          if (toBurn > 0) {
735              IUSDOBase(address(asset)).burn(address(this), toBurn);
736          }
737  
738          emit LogRepay(from, to, amount, part);
739      }
740  
741      /// @dev Concrete implementation of `borrow`.
742      function _borrow(
743          address from,
744          address to,
745          uint256 amount
746      ) internal returns (uint256 part, uint256 share) {
747          uint256 feeAmount = (amount * borrowOpeningFee) / FEE_PRECISION; // A flat % fee is charged for any borrow
748  
749          (totalBorrow, part) = totalBorrow.add(amount + feeAmount, true);
750          require(
751              totalBorrowCap == 0 || totalBorrow.elastic <= totalBorrowCap,
752              "BigBang: borrow cap reached"
753          );
754  
755          userBorrowPart[from] += part;
756  
757          //mint USDO
758          IUSDOBase(address(asset)).mint(address(this), amount);
759  
760          //deposit borrowed amount to user
761          asset.approve(address(yieldBox), amount);
762          yieldBox.depositAsset(assetId, address(this), to, amount, 0);
763  
764          share = yieldBox.toShare(assetId, amount, false);
765  
766          emit LogBorrow(from, to, amount, feeAmount, part);
767      }
768  
769      function _updateBorrowAndCollateralShare(
770          address user,
771          uint256 maxBorrowPart,
772          uint256 _exchangeRate
773      )
774          private
775          returns (
776              uint256 borrowAmount,
777              uint256 borrowPart,
778              uint256 collateralShare
779          )
780      {
781          uint256 collateralPartInAsset = (yieldBox.toAmount(
782              collateralId,
783              userCollateralShare[user],
784              false
785          ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;
786  
787          uint256 borrowAssetDecimals = asset.safeDecimals();
788          uint256 collateralDecimals = collateral.safeDecimals();
789  
790          uint256 availableBorrowPart = computeClosingFactor(
791              userBorrowPart[user],
792              collateralPartInAsset,
793              borrowAssetDecimals,
794              collateralDecimals,
795              FEE_PRECISION_DECIMALS
796          );
797          borrowPart = maxBorrowPart > availableBorrowPart
798              ? availableBorrowPart
799              : maxBorrowPart;
800  
801          if (borrowPart > userBorrowPart[user]) {
802              borrowPart = userBorrowPart[user];
803          }
804  
805          userBorrowPart[user] = userBorrowPart[user] - borrowPart;
806  
807          borrowAmount = totalBorrow.toElastic(borrowPart, false);
808          uint256 amountWithBonus = borrowAmount +
809              (borrowAmount * liquidationMultiplier) /
810              FEE_PRECISION;
811          collateralShare = yieldBox.toShare(
812              collateralId,
813              (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,
814              false
815          );
816          if (collateralShare > userCollateralShare[user]) {
817              collateralShare = userCollateralShare[user];
818          }
819          userCollateralShare[user] -= collateralShare;
820          require(borrowAmount != 0, "SGL: solvent");
821  
822          totalBorrow.elastic -= uint128(borrowAmount);
823          totalBorrow.base -= uint128(borrowPart);
824      }
825: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L39-L825

File: contracts/markets/singularity/Singularity.sol

37   contract Singularity is SGLCommon {
38       using RebaseLibrary for Rebase;
39   
40       // ************ //
41       // *** VARS *** //
42       // ************ //
43       /// @notice enum representing each type of module associated with a Singularity market
44       /// @dev modules are contracts that holds a portion of the market's logic
45       enum Module {
46           Base,
47           Borrow,
48           Collateral,
49           Liquidation,
50           Leverage
51       }
52       /// @notice returns the liquidation module
53       SGLLiquidation public liquidationModule;
54       /// @notice returns the borrow module
55       SGLBorrow public borrowModule;
56       /// @notice returns the collateral module
57       SGLCollateral public collateralModule;
58       /// @notice returns the leverage module
59       SGLLeverage public leverageModule;
60   
61       /// @notice The init function that acts as a constructor
62       function init(bytes calldata data) external onlyOnce {
63           (
64               address _liquidationModule,
65               address _borrowModule,
66               address _collateralModule,
67               address _leverageModule,
68               IPenrose tapiocaBar_,
69               IERC20 _asset,
70               uint256 _assetId,
71               IERC20 _collateral,
72               uint256 _collateralId,
73               IOracle _oracle,
74               uint256 _exchangeRatePrecision
75           ) = abi.decode(
76                   data,
77                   (
78                       address,
79                       address,
80                       address,
81                       address,
82                       IPenrose,
83                       IERC20,
84                       uint256,
85                       IERC20,
86                       uint256,
87                       IOracle,
88                       uint256
89                   )
90               );
91   
92           liquidationModule = SGLLiquidation(_liquidationModule);
93           collateralModule = SGLCollateral(_collateralModule);
94           borrowModule = SGLBorrow(_borrowModule);
95           leverageModule = SGLLeverage(_leverageModule);
96           penrose = tapiocaBar_;
97           yieldBox = YieldBox(tapiocaBar_.yieldBox());
98           owner = address(penrose);
99   
100          require(
101              address(_collateral) != address(0) &&
102                  address(_asset) != address(0) &&
103                  address(_oracle) != address(0),
104              "SGL: bad pair"
105          );
106          asset = _asset;
107          collateral = _collateral;
108          assetId = _assetId;
109          collateralId = _collateralId;
110          oracle = _oracle;
111  
112          minimumInterestPerSecond = 951293760; // approx 3% APR
113          maximumInterestPerSecond = 2536783360; // approx 8% APR
114          interestElasticity = 7200e36; // Half or double in 28800 seconds (1 hours) if linear
115          startingInterestPerSecond = minimumInterestPerSecond;
116  
117          accrueInfo.interestPerSecond = uint64(startingInterestPerSecond); // 1% APR, with 1e18 being 100%
118  
119          updateExchangeRate();
120  
121          //default fees
122          callerFee = 1000; // 1%
123          protocolFee = 10000; // 10%
124          borrowOpeningFee = 50; // 0.05%
125  
126          //liquidation
127          liquidationMultiplier = 12000; //12%
128  
129          collateralizationRate = 75000;
130          lqCollateralizationRate = 25000;
131          EXCHANGE_RATE_PRECISION = _exchangeRatePrecision > 0
132              ? _exchangeRatePrecision
133              : 1e18;
134  
135          minLiquidatorReward = 1e3;
136          maxLiquidatorReward = 1e4;
137          liquidationBonusAmount = 1e4;
138  
139          minimumTargetUtilization = 3e17;
140          maximumTargetUtilization = 5e17;
141          fullUtilizationMinusMax = FULL_UTILIZATION - maximumTargetUtilization;
142      }
143  
144      // ********************** //
145      // *** VIEW FUNCTIONS *** //
146      // ********************** //
147      /// @notice transforms amount to shares for a market's permit operation
148      /// @param amount the amount to transform
149      /// @param tokenId the YieldBox asset id
150      /// @return share amount transformed into shares
151      function computeAllowedLendShare(
152          uint256 amount,
153          uint256 tokenId
154      ) external view returns (uint256 share) {
155          uint256 allShare = totalAsset.elastic +
156              yieldBox.toShare(tokenId, totalBorrow.elastic, true);
157          share = (amount * allShare) / totalAsset.base;
158      }
159  
160      /// @notice returns Total yieldBox shares for user
161      /// @param _user The user to check shares for
162      /// @param _assetId The asset id to check shares for
163      /// @return shares value
164      function yieldBoxShares(
165          address _user,
166          uint256 _assetId
167      ) external view returns (uint256) {
168          bytes32 sig = _assetId == assetId ? ASSET_SIG : COLLATERAL_SIG;
169          return
170              yieldBox.balanceOf(_user, _assetId) + _yieldBoxShares[_user][sig];
171      }
172  
173      // ************************ //
174      // *** PUBLIC FUNCTIONS *** //
175      // ************************ //
176      /// @notice Allows batched call to Singularity.
177      /// @param calls An array encoded call data.
178      /// @param revertOnFail If True then reverts after a failed call and stops doing further calls.
179      /// @return successes count of successful operations
180      /// @return results array of revert messages
181      function execute(
182          bytes[] calldata calls,
183          bool revertOnFail
184      ) external returns (bool[] memory successes, string[] memory results) {
185          successes = new bool[](calls.length);
186          results = new string[](calls.length);
187          for (uint256 i = 0; i < calls.length; i++) {
188              (bool success, bytes memory result) = address(this).delegatecall(
189                  calls[i]
190              );
191              require(success || !revertOnFail, _getRevertMsg(result));
192              successes[i] = success;
193              results[i] = _getRevertMsg(result);
194          }
195      }
196  
197      /// @notice Adds assets to the lending pair.
198      /// @param from Address to add asset from.
199      /// @param to The address of the user to receive the assets.
200      /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
201      /// False if tokens from msg.sender in `yieldBox` should be transferred.
202      /// @param share The amount of shares to add.
203      /// @return fraction Total fractions added.
204      function addAsset(
205          address from,
206          address to,
207          bool skim,
208          uint256 share
209      ) public notPaused allowedLend(from, share) returns (uint256 fraction) {
210          _accrue();
211          fraction = _addAsset(from, to, skim, share);
212      }
213  
214      /// @notice Removes an asset from msg.sender and transfers it to `to`.
215      /// @param from Account to debit Assets from.
216      /// @param to The user that receives the removed assets.
217      /// @param fraction The amount/fraction of assets held to remove.
218      /// @return share The amount of shares transferred to `to`.
219      function removeAsset(
220          address from,
221          address to,
222          uint256 fraction
223      ) public notPaused returns (uint256 share) {
224          _accrue();
225          share = _removeAsset(from, to, fraction, true);
226          _allowedLend(from, share);
227      }
228  
229      /// @notice Adds `collateral` from msg.sender to the account `to`.
230      /// @param from Account to transfer shares from.
231      /// @param to The receiver of the tokens.
232      /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
233      /// False if tokens from msg.sender in `yieldBox` should be transferred.
234      /// @param share The amount of shares to add for `to`.
235      function addCollateral(
236          address from,
237          address to,
238          bool skim,
239          uint256 amount,
240          uint256 share
241      ) public {
242          _executeModule(
243              Module.Collateral,
244              abi.encodeWithSelector(
245                  SGLCollateral.addCollateral.selector,
246                  from,
247                  to,
248                  skim,
249                  amount,
250                  share
251              )
252          );
253      }
254  
255      /// @notice Removes `share` amount of collateral and transfers it to `to`.
256      /// @param from Account to debit collateral from.
257      /// @param to The receiver of the shares.
258      /// @param share Amount of shares to remove.
259      function removeCollateral(address from, address to, uint256 share) public {
260          _executeModule(
261              Module.Collateral,
262              abi.encodeWithSelector(
263                  SGLCollateral.removeCollateral.selector,
264                  from,
265                  to,
266                  share
267              )
268          );
269      }
270  
271      /// @notice Sender borrows `amount` and transfers it to `to`.
272      /// @param from Account to borrow for.
273      /// @param to The receiver of borrowed tokens.
274      /// @param amount Amount to borrow.
275      /// @return part Total part of the debt held by borrowers.
276      /// @return share Total amount in shares borrowed.
277      function borrow(
278          address from,
279          address to,
280          uint256 amount
281      ) public returns (uint256 part, uint256 share) {
282          bytes memory result = _executeModule(
283              Module.Borrow,
284              abi.encodeWithSelector(SGLBorrow.borrow.selector, from, to, amount)
285          );
286          (part, share) = abi.decode(result, (uint256, uint256));
287      }
288  
289      /// @notice Repays a loan.
290      /// @param from Address to repay from.
291      /// @param to Address of the user this payment should go.
292      /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
293      /// False if tokens from msg.sender in `yieldBox` should be transferred.
294      /// @param part The amount to repay. See `userBorrowPart`.
295      /// @return amount The total amount repayed.
296      function repay(
297          address from,
298          address to,
299          bool skim,
300          uint256 part
301      ) public returns (uint256 amount) {
302          bytes memory result = _executeModule(
303              Module.Borrow,
304              abi.encodeWithSelector(
305                  SGLBorrow.repay.selector,
306                  from,
307                  to,
308                  skim,
309                  part
310              )
311          );
312          amount = abi.decode(result, (uint256));
313      }
314  
315      /// @notice Lever down: Sell collateral to repay debt; excess goes to YB
316      /// @param from The user who sells
317      /// @param share Collateral YieldBox-shares to sell
318      /// @param minAmountOut Mininal proceeds required for the sale
319      /// @param swapper Swapper to execute the sale
320      /// @param dexData Additional data to pass to the swapper
321      /// @return amountOut Actual asset amount received in the sale
322      function sellCollateral(
323          address from,
324          uint256 share,
325          uint256 minAmountOut,
326          ISwapper swapper,
327          bytes calldata dexData
328      ) external returns (uint256 amountOut) {
329          bytes memory result = _executeModule(
330              Module.Leverage,
331              abi.encodeWithSelector(
332                  SGLLeverage.sellCollateral.selector,
333                  from,
334                  share,
335                  minAmountOut,
336                  swapper,
337                  dexData
338              )
339          );
340          amountOut = abi.decode(result, (uint256));
341      }
342  
343      /// @notice Lever up: Borrow more and buy collateral with it.
344      /// @param from The user who buys
345      /// @param borrowAmount Amount of extra asset borrowed
346      /// @param supplyAmount Amount of asset supplied (down payment)
347      /// @param minAmountOut Mininal collateral amount to receive
348      /// @param swapper Swapper to execute the purchase
349      /// @param dexData Additional data to pass to the swapper
350      /// @return amountOut Actual collateral amount purchased
351      function buyCollateral(
352          address from,
353          uint256 borrowAmount,
354          uint256 supplyAmount,
355          uint256 minAmountOut,
356          ISwapper swapper,
357          bytes calldata dexData
358      ) external returns (uint256 amountOut) {
359          bytes memory result = _executeModule(
360              Module.Leverage,
361              abi.encodeWithSelector(
362                  SGLLeverage.buyCollateral.selector,
363                  from,
364                  borrowAmount,
365                  supplyAmount,
366                  minAmountOut,
367                  swapper,
368                  dexData
369              )
370          );
371          amountOut = abi.decode(result, (uint256));
372      }
373  
374      /// @notice Level up cross-chain: Borrow more and buy collateral with it.
375      /// @param from The user who sells
376      /// @param collateralAmount Extra collateral to be added
377      /// @param borrowAmount Borrowed amount that will be swapped into collateral
378      /// @param swapData Swap data used on destination chain for swapping USDO to the underlying TOFT token
379      /// @param lzData LayerZero specific data
380      /// @param externalData External contracts used for the cross chain operation
381      function multiHopBuyCollateral(
382          address from,
383          uint256 collateralAmount,
384          uint256 borrowAmount,
385          IUSDOBase.ILeverageSwapData calldata swapData,
386          IUSDOBase.ILeverageLZData calldata lzData,
387          IUSDOBase.ILeverageExternalContractsData calldata externalData
388      ) external payable {
389          _executeModule(
390              Module.Leverage,
391              abi.encodeWithSelector(
392                  SGLLeverage.multiHopBuyCollateral.selector,
393                  from,
394                  collateralAmount,
395                  borrowAmount,
396                  swapData,
397                  lzData,
398                  externalData
399              )
400          );
401      }
402  
403      /// @notice Level up cross-chain: Borrow more and buy collateral with it.
404      /// @param from The user who sells
405      /// @param share Collateral YieldBox-shares to sell
406      /// @param swapData Swap data used on destination chain for swapping USDO to the underlying TOFT token
407      /// @param lzData LayerZero specific data
408      /// @param externalData External contracts used for the cross chain operation
409      function multiHopSellCollateral(
410          address from,
411          uint256 share,
412          IUSDOBase.ILeverageSwapData calldata swapData,
413          IUSDOBase.ILeverageLZData calldata lzData,
414          IUSDOBase.ILeverageExternalContractsData calldata externalData
415      ) external payable {
416          _executeModule(
417              Module.Leverage,
418              abi.encodeWithSelector(
419                  SGLLeverage.multiHopSellCollateral.selector,
420                  from,
421                  share,
422                  swapData,
423                  lzData,
424                  externalData
425              )
426          );
427      }
428  
429      /// @notice Entry point for liquidations.
430      /// @dev Will call `closedLiquidation()` if not LQ exists or no LQ bid avail exists. Otherwise use LQ.
431      /// @param users An array of user addresses.
432      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.
433      ///        Ignore for `orderBookLiquidation()`
434      /// @param swapper Contract address of the `MultiSwapper` implementation. See `setSwapper`.
435      ///        Ignore for `orderBookLiquidation()`
436      /// @param collateralToAssetSwapData Extra swap data
437      ///        Ignore for `orderBookLiquidation()`
438      /// @param usdoToBorrowedSwapData Extra swap data
439      ///        Ignore for `closedLiquidation()`
440      function liquidate(
441          address[] calldata users,
442          uint256[] calldata maxBorrowParts,
443          ISwapper swapper,
444          bytes calldata collateralToAssetSwapData,
445          bytes calldata usdoToBorrowedSwapData
446      ) external {
447          _executeModule(
448              Module.Liquidation,
449              abi.encodeWithSelector(
450                  SGLLiquidation.liquidate.selector,
451                  users,
452                  maxBorrowParts,
453                  swapper,
454                  collateralToAssetSwapData,
455                  usdoToBorrowedSwapData
456              )
457          );
458      }
459  
460      /// @notice Withdraw the fees accumulated in `accrueInfo.feesEarnedFraction` to the balance of `feeTo`.
461      function withdrawFeesEarned() public {
462          _accrue();
463          address _feeTo = penrose.feeTo();
464          uint256 _feesEarnedFraction = accrueInfo.feesEarnedFraction;
465          balanceOf[_feeTo] += _feesEarnedFraction;
466          emit Transfer(address(0), _feeTo, _feesEarnedFraction);
467          accrueInfo.feesEarnedFraction = 0;
468          emit LogWithdrawFees(_feeTo, _feesEarnedFraction);
469      }
470  
471      // *********************** //
472      // *** OWNER FUNCTIONS *** //
473      // *********************** //
474      /// @notice Transfers fees to penrose
475      /// @dev can only be called by the owner
476      /// @param feeTo fees receiver
477      function refreshPenroseFees(
478          address feeTo
479      ) external onlyOwner notPaused returns (uint256 feeShares) {
480          if (accrueInfo.feesEarnedFraction > 0) {
481              withdrawFeesEarned();
482          }
483  
484          feeShares = _removeAsset(feeTo, msg.sender, balanceOf[feeTo], false);
485      }
486  
487      /// @notice sets Singularity specific configuration
488      /// @dev values are updated only if > 0 or not address(0)
489      function setSingularityConfig(
490          uint256 _lqCollateralizationRate,
491          uint256 _liquidationMultiplier,
492          uint256 _minimumTargetUtilization,
493          uint256 _maximumTargetUtilization,
494          uint64 _minimumInterestPerSecond,
495          uint64 _maximumInterestPerSecond,
496          uint256 _interestElasticity
497      ) external onlyOwner {
498          if (_minimumTargetUtilization > 0) {
499              emit MinimumTargetUtilizationUpdated(
500                  minimumTargetUtilization,
501                  _minimumTargetUtilization
502              );
503              minimumTargetUtilization = _minimumTargetUtilization;
504          }
505  
506          if (_maximumTargetUtilization > 0) {
507              require(
508                  _maximumTargetUtilization < FULL_UTILIZATION,
509                  "SGL: not valid"
510              );
511              emit MaximumTargetUtilizationUpdated(
512                  maximumTargetUtilization,
513                  _maximumTargetUtilization
514              );
515              maximumTargetUtilization = _maximumTargetUtilization;
516              fullUtilizationMinusMax =
517                  FULL_UTILIZATION -
518                  maximumTargetUtilization;
519          }
520  
521          if (_minimumInterestPerSecond > 0) {
522              require(
523                  _minimumInterestPerSecond < maximumInterestPerSecond,
524                  "SGL: not valid"
525              );
526              emit MinimumInterestPerSecondUpdated(
527                  minimumInterestPerSecond,
528                  _minimumInterestPerSecond
529              );
530              minimumInterestPerSecond = _minimumInterestPerSecond;
531          }
532  
533          if (_maximumInterestPerSecond > 0) {
534              require(
535                  _maximumInterestPerSecond > minimumInterestPerSecond,
536                  "SGL: not valid"
537              );
538              emit MaximumInterestPerSecondUpdated(
539                  maximumInterestPerSecond,
540                  _maximumInterestPerSecond
541              );
542              maximumInterestPerSecond = _maximumInterestPerSecond;
543          }
544  
545          if (_interestElasticity > 0) {
546              emit InterestElasticityUpdated(
547                  interestElasticity,
548                  _interestElasticity
549              );
550              interestElasticity = _interestElasticity;
551          }
552  
553          if (_lqCollateralizationRate > 0) {
554              require(
555                  _lqCollateralizationRate <= FEE_PRECISION,
556                  "SGL: not valid"
557              );
558              emit LqCollateralizationRateUpdated(
559                  lqCollateralizationRate,
560                  _lqCollateralizationRate
561              );
562              lqCollateralizationRate = _lqCollateralizationRate;
563          }
564  
565          if (_liquidationMultiplier > 0) {
566              require(_liquidationMultiplier < FEE_PRECISION, "SGL: not valid");
567              emit LiquidationMultiplierUpdated(
568                  liquidationMultiplier,
569                  _liquidationMultiplier
570              );
571              liquidationMultiplier = _liquidationMultiplier;
572          }
573      }
574  
575      /// @notice sets LQ specific confinguration
576      function setLiquidationQueueConfig(
577          ILiquidationQueue _liquidationQueue,
578          address _bidExecutionSwapper,
579          address _usdoSwapper
580      ) external onlyOwner {
581          if (address(_liquidationQueue) != address(0)) {
582              require(_liquidationQueue.onlyOnce(), "SGL: LQ not initalized");
583              liquidationQueue = _liquidationQueue;
584          }
585  
586          if (_bidExecutionSwapper != address(0)) {
587              emit BidExecutionSwapperUpdated(_bidExecutionSwapper);
588              liquidationQueue.setBidExecutionSwapper(_bidExecutionSwapper);
589          }
590  
591          if (_usdoSwapper != address(0)) {
592              emit UsdoSwapperUpdated(_usdoSwapper);
593              liquidationQueue.setUsdoSwapper(_usdoSwapper);
594          }
595      }
596  
597      // ************************* //
598      // *** PRIVATE FUNCTIONS *** //
599      // ************************* //
600      function _extractModule(Module _module) private view returns (address) {
601          address module;
602          if (_module == Module.Borrow) {
603              module = address(borrowModule);
604          } else if (_module == Module.Collateral) {
605              module = address(collateralModule);
606          } else if (_module == Module.Liquidation) {
607              module = address(liquidationModule);
608          } else if (_module == Module.Leverage) {
609              module = address(leverageModule);
610          }
611          if (module == address(0)) {
612              revert("SGL: module not set");
613          }
614  
615          return module;
616      }
617  
618      function _executeModule(
619          Module _module,
620          bytes memory _data
621      ) private returns (bytes memory returnData) {
622          bool success = true;
623          address module = _extractModule(_module);
624  
625          (success, returnData) = module.delegatecall(_data);
626          if (!success) {
627              revert(_getRevertMsg(returnData));
628          }
629      }
630  
631      function _executeViewModule(
632          Module _module,
633          bytes memory _data
634      ) private view returns (bytes memory returnData) {
635          bool success = true;
636          address module = _extractModule(_module);
637  
638          (success, returnData) = module.staticcall(_data);
639          if (!success) {
640              revert(_getRevertMsg(returnData));
641          }
642      }
643  
644      receive() external payable {}
645: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L37-L645

File: contracts/usd0/BaseUSDO.sol

46   contract BaseUSDO is BaseUSDOStorage, ERC20Permit {
47       using SafeERC20 for IERC20;
48       using BytesLib for bytes;
49       // ************ //
50       // *** VARS *** //
51       // ************ //
52       enum Module {
53           Leverage,
54           Market,
55           Options
56       }
57   
58       /// @notice returns the leverage module
59       USDOLeverageModule public leverageModule;
60   
61       /// @notice returns the market module
62       USDOMarketModule public marketModule;
63   
64       /// @notice returns the options module
65       USDOOptionsModule public optionsModule;
66   
67       constructor(
68           address _lzEndpoint,
69           IYieldBoxBase _yieldBox,
70           address _owner,
71           address payable _leverageModule,
72           address payable _marketModule,
73           address payable _optionsModule
74       ) BaseUSDOStorage(_lzEndpoint, _yieldBox) ERC20Permit("USDO") {
75           leverageModule = USDOLeverageModule(_leverageModule);
76           marketModule = USDOMarketModule(_marketModule);
77           optionsModule = USDOOptionsModule(_optionsModule);
78   
79           transferOwnership(_owner);
80       }
81   
82       // *********************** //
83       // *** OWNER FUNCTIONS *** //
84       // *********************** //
85       /// @notice set the max allowed USDO mintable through flashloan
86       /// @dev can only be called by the owner
87       /// @param _val the new amount
88       function setMaxFlashMintable(uint256 _val) external onlyOwner {
89           emit MaxFlashMintUpdated(maxFlashMint, _val);
90           maxFlashMint = _val;
91       }
92   
93       /// @notice set the flashloan fee
94       /// @dev can only be called by the owner
95       /// @param _val the new fee
96       function setFlashMintFee(uint256 _val) external onlyOwner {
97           require(_val < FLASH_MINT_FEE_PRECISION, "USDO: fee too big");
98           emit FlashMintFeeUpdated(flashMintFee, _val);
99           flashMintFee = _val;
100      }
101  
102      /// @notice set the Conservator address
103      /// @dev conservator can pause the contract
104      /// @param _conservator the new address
105      function setConservator(address _conservator) external onlyOwner {
106          require(_conservator != address(0), "USDO: address not valid");
107          emit ConservatorUpdated(conservator, _conservator);
108          conservator = _conservator;
109      }
110  
111      /// @notice updates the pause state of the contract
112      /// @dev can only be called by the conservator
113      /// @param val the new value
114      function updatePause(bool val) external {
115          require(msg.sender == conservator, "USDO: unauthorized");
116          require(val != paused, "USDO: same state");
117          emit PausedUpdated(paused, val);
118          paused = val;
119      }
120  
121      /// @notice sets/unsets address as minter
122      /// @dev can only be called by the owner
123      /// @param _for role receiver
124      /// @param _status true/false
125      function setMinterStatus(address _for, bool _status) external onlyOwner {
126          allowedMinter[_getChainId()][_for] = _status;
127          emit SetMinterStatus(_for, _status);
128      }
129  
130      /// @notice sets/unsets address as burner
131      /// @dev can only be called by the owner
132      /// @param _for role receiver
133      /// @param _status true/false
134      function setBurnerStatus(address _for, bool _status) external onlyOwner {
135          allowedBurner[_getChainId()][_for] = _status;
136          emit SetBurnerStatus(_for, _status);
137      }
138  
139      // ************************ //
140      // *** VIEW FUNCTIONS *** //
141      // ************************ //
142      /// @notice returns token's decimals
143      function decimals() public pure override returns (uint8) {
144          return 18;
145      }
146  
147      // ************************ //
148      // *** PUBLIC FUNCTIONS *** //
149      // ************************ //
150  
151      /// @notice triggers a sendFrom to another layer from destination
152      /// @param lzDstChainId LZ destination id
153      /// @param airdropAdapterParams airdrop params
154      /// @param zroPaymentAddress ZRO payment address
155      /// @param amount amount to send back
156      /// @param sendFromData data needed to trigger sendFrom on destination
157      /// @param approvals approvals array
158      function triggerSendFrom(
159          uint16 lzDstChainId,
160          bytes calldata airdropAdapterParams,
161          address zroPaymentAddress,
162          uint256 amount,
163          ISendFrom.LzCallParams calldata sendFromData,
164          ICommonData.IApproval[] calldata approvals
165      ) external payable {
166          _executeModule(
167              Module.Options,
168              abi.encodeWithSelector(
169                  USDOOptionsModule.triggerSendFrom.selector,
170                  lzDstChainId,
171                  airdropAdapterParams,
172                  zroPaymentAddress,
173                  amount,
174                  sendFromData,
175                  approvals
176              ),
177              false
178          );
179      }
180  
181      /// @notice Exercise an oTAP position
182      /// @param optionsData oTap exerciseOptions data
183      /// @param lzData data needed for the cross chain transer
184      /// @param tapSendData needed for withdrawing Tap token
185      /// @param approvals array
186      function exerciseOption(
187          ITapiocaOptionsBrokerCrossChain.IExerciseOptionsData
188              calldata optionsData,
189          ITapiocaOptionsBrokerCrossChain.IExerciseLZData calldata lzData,
190          ITapiocaOptionsBrokerCrossChain.IExerciseLZSendTapData
191              calldata tapSendData,
192          ICommonData.IApproval[] calldata approvals
193      ) external payable {
194          _executeModule(
195              Module.Options,
196              abi.encodeWithSelector(
197                  USDOOptionsModule.exerciseOption.selector,
198                  optionsData,
199                  lzData,
200                  tapSendData,
201                  approvals
202              ),
203              false
204          );
205      }
206  
207      /// @notice inits multiHopBuyCollateral
208      /// @param from The user who sells
209      /// @param collateralAmount Extra collateral to be added
210      /// @param borrowAmount Borrowed amount that will be swapped into collateral
211      /// @param swapData Swap data used on destination chain for swapping USDO to the underlying TOFT token
212      /// @param lzData LayerZero specific data
213      /// @param externalData External contracts used for the cross chain operation
214      /// @param approvals array
215      function initMultiHopBuy(
216          address from,
217          uint256 collateralAmount,
218          uint256 borrowAmount,
219          IUSDOBase.ILeverageSwapData calldata swapData,
220          IUSDOBase.ILeverageLZData calldata lzData,
221          IUSDOBase.ILeverageExternalContractsData calldata externalData,
222          bytes calldata airdropAdapterParams,
223          ICommonData.IApproval[] memory approvals
224      ) external payable {
225          _executeModule(
226              Module.Leverage,
227              abi.encodeWithSelector(
228                  USDOLeverageModule.initMultiHopBuy.selector,
229                  from,
230                  collateralAmount,
231                  borrowAmount,
232                  swapData,
233                  lzData,
234                  externalData,
235                  airdropAdapterParams,
236                  approvals
237              ),
238              false
239          );
240      }
241  
242      /// @notice calls removeAssetAndRepay on Magnetar from the destination layer
243      /// @param from sending address
244      /// @param to receiver address
245      /// @param lzDstChainId LayerZero destination chain id
246      /// @param zroPaymentAddress ZRO payment address
247      /// @param adapterParams LZ adapter params
248      /// @param externalData external addresses needed for the operation
249      /// @param removeAndRepayData removeAssetAndRepay params
250      /// @param approvals approvals params
251      function removeAsset(
252          address from,
253          address to,
254          uint16 lzDstChainId,
255          address zroPaymentAddress,
256          bytes calldata adapterParams,
257          ICommonData.ICommonExternalContracts calldata externalData,
258          IUSDOBase.IRemoveAndRepay calldata removeAndRepayData,
259          ICommonData.IApproval[] calldata approvals
260      ) external payable {
261          _executeModule(
262              Module.Market,
263              abi.encodeWithSelector(
264                  USDOMarketModule.removeAsset.selector,
265                  from,
266                  to,
267                  lzDstChainId,
268                  zroPaymentAddress,
269                  adapterParams,
270                  externalData,
271                  removeAndRepayData,
272                  approvals
273              ),
274              false
275          );
276      }
277  
278      /// @notice sends USDO to a specific chain and performs a leverage up operation
279      /// @param amount the amount to use
280      /// @param leverageFor the receiver address
281      /// @param lzData LZ specific data
282      /// @param swapData ISwapper specific data
283      /// @param externalData external contracts used for the flow
284      function sendForLeverage(
285          uint256 amount,
286          address leverageFor,
287          IUSDOBase.ILeverageLZData calldata lzData,
288          IUSDOBase.ILeverageSwapData calldata swapData,
289          IUSDOBase.ILeverageExternalContractsData calldata externalData
290      ) external payable {
291          _executeModule(
292              Module.Leverage,
293              abi.encodeWithSelector(
294                  USDOLeverageModule.sendForLeverage.selector,
295                  amount,
296                  leverageFor,
297                  lzData,
298                  swapData,
299                  externalData
300              ),
301              false
302          );
303      }
304  
305      /// @notice sends to YieldBox over layer and lends asset to market
306      /// @param _from sending address
307      /// @param _to receiver address
308      /// @param lzDstChainId LayerZero destination chain id
309      /// @param lendParams lend specific params
310      /// @param approvals approvals specific params
311      /// @param withdrawParams parameter to withdraw the SGL collateral
312      /// @param adapterParams adapter params of the withdrawn collateral
313      function sendAndLendOrRepay(
314          address _from,
315          address _to,
316          uint16 lzDstChainId,
317          address zroPaymentAddress,
318          IUSDOBase.ILendOrRepayParams calldata lendParams,
319          ICommonData.IApproval[] calldata approvals,
320          ICommonData.IWithdrawParams calldata withdrawParams,
321          bytes calldata adapterParams
322      ) external payable {
323          _executeModule(
324              Module.Market,
325              abi.encodeWithSelector(
326                  USDOMarketModule.sendAndLendOrRepay.selector,
327                  _from,
328                  _to,
329                  lzDstChainId,
330                  zroPaymentAddress,
331                  lendParams,
332                  approvals,
333                  withdrawParams,
334                  adapterParams
335              ),
336              false
337          );
338      }
339  
340      // ************************* //
341      // *** PRIVATE FUNCTIONS *** //
342      // ************************* //
343  
344      function _extractModule(Module _module) private view returns (address) {
345          address module;
346          if (_module == Module.Leverage) {
347              module = address(leverageModule);
348          } else if (_module == Module.Market) {
349              module = address(marketModule);
350          } else if (_module == Module.Options) {
351              module = address(optionsModule);
352          }
353  
354          if (module == address(0)) {
355              revert("USDO: module not found");
356          }
357  
358          return module;
359      }
360  
361      function _executeModule(
362          Module _module,
363          bytes memory _data,
364          bool _forwardRevert
365      ) private returns (bool success, bytes memory returnData) {
366          success = true;
367          address module = _extractModule(_module);
368  
369          (success, returnData) = module.delegatecall(_data);
370          if (!success && !_forwardRevert) {
371              revert(_getRevertMsg(returnData));
372          }
373      }
374  
375      function _executeOnDestination(
376          Module _module,
377          bytes memory _data,
378          uint16 _srcChainId,
379          bytes memory _srcAddress,
380          uint64 _nonce,
381          bytes memory _payload
382      ) private {
383          (bool success, bytes memory returnData) = _executeModule(
384              _module,
385              _data,
386              true
387          );
388          if (!success) {
389              _storeFailedMessage(
390                  _srcChainId,
391                  _srcAddress,
392                  _nonce,
393                  _payload,
394                  returnData
395              );
396          }
397      }
398  
399      function _nonblockingLzReceive(
400          uint16 _srcChainId,
401          bytes memory _srcAddress,
402          uint64 _nonce,
403          bytes memory _payload
404      ) internal virtual override {
405          uint256 packetType = _payload.toUint256(0);
406  
407          if (packetType == PT_YB_SEND_SGL_LEND_OR_REPAY) {
408              _executeOnDestination(
409                  Module.Market,
410                  abi.encodeWithSelector(
411                      USDOMarketModule.lend.selector,
412                      marketModule,
413                      _srcChainId,
414                      _srcAddress,
415                      _nonce,
416                      _payload
417                  ),
418                  _srcChainId,
419                  _srcAddress,
420                  _nonce,
421                  _payload
422              );
423          } else if (packetType == PT_LEVERAGE_MARKET_UP) {
424              _executeOnDestination(
425                  Module.Leverage,
426                  abi.encodeWithSelector(
427                      USDOLeverageModule.leverageUp.selector,
428                      leverageModule,
429                      _srcChainId,
430                      _srcAddress,
431                      _nonce,
432                      _payload
433                  ),
434                  _srcChainId,
435                  _srcAddress,
436                  _nonce,
437                  _payload
438              );
439          } else if (packetType == PT_MARKET_REMOVE_ASSET) {
440              _executeOnDestination(
441                  Module.Market,
442                  abi.encodeWithSelector(
443                      USDOMarketModule.remove.selector,
444                      _payload
445                  ),
446                  _srcChainId,
447                  _srcAddress,
448                  _nonce,
449                  _payload
450              );
451          } else if (packetType == PT_MARKET_MULTIHOP_BUY) {
452              _executeOnDestination(
453                  Module.Leverage,
454                  abi.encodeWithSelector(
455                      USDOLeverageModule.multiHop.selector,
456                      _payload
457                  ),
458                  _srcChainId,
459                  _srcAddress,
460                  _nonce,
461                  _payload
462              );
463          } else if (packetType == PT_TAP_EXERCISE) {
464              _executeOnDestination(
465                  Module.Options,
466                  abi.encodeWithSelector(
467                      USDOOptionsModule.exercise.selector,
468                      optionsModule,
469                      _srcChainId,
470                      _srcAddress,
471                      _nonce,
472                      _payload
473                  ),
474                  _srcChainId,
475                  _srcAddress,
476                  _nonce,
477                  _payload
478              );
479          } else if (packetType == PT_SEND_FROM) {
480              _executeOnDestination(
481                  Module.Options,
482                  abi.encodeWithSelector(
483                      USDOOptionsModule.sendFromDestination.selector,
484                      _payload
485                  ),
486                  _srcChainId,
487                  _srcAddress,
488                  _nonce,
489                  _payload
490              );
491          } else {
492              packetType = _payload.toUint8(0);
493              if (packetType == PT_SEND) {
494                  _sendAck(_srcChainId, _srcAddress, _nonce, _payload);
495              } else if (packetType == PT_SEND_AND_CALL) {
496                  _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);
497              } else {
498                  revert("OFTCoreV2: unknown packet type");
499              }
500          }
501      }
502: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L46-L502

File: contracts/Balancer.sol

34   contract Balancer is Owned {
35       // ************ //
36       // *** VARS *** //
37       // ************ //
38       /// @notice current OFT => chain => destination OFT
39       /// @dev chain ids (https://stargateprotocol.gitbook.io/stargate/developers/chain-ids):
40       ///         - Ethereum: 101
41       ///         - BNB: 102
42       ///         - Avalanche: 106
43       ///         - Polygon: 109
44       ///         - Arbitrum: 110
45       ///         - Optimism: 111
46       ///         - Fantom: 112
47       ///         - Metis: 151
48       ///     pool ids https://stargateprotocol.gitbook.io/stargate/developers/pool-ids
49       mapping(address => mapping(uint16 => OFTData)) public connectedOFTs;
50   
51       struct OFTData {
52           uint256 srcPoolId;
53           uint256 dstPoolId;
54           address dstOft;
55           uint256 rebalanceable;
56       }
57   
58       /// @notice StargetETH router address
59       IStargateRouter public immutable routerETH;
60       /// @notice Stargate router address
61       IStargateRouter public immutable router;
62   
63       uint256 private constant SLIPPAGE_PRECISION = 1e5;
64   
65       // ************************ //
66       // *** EVENTS FUNCTIONS *** //
67       // ************************ //
68       /// @notice event emitted when mTapiocaOFT is initialized
69       event ConnectedChainUpdated(
70           address indexed _srcOft,
71           uint16 _dstChainId,
72           address indexed _dstOft
73       );
74       /// @notice event emitted when a rebalance operation is performed
75       /// @dev rebalancing means sending an amount of the underlying token to one of the connected chains
76       event Rebalanced(
77           address indexed _srcOft,
78           uint16 _dstChainId,
79           uint256 _slippage,
80           uint256 _amount,
81           bool _isNative
82       );
83       /// @notice event emitted when max rebalanceable amount is updated
84       event RebalanceAmountUpdated(
85           address _srcOft,
86           uint16 _dstChainId,
87           uint256 _amount,
88           uint256 _totalAmount
89       );
90   
91       // ************************ //
92       // *** ERRORS FUNCTIONS *** //
93       // ************************ //
94       /// @notice error thrown when IStargetRouter address is not valid
95       error RouterNotValid();
96       /// @notice error thrown when value exceeds balance
97       error ExceedsBalance();
98       /// @notice error thrown when chain destination is not valid
99       error DestinationNotValid();
100      /// @notice error thrown when dex slippage is not valid
101      error SlippageNotValid();
102      /// @notice error thrown when fee amount is not set
103      error FeeAmountNotSet();
104      error PoolInfoRequired();
105      error RebalanceAmountNotSet();
106      error DestinationOftNotValid();
107  
108      // *************************** //
109      // *** MODIFIERS FUNCTIONS *** //
110      // *************************** //
111      modifier onlyValidDestination(address _srcOft, uint16 _dstChainId) {
112          if (connectedOFTs[_srcOft][_dstChainId].dstOft == address(0))
113              revert DestinationNotValid();
114          _;
115      }
116  
117      modifier onlyValidSlippage(uint256 _slippage) {
118          if (_slippage >= 1e5) revert SlippageNotValid();
119          _;
120      }
121  
122      constructor(
123          address _routerETH,
124          address _router,
125          address _owner
126      ) Owned(_owner) {
127          if (_router == address(0)) revert RouterNotValid();
128          if (_routerETH == address(0)) revert RouterNotValid();
129          routerETH = IStargateRouter(_routerETH);
130          router = IStargateRouter(_router);
131      }
132  
133      // ************************ //
134      // *** PUBLIC FUNCTIONS *** //
135      // ************************ //
136  
137      function checker(
138          address payable _srcOft,
139          uint16 _dstChainId
140      ) external view returns (bool canExec, bytes memory execPayload) {
141          bytes memory ercData;
142          if (ITapiocaOFT(_srcOft).erc20() == address(0)) {
143              ercData = abi.encode(
144                  connectedOFTs[_srcOft][_dstChainId].srcPoolId,
145                  connectedOFTs[_srcOft][_dstChainId].dstPoolId
146              );
147          }
148  
149          canExec = connectedOFTs[_srcOft][_dstChainId].rebalanceable > 0;
150          execPayload = abi.encodeCall(
151              Balancer.rebalance,
152              (
153                  _srcOft,
154                  _dstChainId,
155                  1e3, //1% slippage
156                  connectedOFTs[_srcOft][_dstChainId].rebalanceable,
157                  ercData
158              )
159          );
160      }
161  
162      // *********************** //
163      // *** OWNER FUNCTIONS *** //
164      // *********************** //
165      /// @notice performs a rebalance operation
166      /// @dev callable only by the owner
167      /// @param _srcOft the source TOFT address
168      /// @param _dstChainId the destination LayerZero id
169      /// @param _slippage the destination LayerZero id
170      /// @param _amount the rebalanced amount
171      /// @param _ercData custom send data
172      function rebalance(
173          address payable _srcOft,
174          uint16 _dstChainId,
175          uint256 _slippage,
176          uint256 _amount,
177          bytes memory _ercData
178      )
179          external
180          payable
181          onlyOwner
182          onlyValidDestination(_srcOft, _dstChainId)
183          onlyValidSlippage(_slippage)
184      {
185          if (connectedOFTs[_srcOft][_dstChainId].rebalanceable < _amount)
186              revert RebalanceAmountNotSet();
187  
188          //check if OFT is still valid
189          if (
190              !_isValidOft(
191                  _srcOft,
192                  connectedOFTs[_srcOft][_dstChainId].dstOft,
193                  _dstChainId
194              )
195          ) revert DestinationOftNotValid();
196  
197          //extract
198          ITapiocaOFT(_srcOft).extractUnderlying(_amount);
199  
200          //send
201          bool _isNative = ITapiocaOFT(_srcOft).erc20() == address(0);
202          if (_isNative) {
203              if (msg.value <= _amount) revert FeeAmountNotSet();
204              _sendNative(_srcOft, _amount, _dstChainId, _slippage);
205          } else {
206              if (msg.value == 0) revert FeeAmountNotSet();
207              _sendToken(_srcOft, _amount, _dstChainId, _slippage, _ercData);
208          }
209  
210          connectedOFTs[_srcOft][_dstChainId].rebalanceable -= _amount;
211          emit Rebalanced(_srcOft, _dstChainId, _slippage, _amount, _isNative);
212      }
213  
214      /// @notice registeres mTapiocaOFT for rebalancing
215      /// @param _srcOft the source TOFT address
216      /// @param _dstChainId the destination LayerZero id
217      /// @param _dstOft the destination TOFT address
218      /// @param _ercData custom send data
219      function initConnectedOFT(
220          address _srcOft,
221          uint16 _dstChainId,
222          address _dstOft,
223          bytes memory _ercData
224      ) external onlyOwner {
225          bool isNative = ITapiocaOFT(_srcOft).erc20() == address(0);
226          if (!isNative && _ercData.length == 0) revert PoolInfoRequired();
227          if (!_isValidOft(_srcOft, _dstOft, _dstChainId))
228              revert DestinationOftNotValid();
229  
230          (uint256 _srcPoolId, uint256 _dstPoolId) = abi.decode(
231              _ercData,
232              (uint256, uint256)
233          );
234  
235          OFTData memory oftData = OFTData({
236              srcPoolId: _srcPoolId,
237              dstPoolId: _dstPoolId,
238              dstOft: _dstOft,
239              rebalanceable: 0
240          });
241  
242          connectedOFTs[_srcOft][_dstChainId] = oftData;
243          emit ConnectedChainUpdated(_srcOft, _dstChainId, _dstOft);
244      }
245  
246      /// @notice assings more rebalanceable amount for TOFT
247      /// @param _srcOft the source TOFT address
248      /// @param _dstChainId the destination LayerZero id
249      /// @param _amount the rebalanced amount
250      function addRebalanceAmount(
251          address _srcOft,
252          uint16 _dstChainId,
253          uint256 _amount
254      ) external onlyValidDestination(_srcOft, _dstChainId) onlyOwner {
255          connectedOFTs[_srcOft][_dstChainId].rebalanceable += _amount;
256          emit RebalanceAmountUpdated(
257              _srcOft,
258              _dstChainId,
259              _amount,
260              connectedOFTs[_srcOft][_dstChainId].rebalanceable
261          );
262      }
263  
264      // ************************* //
265      // *** PRIVATE FUNCTIONS *** //
266      // ************************* //
267      function _isValidOft(
268          address _srcOft,
269          address _dstOft,
270          uint16 _dstChainId
271      ) private view returns (bool) {
272          bytes memory trustedRemotePath = abi.encodePacked(_dstOft, _srcOft);
273          return
274              ITapiocaOFT(_srcOft).isTrustedRemote(
275                  _dstChainId,
276                  trustedRemotePath
277              );
278      }
279  
280      function _sendNative(
281          address payable _oft,
282          uint256 _amount,
283          uint16 _dstChainId,
284          uint256 _slippage
285      ) private {
286          if (address(this).balance < _amount) revert ExceedsBalance();
287  
288          routerETH.swapETH(
289              _dstChainId,
290              _oft, //refund
291              abi.encodePacked(connectedOFTs[_oft][_dstChainId].dstOft),
292              _amount,
293              _computeMinAmount(_amount, _slippage)
294          );
295      }
296  
297      function _sendToken(
298          address payable _oft,
299          uint256 _amount,
300          uint16 _dstChainId,
301          uint256 _slippage,
302          bytes memory _data
303      ) private {
304          IERC20Metadata erc20 = IERC20Metadata(ITapiocaOFT(_oft).erc20());
305          if (erc20.balanceOf(address(this)) < _amount) revert ExceedsBalance();
306  
307          (uint256 _srcPoolId, uint256 _dstPoolId) = abi.decode(
308              _data,
309              (uint256, uint256)
310          );
311  
312          IStargateRouter.lzTxObj memory _lzTxParams = IStargateRouterBase
313              .lzTxObj({
314                  dstGasForCall: 0,
315                  dstNativeAmount: msg.value,
316                  dstNativeAddr: abi.encode(
317                      connectedOFTs[_oft][_dstChainId].dstOft
318                  )
319              });
320  
321          erc20.approve(address(router), _amount);
322          router.swap(
323              _dstChainId,
324              _srcPoolId,
325              _dstPoolId,
326              _oft, //refund,
327              _amount,
328              _computeMinAmount(_amount, _slippage),
329              _lzTxParams,
330              _lzTxParams.dstNativeAddr,
331              "0x"
332          );
333      }
334  
335      function _computeMinAmount(
336          uint256 _amount,
337          uint256 _slippage
338      ) private pure returns (uint256) {
339          return _amount - ((_amount * _slippage) / SLIPPAGE_PRECISION);
340      }
341  
342      receive() external payable {}
343: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L34-L343

File: contracts/TapiocaWrapper.sol

26   contract TapiocaWrapper is Ownable {
27       struct ExecutionCall {
28           address toft;
29           bytes bytecode;
30           bool revertOnFailure;
31       }
32   
33       // ************ //
34       // *** VARS *** //
35       // ************ //
36       /// @notice Array of deployed TOFT contracts.
37       ITapiocaOFT[] public tapiocaOFTs;
38       /// @notice Array of harvestable TOFT fees.
39       ITapiocaOFT[] private harvestableTapiocaOFTs;
40       /// @notice Map of deployed TOFT contracts by ERC20.
41       mapping(address => ITapiocaOFT) public tapiocaOFTsByErc20;
42   
43       // ************** //
44       // *** EVENTS *** //
45       // ************** //
46       /// @notice Called when a new OFT is deployed.
47       event CreateOFT(ITapiocaOFT indexed _tapiocaOFT, address indexed _erc20);
48       /// @notice Called when fees are harvested.
49       event HarvestFees(address indexed _caller);
50       /// @notice Called when fees are changed.
51       event SetFees(uint256 _newFee);
52   
53       // ************** //
54       // *** ERRORS *** //
55       // ************** //
56       /// @notice If the TOFT is already deployed.
57       error TapiocaWrapper__AlreadyDeployed(address _erc20);
58       /// @notice Failed to deploy the TapiocaWrapper contract.
59       error TapiocaWrapper__FailedDeploy();
60       /// @notice The management fee is too high. Currently set to a max of 50 BPS or 0.5%.
61       error TapiocaWrapper__MngmtFeeTooHigh();
62       /// @notice The TapiocaOFT execution failed.
63       error TapiocaWrapper__TOFTExecutionFailed(bytes message);
64       /// @notice No TOFT has been deployed yet.
65       error TapiocaWrapper__NoTOFTDeployed();
66   
67       constructor(address _owner) {
68           _transferOwnership(_owner);
69       }
70   
71       // ********************** //
72       // *** VIEW FUNCTIONS *** //
73       // ********************** //
74       /// @notice Return the number of TOFT contracts deployed on the current chain.
75       function tapiocaOFTLength() external view returns (uint256) {
76           return tapiocaOFTs.length;
77       }
78   
79       /// @notice Return the number of harvestable TOFT contracts deployed on the current chain.
80       function harvestableTapiocaOFTsLength() external view returns (uint256) {
81           return harvestableTapiocaOFTs.length;
82       }
83   
84       /// @notice Return the latest TOFT contract deployed on the current chain.
85       function lastTOFT() external view returns (ITapiocaOFT) {
86           if (tapiocaOFTs.length == 0) {
87               revert TapiocaWrapper__NoTOFTDeployed();
88           }
89           return tapiocaOFTs[tapiocaOFTs.length - 1];
90       }
91   
92       // ************************ //
93       // *** PUBLIC FUNCTIONS *** //
94       // ************************ //
95   
96       /// @notice Harvest fees from all the deployed TOFT contracts. Fees are transferred to the owner.
97       function harvestFees() external {
98           for (uint256 i = 0; i < harvestableTapiocaOFTs.length; i++) {
99               harvestableTapiocaOFTs[i].harvestFees();
100          }
101          emit HarvestFees(msg.sender);
102      }
103  
104      // *********************** //
105      // *** OWNER FUNCTIONS *** //
106      // *********************** //
107  
108      /// @notice Execute the `_bytecode` against the `_toft`. Callable only by the owner.
109      /// @dev Used to call derived OFT functions to a TOFT contract.
110      /// @param _toft The TOFT contract to execute against.
111      /// @param _bytecode The executable bytecode of the TOFT contract.
112      /// @param _revertOnFailure Whether to revert on failure.
113      /// @return success If the execution was successful.
114      /// @return result The error message if the execution failed.
115      function executeTOFT(
116          address _toft,
117          bytes calldata _bytecode,
118          bool _revertOnFailure
119      ) external payable onlyOwner returns (bool success, bytes memory result) {
120          (success, result) = payable(_toft).call{value: msg.value}(_bytecode);
121          if (_revertOnFailure && !success) {
122              revert TapiocaWrapper__TOFTExecutionFailed(result);
123          }
124      }
125  
126      /// @notice Execute the `_bytecode` against the `_toft`. Callable only by the owner.
127      /// @dev Used to call derived OFT functions to a TOFT contract.
128      /// @param _call The array calls to do.
129      /// @return success If the execution was successful.
130      /// @return results The message of the execution, could be an error message.
131      function executeCalls(
132          ExecutionCall[] calldata _call
133      )
134          external
135          payable
136          onlyOwner
137          returns (bool success, bytes[] memory results)
138      {
139          results = new bytes[](_call.length);
140          for (uint256 i = 0; i < _call.length; i++) {
141              (success, results[i]) = payable(_call[i].toft).call{
142                  value: msg.value
143              }(_call[i].bytecode);
144              if (_call[i].revertOnFailure && !success) {
145                  revert TapiocaWrapper__TOFTExecutionFailed(results[i]);
146              }
147          }
148      }
149  
150      /// @notice Deploy a new TOFT contract. Callable only by the owner.
151      /// @param _erc20 The ERC20 to wrap.
152      /// @param _bytecode The executable bytecode of the TOFT contract.
153      /// @param _salt Create2 salt.
154      function createTOFT(
155          address _erc20,
156          bytes calldata _bytecode,
157          bytes32 _salt,
158          bool _linked
159      ) external onlyOwner {
160          if (address(tapiocaOFTsByErc20[_erc20]) != address(0x0)) {
161              revert TapiocaWrapper__AlreadyDeployed(_erc20);
162          }
163  
164          ITapiocaOFT iOFT = ITapiocaOFT(
165              _createTOFT(_erc20, _bytecode, _salt, _linked)
166          );
167          if (address(iOFT.erc20()) != _erc20) {
168              revert TapiocaWrapper__FailedDeploy();
169          }
170  
171          tapiocaOFTs.push(iOFT);
172          tapiocaOFTsByErc20[_erc20] = iOFT;
173  
174          if (iOFT.hostChainID() == block.chainid) {
175              harvestableTapiocaOFTs.push(iOFT);
176          }
177          emit CreateOFT(iOFT, _erc20);
178      }
179  
180      // ************************* //
181      // *** PRIVATE FUNCTIONS *** //
182      // ************************* //
183      function _createTOFT(
184          address _erc20,
185          bytes calldata _bytecode,
186          bytes32 _salt,
187          bool _linked
188      ) private returns (address) {
189          address oft;
190          if (!_linked) {
191              TapiocaOFT toft = TapiocaOFT(
192                  payable(
193                      Create2.deploy(
194                          0,
195                          keccak256(
196                              abi.encodePacked(
197                                  keccak256(_bytecode),
198                                  address(this),
199                                  _erc20,
200                                  _salt
201                              )
202                          ),
203                          _bytecode
204                      )
205                  )
206              );
207              oft = address(toft);
208          } else {
209              mTapiocaOFT toft = mTapiocaOFT(
210                  payable(
211                      Create2.deploy(
212                          0,
213                          keccak256(
214                              abi.encodePacked(
215                                  keccak256(_bytecode),
216                                  address(this),
217                                  _erc20,
218                                  _salt
219                              )
220                          ),
221                          _bytecode
222                      )
223                  )
224              );
225              oft = address(toft);
226          }
227          return oft;
228      }
229: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L26-L229

File: contracts/tOFT/mTapiocaOFT.sol

9    contract mTapiocaOFT is BaseTOFT {
10       using SafeERC20 for IERC20;
11   
12       // ************ //
13       // *** VARS *** //
14       // ************ //
15   
16       /// @notice allowed chains where you can unwrap your TOFT
17       mapping(uint256 => bool) public connectedChains;
18   
19       /// @notice map of approved balancers
20       /// @dev a balancer can extract the underlying
21       mapping(address => bool) public balancers;
22   
23       // ************** //
24       // *** EVENTS *** //
25       // ************** //
26       /// @notice event emitted when a connected chain is reigstered or unregistered
27       event ConnectedChainStatusUpdated(uint256 _chain, bool _old, bool _new);
28       /// @notice event emitted when balancer status is updated
29       event BalancerStatusUpdated(
30           address indexed _balancer,
31           bool _bool,
32           bool _new
33       );
34       /// @notice event emitted when rebalancing is performed
35       event Rebalancing(
36           address indexed _balancer,
37           uint256 _amount,
38           bool _isNative
39       );
40   
41       /// @notice creates a new mTapiocaOFT
42       /// @param _lzEndpoint LayerZero endpoint address
43       /// @param _erc20 true the underlying ERC20 address
44       /// @param _yieldBox the YieldBox address
45       /// @param _name the TOFT name
46       /// @param _symbol the TOFT symbol
47       /// @param _decimal the TOFT decimal
48       /// @param _hostChainID the TOFT host chain LayerZero id
49       constructor(
50           address _lzEndpoint,
51           address _erc20,
52           IYieldBoxBase _yieldBox,
53           string memory _name,
54           string memory _symbol,
55           uint8 _decimal,
56           uint256 _hostChainID,
57           address payable _leverageModule,
58           address payable _strategyModule,
59           address payable _marketModule,
60           address payable _optionsModule
61       )
62           BaseTOFT(
63               _lzEndpoint,
64               _erc20,
65               _yieldBox,
66               _name,
67               _symbol,
68               _decimal,
69               _hostChainID,
70               _leverageModule,
71               _strategyModule,
72               _marketModule,
73               _optionsModule
74           )
75       {
76           if (block.chainid == _hostChainID) {
77               connectedChains[_hostChainID] = true;
78           }
79       }
80   
81       // ************************ //
82       // *** PUBLIC FUNCTIONS *** //
83       // ************************ //
84       /// @notice Wrap an ERC20 with a 1:1 ratio with a fee if existing.
85       /// @dev Since it can be executed only on the main chain, if an address exists on the OP chain it will not allowed to wrap.
86       /// @param _toAddress The address to wrap the ERC20 to.
87       /// @param _amount The amount of ERC20 to wrap.
88       function wrap(
89           address _fromAddress,
90           address _toAddress,
91           uint256 _amount
92       ) external payable onlyHostChain {
93           require(!balancers[msg.sender], "TOFT_auth");
94           if (erc20 == address(0)) {
95               _wrapNative(_toAddress);
96           } else {
97               _wrap(_fromAddress, _toAddress, _amount);
98           }
99       }
100  
101      /// @notice Unwrap an ERC20/Native with a 1:1 ratio. Called only on host chain.
102      /// @param _toAddress The address to unwrap the tokens to.
103      /// @param _amount The amount of tokens to unwrap.
104      function unwrap(address _toAddress, uint256 _amount) external {
105          require(connectedChains[block.chainid], "TOFT_host");
106          require(!balancers[msg.sender], "TOFT_auth");
107          _unwrap(_toAddress, _amount);
108      }
109  
110      // *********************** //
111      // *** OWNER FUNCTIONS *** //
112      // *********************** //
113      /// @notice updates a connected chain whitelist status
114      /// @param _chain the block.chainid of that specific chain
115      /// @param _status the new whitelist status
116      function updateConnectedChain(
117          uint256 _chain,
118          bool _status
119      ) external onlyOwner {
120          emit ConnectedChainStatusUpdated(
121              _chain,
122              connectedChains[_chain],
123              _status
124          );
125          connectedChains[_chain] = _status;
126      }
127  
128      /// @notice updates a Balancer whitelist status
129      /// @param _balancer the operator address
130      /// @param _status the new whitelist status
131      function updateBalancerState(
132          address _balancer,
133          bool _status
134      ) external onlyOwner {
135          emit BalancerStatusUpdated(_balancer, balancers[_balancer], _status);
136          balancers[_balancer] = _status;
137      }
138  
139      /// @notice extracts the underlying token/native for rebalancing
140      /// @param _amount the amount used for rebalancing
141      function extractUnderlying(uint256 _amount) external {
142          require(balancers[msg.sender], "TOFT_auth");
143  
144          bool _isNative = erc20 == address(0);
145          if (_isNative) {
146              _safeTransferETH(msg.sender, _amount);
147          } else {
148              IERC20(erc20).safeTransfer(msg.sender, _amount);
149          }
150  
151          emit Rebalancing(msg.sender, _amount, _isNative);
152      }
153: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L9-L153

File: contracts/Vesting.sol

10   contract Vesting is BoringOwnable, ReentrancyGuard {
11       using SafeERC20 for IERC20;
12   
13       // ************ //
14       // *** VARS *** //
15       // ************ //
16       /// @notice the vested token
17       IERC20 public token;
18   
19       /// @notice returns the start time for vesting
20       uint256 public start;
21   
22       /// @notice returns the cliff period
23       uint256 public cliff;
24   
25       /// @notice returns total vesting duration
26       uint256 public duration;
27   
28       /// @notice returns total available tokens
29       uint256 public seeded = 0;
30   
31       /// @notice user vesting data
32       struct UserData {
33           uint256 amount;
34           uint256 claimed;
35           uint256 latestClaimTimestamp;
36           bool revoked;
37       }
38       mapping(address => UserData) public users;
39   
40       uint256 private _totalAmount;
41       uint256 private _totalClaimed;
42   
43       // ************** //
44       // *** ERRORS *** //
45       // ************** //
46       error NotStarted();
47       error NothingToClaim();
48       error Initialized();
49       error AddressNotValid();
50       error AmountNotValid();
51       error AlreadyRegistered();
52       error NoTokens();
53       error NotEnough();
54       error BalanceTooLow();
55   
56       // *************** //
57       // *** EVENTS *** //
58       // ************** //
59       /// @notice event emitted when a new user is registered
60       event UserRegistered(address indexed user, uint256 amount);
61       /// @notice event emitted when someone claims available tokens
62       event Claimed(address indexed user, uint256 amount);
63   
64       /// @notice creates a new Vesting contract
65       /// @param _cliff cliff period
66       /// @param _duration vesting period
67       constructor(uint256 _cliff, uint256 _duration, address _owner) {
68           require(_duration > 0, "Vesting: no vesting");
69   
70           cliff = _cliff;
71           duration = _duration;
72           owner = _owner;
73       }
74   
75       // ********************** //
76       // *** VIEW FUNCTIONS *** //
77       // ********************** //
78       /// @notice returns total claimable
79       function claimable() external view returns (uint256) {
80           return _vested(seeded) - _totalClaimed;
81       }
82   
83       /// @notice returns total claimable for user
84       /// @param _user the user address
85       function claimable(address _user) public view returns (uint256) {
86           return _vested(users[_user].amount) - users[_user].claimed;
87       }
88   
89       /// @notice returns total vested amount
90       function vested() external view returns (uint256) {
91           return _vested(seeded);
92       }
93   
94       /// @notice returns total vested amount for user
95       /// @param _user the user address
96       function vested(address _user) external view returns (uint256) {
97           return _vested(users[_user].amount);
98       }
99   
100      /// @notice returns total claimed
101      function totalClaimed() external view returns (uint256) {
102          return _totalClaimed;
103      }
104  
105      // ************************ //
106      // *** PUBLIC FUNCTIONS *** //
107      // ************************ //
108      /// @notice claim available tokens
109      /// @dev claim works for msg.sender
110      function claim() external nonReentrant {
111          if (start == 0 || seeded == 0) revert NotStarted();
112          uint256 _claimable = claimable(msg.sender);
113          if (_claimable == 0) revert NothingToClaim();
114  
115          _totalClaimed += _claimable;
116          users[msg.sender].claimed += _claimable;
117          users[msg.sender].latestClaimTimestamp = block.timestamp;
118  
119          token.safeTransfer(msg.sender, _claimable);
120          emit Claimed(msg.sender, _claimable);
121      }
122  
123      // *********************** //
124      // *** OWNER FUNCTIONS *** //
125      // *********************** //
126      /// @notice adds a new user
127      /// @dev should be called before init
128      /// @param _user the user address
129      /// @param _amount user weight
130      function registerUser(address _user, uint256 _amount) external onlyOwner {
131          if (start > 0) revert Initialized();
132          if (_user == address(0)) revert AddressNotValid();
133          if (_amount == 0) revert AmountNotValid();
134          if (users[_user].amount > 0) revert AlreadyRegistered();
135  
136          UserData memory data;
137          data.amount = _amount;
138          data.claimed = 0;
139          data.revoked = false;
140          data.latestClaimTimestamp = 0;
141          users[_user] = data;
142  
143          _totalAmount += _amount;
144  
145          emit UserRegistered(_user, _amount);
146      }
147  
148      /// @notice inits the contract with total amount
149      /// @dev sets the start time to block.timestamp
150      /// @param _seededAmount total vested amount
151      function init(IERC20 _token, uint256 _seededAmount) external onlyOwner {
152          if (start > 0) revert Initialized();
153          if (_seededAmount == 0) revert NoTokens();
154          if (_totalAmount > _seededAmount) revert NotEnough();
155  
156          token = _token;
157          uint256 availableToken = _token.balanceOf(address(this));
158          if (availableToken < _seededAmount) revert BalanceTooLow();
159  
160          seeded = _seededAmount;
161          start = block.timestamp;
162      }
163  
164      // ************************* //
165      // *** PRIVATE FUNCTIONS *** //
166      // ************************* //
167      function _vested(uint256 _total) private view returns (uint256) {
168          if (start == 0) return 0;
169          uint256 total = _total;
170          if (block.timestamp < start + cliff) return 0;
171          if (block.timestamp >= start + duration) return total;
172          return (total * (block.timestamp - start)) / duration;
173      }
174: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L10-L174

File: contracts/governance/twTAP.sol

71   contract TwTAP is TWAML, ONFT721, ERC721Permit {
72       using SafeERC20 for IERC20;
73   
74       TapOFT public immutable tapOFT;
75   
76       /// ===== TWAML ======
77       TWAMLPool public twAML; // sglAssetId => twAMLPool
78   
79       mapping(uint256 => Participation) public participants; // tokenId => part.
80   
81       uint256 constant MIN_WEIGHT_FACTOR = 10; // In BPS, 0.1%
82       uint256 constant dMAX = 100 * 1e4; // 10% - 100% voting power multiplier
83       uint256 constant dMIN = 10 * 1e4;
84       uint256 public constant EPOCH_DURATION = 7 days;
85   
86       // If we assume 128 bit balances for the reward token -- which fit 1e40
87       // "tokens" at the most commonly used 1e18 precision -- then we can use the
88       // other 128 bits to store the tokens allotted to a single vote more
89       // accurately. Votes in turn are proportional to the amount of TAP locked,
90       // weighted by a multiplier. This number is at most 107 bits long (see
91       // definition of `Participation` struct).
92       // the weight ranges from 10-100% where 1% = 1e4, so 1 million (20 bits).
93       // the multiplier is at most 100% = 1M (20 bits), so votes is at most a
94       // 107-bit number.
95       uint256 constant DIST_PRECISION = 2 ** 128;
96   
97       IERC20[] public rewardTokens;
98       mapping(IERC20 => uint256) public rewardTokenIndex;
99       // tokenId -> rewardTokens index -> amount
100      mapping(uint256 => mapping(uint256 => uint256)) public claimed;
101  
102      // The current week is determined by creation, but there are values that
103      // need to be updated weekly. If, for any reason whatsoever, this cannot
104      // be done in time, the `lastProcessedWeek` will be behind until this is
105      // done.
106      uint256 public mintedTWTap;
107      uint256 public creation; // Week 0 starts here
108      uint256 public lastProcessedWeek;
109      mapping(uint256 => WeekTotals) public weekTotals;
110  
111      uint256 public immutable HOST_CHAIN_ID;
112      string private baseURI;
113  
114      /// =====-------======
115      constructor(
116          address payable _tapOFT,
117          address _owner,
118          address _layerZeroEndpoint,
119          uint256 _hostChainID,
120          uint256 _minGas
121      )
122          ONFT721("Time Weighted TAP", "twTAP", _minGas, _layerZeroEndpoint)
123          ERC721Permit("Time Weighted TAP")
124      {
125          tapOFT = TapOFT(_tapOFT);
126          transferOwnership(_owner);
127          creation = block.timestamp;
128          HOST_CHAIN_ID = _hostChainID;
129      }
130  
131      // ==========
132      //   EVENTS
133      // ==========
134      event Participate(
135          address indexed participant,
136          uint256 tapAmount,
137          uint256 multiplier
138      );
139      event AMLDivergence(
140          uint256 cumulative,
141          uint256 averageMagnitude,
142          uint256 totalParticipants
143      );
144      event ExitPosition(uint256 tokenId, uint256 amount);
145  
146      // ==========
147      //    READ
148      // ==========
149  
150      function currentWeek() public view returns (uint256) {
151          return (block.timestamp - creation) / EPOCH_DURATION;
152      }
153  
154      /// @notice Return the participation of a token. Returns 0 votes for expired tokens.
155      function getParticipation(
156          uint _tokenId
157      ) public view returns (Participation memory participant) {
158          participant = participants[_tokenId];
159          if (participant.expiry < block.timestamp) {
160              participant.multiplier = 0;
161          }
162          return participant;
163      }
164  
165      /// @notice Amount currently claimable for each reward token
166      function claimable(
167          uint256 _tokenId
168      ) public view returns (uint256[] memory) {
169          uint256 len = rewardTokens.length;
170          uint256[] memory result = new uint256[](len);
171  
172          Participation memory position = participants[_tokenId];
173          uint256 votes;
174          unchecked {
175              // Math is safe: Types fit
176              votes = uint256(position.tapAmount) * uint256(position.multiplier);
177          }
178  
179          if (votes == 0) {
180              return result;
181          }
182  
183          // If the "last processed week" is behind the actual week, rewards
184          // get processed as if it were earlier.
185          uint256 week = lastProcessedWeek;
186          if (week <= position.lastInactive) {
187              return result;
188          }
189          if (position.lastActive < week) {
190              week = position.lastActive;
191          }
192  
193          WeekTotals storage cur = weekTotals[week];
194          WeekTotals storage prev = weekTotals[position.lastInactive];
195  
196          for (uint256 i = 0; i < len; ) {
197              // Math is safe (but we do the checks anyway):
198              //
199              // -- The `totalDistPerVote[i]` values are increasing as a
200              //    function of weeks (see `advanceWeek()`), and if `week`
201              //    were not greater than `position.lastInactive`, this bit
202              //    of code would not be reached (see above). Therefore the
203              //    subtraction in the calculation of `net` cannot underflow.
204              //
205              // -- `votes * net` is at most the entire reward amount given
206              //    out, ever, in units of
207              //
208              //        (reward tokens) * DIST_PRECISION.
209              //
210              //    If this number were to exceed 256 bits, then
211              //    `distributeReward` would revert.
212              //
213              // -- `claimed[_tokenId][i]` is the sum of all (the i-th values
214              //    of) previous calls to the current function that were made
215              //    by `_claimRewards()`. Let there be n such calls, and let
216              //    r_j be `result[i]`, c_j be `claimed[_tokenId][i]`, and
217              //    net_j be `net` during that j-th call. Then, up to a
218              //    multiplication by votes / DIST_PRECISION:
219              //
220              //              c_1 = 0 <= net_1,
221              //
222              //    and, for n > 1:
223              //
224              //              c_n = r_(n-1) + r_(n-2) + ... + r_1
225              //                  = r_(n-1) + c_(n-1)
226              //                  = (net_(n-1) - c_(n-1) + c_(n-1)
227              //                  = net_(n-1)
228              //                  <= net_n,
229              //
230              //    so that the subtraction net_n - c_n does not underflow.
231              //    (The rounding the calculation favors the greater first
232              //    term).
233              //    (TODO: Word better?)
234              //
235              uint256 net = cur.totalDistPerVote[i] - prev.totalDistPerVote[i];
236              result[i] = ((votes * net) / DIST_PRECISION) - claimed[_tokenId][i];
237              unchecked {
238                  ++i;
239              }
240          }
241          return result;
242      }
243  
244      // ===========
245      //    WRITE
246      // ===========
247  
248      /// @notice Participate in twAMl voting and mint an oTAP position
249      /// @param _participant The address of the participant
250      /// @param _amount The amount of TAP to participate with
251      /// @param _duration The duration of the lock
252      function participate(
253          address _participant,
254          uint256 _amount,
255          uint256 _duration
256      ) external returns (uint256 tokenId) {
257          require(_duration >= EPOCH_DURATION, "twTAP: Lock not a week");
258  
259          // Transfer TAP to this contract
260          tapOFT.transferFrom(msg.sender, address(this), _amount);
261  
262          // Copy to memory
263          TWAMLPool memory pool = twAML;
264  
265          uint256 magnitude = computeMagnitude(_duration, pool.cumulative);
266          bool divergenceForce;
267          uint256 multiplier = computeTarget(
268              dMIN,
269              dMAX,
270              magnitude,
271              pool.cumulative
272          );
273  
274          // Calculate twAML voting weight
275          bool hasVotingPower = _amount >=
276              computeMinWeight(pool.totalDeposited, MIN_WEIGHT_FACTOR);
277          if (hasVotingPower) {
278              pool.totalParticipants++; // Save participation
279              pool.averageMagnitude =
280                  (pool.averageMagnitude + magnitude) /
281                  pool.totalParticipants; // compute new average magnitude
282  
283              // Compute and save new cumulative
284              divergenceForce = _duration > pool.cumulative;
285  
286              if (divergenceForce) {
287                  pool.cumulative += pool.averageMagnitude;
288              } else {
289                  // TODO: Strongly suspect this is never less. Prove it.
290                  if (pool.cumulative > pool.averageMagnitude) {
291                      pool.cumulative -= pool.averageMagnitude;
292                  } else {
293                      pool.cumulative = 0;
294                  }
295              }
296  
297              // Save new weight
298              pool.totalDeposited += _amount;
299  
300              twAML = pool; // Save twAML participation
301              emit AMLDivergence(
302                  pool.cumulative,
303                  pool.averageMagnitude,
304                  pool.totalParticipants
305              );
306          }
307  
308          // Mint twTAP position
309          tokenId = ++mintedTWTap;
310          _safeMint(_participant, tokenId);
311  
312          uint256 expiry = block.timestamp + _duration;
313          require(expiry < type(uint56).max, "twTAP: too long");
314          // Eligibility starts NEXT week, and lasts until the week that the lock
315          // expires. This is guaranteed to be at least one week later by the
316          // check on `_duration`.
317          // If a user locks right before the current week ends, and have a
318          // duration slightly over one week, straddling the two starting points,
319          // then that user is eligible for the rewards during both weeks; the
320          // price for this maneuver is a lower multiplier, and loss of voting
321          // power in the DAO after the lock expires.
322          uint256 w0 = currentWeek();
323          uint256 w1 = (expiry - creation) / EPOCH_DURATION;
324  
325          // Save twAML participation
326          // Casts are safe: see struct definition
327          uint256 votes = _amount * multiplier;
328          participants[tokenId] = Participation({
329              averageMagnitude: pool.averageMagnitude,
330              hasVotingPower: hasVotingPower,
331              divergenceForce: divergenceForce,
332              tapReleased: false,
333              expiry: uint56(expiry),
334              tapAmount: uint88(_amount),
335              multiplier: uint24(multiplier),
336              lastInactive: uint40(w0),
337              lastActive: uint40(w1)
338          });
339  
340          // w0 + 1 = lastInactive + 1 = first active
341          // w1 + 1 = lastActive + 1 = first inactive
342          // Cast is safe: `votes` is the product of a uint88 and a uint24
343          weekTotals[w0 + 1].netActiveVotes += int256(votes);
344          weekTotals[w1 + 1].netActiveVotes -= int256(votes);
345  
346          emit Participate(_participant, _amount, multiplier);
347          // TODO: Mint event?
348      }
349  
350      /// @notice claims all rewards distributed since token mint or last claim.
351      /// @param _tokenId tokenId whose rewards to claim
352      /// @param _to address to receive the rewards
353      function claimRewards(uint256 _tokenId, address _to) external {
354          _requireClaimPermission(_to, _tokenId);
355          _claimRewards(_tokenId, _to);
356      }
357  
358      /// @notice claims all rewards distributed since token mint or last claim, and send them to another chain.
359      /// @param _tokenId The tokenId of the twTAP position
360      /// @param _rewardTokens The address of the reward token
361      function claimAndSendRewards(
362          uint256 _tokenId,
363          IERC20[] memory _rewardTokens
364      ) external {
365          require(msg.sender == address(tapOFT), "twTAP: only tapOFT");
366          _claimRewardsOn(_tokenId, address(tapOFT), _rewardTokens);
367      }
368  
369      /// @notice claims the TAP locked in a position whose votes have expired,
370      /// @notice and undoes the effect on the twAML calculations.
371      /// @param _tokenId tokenId whose locked TAP to claim
372      /// @param _to address to receive the TAP
373      function releaseTap(uint256 _tokenId, address _to) external {
374          _requireClaimPermission(_to, _tokenId);
375          _releaseTap(_tokenId, _to);
376      }
377  
378      /// @notice Exit a twAML participation and delete the voting power if existing
379      /// @param _tokenId The tokenId of the twTAP position
380      function exitPosition(uint256 _tokenId) external {
381          address to = ownerOf(_tokenId);
382          _releaseTap(_tokenId, to);
383      }
384  
385      /// @notice Exit a twAML participation and send the withdrawn TAP to tapOFT to send it to another chain.
386      /// @param _tokenId The tokenId of the twTAP position
387      function exitPositionAndSendTap(
388          uint256 _tokenId
389      ) external returns (uint256) {
390          require(msg.sender == address(tapOFT), "twTAP: only tapOFT");
391          return _releaseTap(_tokenId, address(tapOFT));
392      }
393  
394      /// @notice Indicate that (a) week(s) have passed and update running totals
395      /// @notice Reverts if called in week 0. Let it.
396      /// @param _limit Maximum number of weeks to process in one call
397      function advanceWeek(uint256 _limit) public {
398          // TODO: Make whole function unchecked
399          uint256 cur = currentWeek();
400          uint256 week = lastProcessedWeek;
401          uint256 goal = cur;
402          unchecked {
403              if (goal - week > _limit) {
404                  goal = week + _limit;
405              }
406          }
407          uint256 len = rewardTokens.length;
408          while (week < goal) {
409              WeekTotals storage prev = weekTotals[week];
410              WeekTotals storage next = weekTotals[++week];
411              // TODO: Prove that math is safe
412              next.netActiveVotes += prev.netActiveVotes;
413              for (uint256 i = 0; i < len; ) {
414                  next.totalDistPerVote[i] += prev.totalDistPerVote[i];
415                  unchecked {
416                      ++i;
417                  }
418              }
419          }
420          lastProcessedWeek = goal;
421      }
422  
423      /// @notice distributes a reward among all tokens, weighted by voting power
424      /// @notice The reward gets allocated to all positions that have locked in
425      /// @notice the current week. Fails, intentionally, if this number is zero.
426      /// @notice Total rewards cannot exceed 2^128 tokens.
427      /// @param _rewardTokenId index of the reward in `rewardTokens`
428      /// @param _amount amount of reward token to distribute.
429      function distributeReward(
430          uint256 _rewardTokenId,
431          uint256 _amount
432      ) external {
433          require(
434              lastProcessedWeek == currentWeek(),
435              "twTAP: Advance week first"
436          );
437          WeekTotals storage totals = weekTotals[lastProcessedWeek];
438          IERC20 rewardToken = rewardTokens[_rewardTokenId];
439          // If this is a DBZ then there are no positions to give the reward to.
440          // Since reward eligibility starts in the week after locking, there is
441          // no way to give out rewards THIS week.
442          // Cast is safe: `netActiveVotes` is at most zero by construction of
443          // weekly totals and the requirement that they are up to date.
444          // TODO: Word this better
445          totals.totalDistPerVote[_rewardTokenId] +=
446              (_amount * DIST_PRECISION) /
447              uint256(totals.netActiveVotes);
448          rewardToken.safeTransferFrom(msg.sender, address(this), _amount);
449      }
450  
451      // =========
452      //   OWNER
453      // =========
454  
455      function addRewardToken(IERC20 token) external onlyOwner returns (uint256) {
456          uint256 i = rewardTokens.length;
457          rewardTokens.push(token);
458          rewardTokenIndex[token] = i;
459          return i;
460      }
461  
462      // ============
463      //   INTERNAL
464      // ============
465  
466      /// @dev Mirrors the implementation of _isApprovedOrOwner, with the modification
467      /// that it is allowed if `_to` is the owner:
468      function _requireClaimPermission(
469          address _to,
470          uint256 _tokenId
471      ) internal view {
472          address tokenOwner = ownerOf(_tokenId);
473          require(
474              msg.sender == tokenOwner ||
475                  _to == tokenOwner ||
476                  isApprovedForAll(tokenOwner, msg.sender) ||
477                  getApproved(_tokenId) == msg.sender,
478              "twTAP: cannot claim"
479          );
480      }
481  
482      /// @dev Claim all rewards on a position and send them to `_to`.
483      function _claimRewards(uint256 _tokenId, address _to) internal {
484          uint256[] memory amounts = claimable(_tokenId);
485          uint256 len = amounts.length;
486          unchecked {
487              for (uint256 i = 0; i < len; ++i) {
488                  uint256 amount = amounts[i];
489                  if (amount > 0) {
490                      // Math is safe: `amount` calculated safely in `claimable()`
491                      claimed[_tokenId][i] += amount;
492                      rewardTokens[i].safeTransfer(_to, amount);
493                  }
494              }
495          }
496      }
497  
498      /// @dev Claim rewards of a specific token on a position and send them to `_to`.
499      function _claimRewardsOn(
500          uint256 _tokenId,
501          address _to,
502          IERC20[] memory _rewardTokens
503      ) internal {
504          uint256[] memory amounts = claimable(_tokenId);
505          unchecked {
506              uint256 len = _rewardTokens.length;
507              for (uint256 i = 0; i < len; ) {
508                  uint256 claimableIndex = rewardTokenIndex[_rewardTokens[i]];
509                  uint256 amount = amounts[i];
510  
511                  if (amount > 0) {
512                      // Math is safe: `amount` calculated safely in `claimable()`
513                      claimed[_tokenId][claimableIndex] += amount;
514                      rewardTokens[claimableIndex].safeTransfer(_to, amount);
515                  }
516                  ++i;
517              }
518          }
519      }
520  
521      /// @dev Release the tap of a position and send it to `_to`. Remove the user from twAML.
522      function _releaseTap(
523          uint256 _tokenId,
524          address _to
525      ) internal returns (uint256 releasedAmount) {
526          Participation memory position = participants[_tokenId];
527          if (position.tapReleased) {
528              return 0;
529          }
530          require(position.expiry <= block.timestamp, "twTAP: Lock not expired");
531  
532          releasedAmount = position.tapAmount;
533  
534          // Remove participation
535          if (position.hasVotingPower) {
536              TWAMLPool memory pool = twAML;
537              pool.totalParticipants--;
538  
539              // Inverse of the participation. The participation entry tracks
540              // the average magnitude as it was at the time the participant
541              // entered. When going the other way around, this value matches the
542              // one in the pool, but here it does not.
543              if (position.divergenceForce) {
544                  if (pool.cumulative > position.averageMagnitude) {
545                      pool.cumulative -= position.averageMagnitude;
546                  } else {
547                      pool.cumulative = 0;
548                  }
549              } else {
550                  pool.cumulative += position.averageMagnitude;
551              }
552  
553              // Save new weight
554              pool.totalDeposited -= position.tapAmount;
555  
556              twAML = pool; // Save twAML exit
557              emit AMLDivergence(
558                  pool.cumulative,
559                  pool.averageMagnitude,
560                  pool.totalParticipants
561              ); // Register new voting power event
562          }
563  
564          participants[_tokenId].tapReleased = true;
565          tapOFT.transfer(_to, releasedAmount);
566  
567          emit ExitPosition(_tokenId, releasedAmount);
568      }
569  
570      /// @dev Returns the chain ID of the current network
571      function _getChainId() internal view virtual returns (uint256) {
572          uint256 chainId;
573          assembly {
574              chainId := chainid()
575          }
576          return chainId;
577      }
578  
579      /**
580       * @dev See {IERC165-supportsInterface}.
581       */
582      function supportsInterface(
583          bytes4 interfaceId
584      ) public view virtual override(ONFT721, ERC721) returns (bool) {
585          return super.supportsInterface(interfaceId);
586      }
587: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L71-L587

File: contracts/option-airdrop/AirdropBroker.sol

43   contract AirdropBroker is Pausable, BoringOwnable, FullMath {
44       bytes public tapOracleData;
45       TapOFT public immutable tapOFT;
46       AOTAP public immutable aoTAP;
47       IOracle public tapOracle;
48       IERC721 public immutable PCNFT;
49   
50       uint128 public epochTAPValuation; // TAP price for the current epoch
51       uint64 public lastEpochUpdate; // timestamp of the last epoch update
52       uint64 public epoch; // Represents the number of weeks since the start of the contract
53   
54       mapping(ERC20 => PaymentTokenOracle) public paymentTokens; // Token address => PaymentTokenOracle
55       address public paymentTokenBeneficiary; // Where to collect the payment tokens
56   
57       mapping(uint256 => mapping(uint256 => uint256)) public aoTAPCalls; // oTAPTokenID => epoch => amountExercised
58   
59       /// @notice Record of participation in phase 2 airdrop
60       /// Only applicable for phase 2. To get subphases on phase 2 we do userParticipation[_user][20+roles]
61       mapping(address => mapping(uint256 => bool)) public userParticipation; // user address => phase => participated
62   
63       /// =====-------======
64       ///      Phase 1
65       /// =====-------======
66   
67       /// @notice user address => eligible TAP amount, 0 means no eligibility
68       mapping(address => uint256) public phase1Users;
69       uint256 public constant PHASE_1_DISCOUNT = 50 * 1e4; // 50%
70   
71       /// =====-------======
72       ///      Phase 2
73       /// =====-------======
74   
75       // [OG Pearls, Sushi Frens, Tapiocans, Oysters, Cassava]
76       bytes32[4] public phase2MerkleRoots; // merkle root of phase 2 airdrop
77       uint8[4] public PHASE_2_AMOUNT_PER_USER = [200, 190, 200, 190];
78       uint8[4] public PHASE_2_DISCOUNT_PER_USER = [50, 40, 40, 33];
79   
80       /// =====-------======
81       ///      Phase 3
82       /// =====-------======
83   
84       uint256 public constant PHASE_3_AMOUNT_PER_USER = 714;
85       uint256 public constant PHASE_3_DISCOUNT = 50 * 1e4;
86   
87       /// =====-------======
88       ///      Phase 4
89       /// =====-------======
90   
91       /// @notice user address => eligible TAP amount, 0 means no eligibility
92       mapping(address => uint256) public phase4Users;
93       uint256 public constant PHASE_4_DISCOUNT = 33 * 1e4;
94   
95       uint256 public constant EPOCH_DURATION = 2 days;
96   
97       /// =====-------======
98       constructor(
99           address _aoTAP,
100          address payable _tapOFT,
101          address _pcnft,
102          address _paymentTokenBeneficiary,
103          address _owner
104      ) {
105          paymentTokenBeneficiary = _paymentTokenBeneficiary;
106          tapOFT = TapOFT(_tapOFT);
107          aoTAP = AOTAP(_aoTAP);
108          PCNFT = IERC721(_pcnft);
109          owner = _owner;
110      }
111  
112      // ==========
113      //   EVENTS
114      // ==========
115      event Participate(uint256 indexed epoch, uint256 aoTAPTokenID);
116      event ExerciseOption(
117          uint256 indexed epoch,
118          address indexed to,
119          ERC20 indexed paymentToken,
120          uint256 aoTapTokenID,
121          uint256 amount
122      );
123      event NewEpoch(uint256 indexed epoch, uint256 epochTAPValuation);
124  
125      event SetPaymentToken(ERC20 paymentToken, IOracle oracle, bytes oracleData);
126      event SetTapOracle(IOracle oracle, bytes oracleData);
127  
128      // ==========
129      //    READ
130      // ==========
131  
132      /// @notice Returns the details of an OTC deal for a given oTAP token ID and a payment token.
133      ///         The oracle uses the last peeked value, and not the latest one, so the payment amount may be different.
134      /// @param _aoTAPTokenID The aoTAP token ID
135      /// @param _paymentToken The payment token
136      /// @param _tapAmount The amount of TAP to be exchanged. If 0 it will use the full amount of TAP eligible for the deal
137      /// @return eligibleTapAmount The amount of TAP eligible for the deal
138      /// @return paymentTokenAmount The amount of payment tokens required for the deal
139      /// @return tapAmount The amount of TAP to be exchanged
140  
141      function getOTCDealDetails(
142          uint256 _aoTAPTokenID,
143          ERC20 _paymentToken,
144          uint256 _tapAmount
145      )
146          external
147          view
148          returns (
149              uint256 eligibleTapAmount,
150              uint256 paymentTokenAmount,
151              uint256 tapAmount
152          )
153      {
154          // Load data
155          (, AirdropTapOption memory aoTapOption) = aoTAP.attributes(
156              _aoTAPTokenID
157          );
158          require(aoTapOption.expiry > block.timestamp, "adb: Option expired");
159  
160          uint256 cachedEpoch = epoch;
161  
162          PaymentTokenOracle memory paymentTokenOracle = paymentTokens[
163              _paymentToken
164          ];
165  
166          // Check requirements
167          require(
168              paymentTokenOracle.oracle != IOracle(address(0)),
169              "adb: Payment token not supported"
170          );
171  
172          eligibleTapAmount = aoTapOption.amount;
173          eligibleTapAmount -= aoTAPCalls[_aoTAPTokenID][cachedEpoch]; // Subtract already exercised amount
174          require(eligibleTapAmount >= _tapAmount, "adb: Too high");
175  
176          tapAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;
177          require(tapAmount >= 1e18, "adb: Too low");
178          // Get TAP valuation
179          uint256 otcAmountInUSD = tapAmount * epochTAPValuation; // Divided by TAP decimals
180          // Get payment token valuation
181          (, uint256 paymentTokenValuation) = paymentTokenOracle.oracle.peek(
182              paymentTokenOracle.oracleData
183          );
184          // Get payment token amount
185          paymentTokenAmount = _getDiscountedPaymentAmount(
186              otcAmountInUSD,
187              paymentTokenValuation,
188              aoTapOption.discount,
189              _paymentToken.decimals()
190          );
191      }
192  
193      // ===========
194      //    WRITE
195      // ===========
196  
197      /// @notice Participate in the airdrop
198      /// @param _data The data to be used for the participation, varies by phases
199      function participate(
200          bytes calldata _data
201      ) external returns (uint256 aoTAPTokenID) {
202          uint256 cachedEpoch = epoch;
203          require(cachedEpoch > 0, "adb: Airdrop not started");
204          require(cachedEpoch <= 4, "adb: Airdrop ended");
205  
206          // Phase 1
207          if (cachedEpoch == 1) {
208              aoTAPTokenID = _participatePhase1();
209          } else if (cachedEpoch == 2) {
210              aoTAPTokenID = _participatePhase2(_data); // _data = (uint256 role, bytes32[] _merkleProof)
211          } else if (cachedEpoch == 3) {
212              aoTAPTokenID = _participatePhase3(_data); // _data = (uint256 _tokenID)
213          } else if (cachedEpoch == 4) {
214              aoTAPTokenID = _participatePhase4();
215          }
216  
217          emit Participate(cachedEpoch, aoTAPTokenID);
218      }
219  
220      /// @notice Exercise an aoTAP position
221      /// @param _aoTAPTokenID tokenId of the aoTAP position, position must be active
222      /// @param _paymentToken Address of the payment token to use, must be whitelisted
223      /// @param _tapAmount Amount of TAP to exercise. If 0, the full amount is exercised
224      function exerciseOption(
225          uint256 _aoTAPTokenID,
226          ERC20 _paymentToken,
227          uint256 _tapAmount
228      ) external {
229          // Load data
230          (, AirdropTapOption memory aoTapOption) = aoTAP.attributes(
231              _aoTAPTokenID
232          );
233          require(aoTapOption.expiry > block.timestamp, "adb: Option expired");
234  
235          uint256 cachedEpoch = epoch;
236  
237          PaymentTokenOracle memory paymentTokenOracle = paymentTokens[
238              _paymentToken
239          ];
240  
241          // Check requirements
242          require(
243              paymentTokenOracle.oracle != IOracle(address(0)),
244              "adb: Payment token not supported"
245          );
246          require(
247              aoTAP.isApprovedOrOwner(msg.sender, _aoTAPTokenID),
248              "adb: Not approved or owner"
249          );
250  
251          // Get eligible OTC amount
252  
253          uint256 eligibleTapAmount = aoTapOption.amount;
254          eligibleTapAmount -= aoTAPCalls[_aoTAPTokenID][cachedEpoch]; // Subtract already exercised amount
255          require(eligibleTapAmount >= _tapAmount, "adb: Too high");
256  
257          uint256 chosenAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;
258          require(chosenAmount >= 1e18, "adb: Too low");
259          aoTAPCalls[_aoTAPTokenID][cachedEpoch] += chosenAmount; // Adds up exercised amount to current epoch
260  
261          // Finalize the deal
262          _processOTCDeal(
263              _paymentToken,
264              paymentTokenOracle,
265              chosenAmount,
266              aoTapOption.discount
267          );
268  
269          emit ExerciseOption(
270              cachedEpoch,
271              msg.sender,
272              _paymentToken,
273              _aoTAPTokenID,
274              chosenAmount
275          );
276      }
277  
278      /// @notice Start a new epoch, extract TAP from the TapOFT contract,
279      ///         emit it to the active singularities and get the price of TAP for the epoch.
280      function newEpoch() external {
281          require(
282              block.timestamp >= lastEpochUpdate + EPOCH_DURATION,
283              "adb: too soon"
284          );
285  
286          // Update epoch info
287          lastEpochUpdate = uint64(block.timestamp);
288          epoch++;
289  
290          // Get epoch TAP valuation
291          (, uint256 _epochTAPValuation) = tapOracle.get(tapOracleData);
292          epochTAPValuation = uint128(_epochTAPValuation);
293          emit NewEpoch(epoch, epochTAPValuation);
294      }
295  
296      /// @notice Claim the Broker role of the aoTAP contract
297      function aoTAPBrokerClaim() external {
298          aoTAP.brokerClaim();
299      }
300  
301      // =========
302      //   OWNER
303      // =========
304  
305      /// @notice Set the TapOFT Oracle address and data
306      /// @param _tapOracle The new TapOFT Oracle address
307      /// @param _tapOracleData The new TapOFT Oracle data
308      function setTapOracle(
309          IOracle _tapOracle,
310          bytes calldata _tapOracleData
311      ) external onlyOwner {
312          tapOracle = _tapOracle;
313          tapOracleData = _tapOracleData;
314  
315          emit SetTapOracle(_tapOracle, _tapOracleData);
316      }
317  
318      function setPhase2MerkleRoots(
319          bytes32[4] calldata _merkleRoots
320      ) external onlyOwner {
321          phase2MerkleRoots = _merkleRoots;
322      }
323  
324      function registerUserForPhase(
325          uint256 _phase,
326          address[] calldata _users,
327          uint256[] calldata _amounts
328      ) external onlyOwner {
329          require(_users.length == _amounts.length, "adb: invalid input");
330  
331          if (_phase == 1) {
332              for (uint256 i = 0; i < _users.length; i++) {
333                  phase1Users[_users[i]] = _amounts[i];
334              }
335          } else if (_phase == 4) {
336              for (uint256 i = 0; i < _users.length; i++) {
337                  phase4Users[_users[i]] = _amounts[i];
338              }
339          }
340      }
341  
342      /// @notice Activate or deactivate a payment token
343      /// @dev set the oracle to address(0) to deactivate, expect the same decimal precision as TAP oracle
344      function setPaymentToken(
345          ERC20 _paymentToken,
346          IOracle _oracle,
347          bytes calldata _oracleData
348      ) external onlyOwner {
349          paymentTokens[_paymentToken].oracle = _oracle;
350          paymentTokens[_paymentToken].oracleData = _oracleData;
351  
352          emit SetPaymentToken(_paymentToken, _oracle, _oracleData);
353      }
354  
355      /// @notice Set the payment token beneficiary
356      /// @param _paymentTokenBeneficiary The new payment token beneficiary
357      function setPaymentTokenBeneficiary(
358          address _paymentTokenBeneficiary
359      ) external onlyOwner {
360          paymentTokenBeneficiary = _paymentTokenBeneficiary;
361      }
362  
363      /// @notice Collect the payment tokens from the OTC deals
364      /// @param _paymentTokens The payment tokens to collect
365      function collectPaymentTokens(
366          address[] calldata _paymentTokens
367      ) external onlyOwner {
368          require(
369              paymentTokenBeneficiary != address(0),
370              "adb: Payment token beneficiary not set"
371          );
372          uint256 len = _paymentTokens.length;
373  
374          unchecked {
375              for (uint256 i = 0; i < len; ++i) {
376                  ERC20 paymentToken = ERC20(_paymentTokens[i]);
377                  paymentToken.transfer(
378                      paymentTokenBeneficiary,
379                      paymentToken.balanceOf(address(this))
380                  );
381              }
382          }
383      }
384  
385      // ============
386      //   INTERNAL
387      // ============
388  
389      /// @notice Participate in phase 1 of the Airdrop. LBP users are given aoTAP pro-rata.
390      function _participatePhase1() internal returns (uint256 oTAPTokenID) {
391          uint256 _eligibleAmount = phase1Users[msg.sender];
392          require(_eligibleAmount > 0, "adb: Not eligible");
393  
394          // Close eligibility
395          phase1Users[msg.sender] = 0;
396  
397          // Mint aoTAP
398          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch
399          oTAPTokenID = aoTAP.mint(
400              msg.sender,
401              expiry,
402              uint128(PHASE_1_DISCOUNT),
403              _eligibleAmount
404          );
405      }
406  
407      /// @notice Participate in phase 2 of the Airdrop. Guild members will receive pre-defined discounts and TAP, based on role.
408      /// @param _data The calldata. Needs to be the address of the user.
409      /// _data = (uint256 role, bytes32[] _merkleProof). Refer to {phase2MerkleRoots} for role.
410      function _participatePhase2(
411          bytes calldata _data
412      ) internal returns (uint256 oTAPTokenID) {
413          (uint256 _role, bytes32[] memory _merkleProof) = abi.decode(
414              _data,
415              (uint256, bytes32[])
416          );
417  
418          bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
419          require(
420              MerkleProof.verify(_merkleProof, phase2MerkleRoots[_role], leaf),
421              "adb: Not eligible"
422          );
423  
424          uint256 subPhase = 20 + _role;
425          require(
426              userParticipation[msg.sender][subPhase] == false,
427              "adb: Already participated"
428          );
429          // Close eligibility
430          userParticipation[msg.sender][subPhase] = true;
431  
432          // Mint aoTAP
433          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch
434          uint256 eligibleAmount = uint256(PHASE_2_AMOUNT_PER_USER[_role]) * 1e18;
435          uint128 discount = uint128(PHASE_2_DISCOUNT_PER_USER[_role]) * 1e4;
436          oTAPTokenID = aoTAP.mint(msg.sender, expiry, discount, eligibleAmount);
437      }
438  
439      /// @notice Participate in phase 1 of the Airdrop. PCNFT holder will receive pre-defined discount and TAP.
440      /// @param _data The calldata. Needs to be the address of the user.
441      /// _data = (uint256 _tokenID)
442      function _participatePhase3(
443          bytes calldata _data
444      ) internal returns (uint256 oTAPTokenID) {
445          uint256 _tokenID = abi.decode(_data, (uint256));
446  
447          require(PCNFT.ownerOf(_tokenID) == msg.sender, "adb: Not eligible");
448          address tokenIDToAddress = address(uint160(_tokenID));
449          require(
450              userParticipation[tokenIDToAddress][3] == false,
451              "adb: Already participated"
452          );
453          // Close eligibility
454          // To avoid a potential attack vector, we cast token ID to an address instead of using _to,
455          // no conflict possible, tokenID goes from 0 ... 714.
456          userParticipation[tokenIDToAddress][3] = true;
457  
458          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch
459          uint256 eligibleAmount = PHASE_3_AMOUNT_PER_USER;
460          uint128 discount = uint128(PHASE_3_DISCOUNT);
461          oTAPTokenID = aoTAP.mint(msg.sender, expiry, discount, eligibleAmount);
462      }
463  
464      /// @notice Participate in phase 4 of the Airdrop. twTAP and Cassava guild's role are given TAP pro-rata.
465      function _participatePhase4() internal returns (uint256 oTAPTokenID) {
466          uint256 _eligibleAmount = phase4Users[msg.sender];
467          require(_eligibleAmount > 0, "adb: Not eligible");
468  
469          // Close eligibility
470          phase4Users[msg.sender] = 0;
471  
472          // Mint aoTAP
473          uint128 expiry = uint128(lastEpochUpdate + EPOCH_DURATION); // Set expiry to the end of the epoch
474          oTAPTokenID = aoTAP.mint(
475              msg.sender,
476              expiry,
477              uint128(PHASE_4_DISCOUNT),
478              _eligibleAmount
479          );
480      }
481  
482      /// @notice Process the OTC deal, transfer the payment token to the broker and the TAP amount to the user
483      /// @param _paymentToken The payment token
484      /// @param _paymentTokenOracle The oracle of the payment token
485      /// @param tapAmount The amount of TAP that the user has to receive
486      /// @param discount The discount that the user has to apply to the OTC deal
487      function _processOTCDeal(
488          ERC20 _paymentToken,
489          PaymentTokenOracle memory _paymentTokenOracle,
490          uint256 tapAmount,
491          uint256 discount
492      ) internal {
493          // Get TAP valuation
494          uint256 otcAmountInUSD = tapAmount * epochTAPValuation;
495  
496          // Get payment token valuation
497          (, uint256 paymentTokenValuation) = _paymentTokenOracle.oracle.get(
498              _paymentTokenOracle.oracleData
499          );
500  
501          // Calculate payment amount and initiate the transfers
502          uint256 discountedPaymentAmount = _getDiscountedPaymentAmount(
503              otcAmountInUSD,
504              paymentTokenValuation,
505              discount,
506              _paymentToken.decimals()
507          );
508  
509          _paymentToken.transferFrom(
510              msg.sender,
511              address(this),
512              discountedPaymentAmount
513          );
514          tapOFT.transfer(msg.sender, tapAmount);
515      }
516  
517      /// @notice Computes the discounted payment amount for a given OTC amount in USD
518      /// @param _otcAmountInUSD The OTC amount in USD, 18 decimals
519      /// @param _paymentTokenValuation The payment token valuation in USD, 18 decimals
520      /// @param _discount The discount in BPS
521      /// @param _paymentTokenDecimals The payment token decimals
522      /// @return paymentAmount The discounted payment amount
523      function _getDiscountedPaymentAmount(
524          uint256 _otcAmountInUSD,
525          uint256 _paymentTokenValuation,
526          uint256 _discount,
527          uint256 _paymentTokenDecimals
528      ) internal pure returns (uint256 paymentAmount) {
529          // Calculate payment amount
530          uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;
531          paymentAmount =
532              rawPaymentAmount -
533              muldiv(rawPaymentAmount, _discount, 100e4); // 1e4 is discount decimals, 100 is discount percentage
534  
535          paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));
536      }
537: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L43-L537

File: contracts/options/TapiocaOptionBroker.sol

53   contract TapiocaOptionBroker is Pausable, BoringOwnable, TWAML {
54       TapiocaOptionLiquidityProvision public immutable tOLP;
55       bytes public tapOracleData;
56       TapOFT public immutable tapOFT;
57       OTAP public immutable oTAP;
58       IOracle public tapOracle;
59   
60       uint256 public lastEpochUpdate; // timestamp of the last epoch update
61       uint256 public epochTAPValuation; // TAP price for the current epoch
62       uint256 public epoch; // Represents the number of weeks since the start of the contract
63   
64       mapping(uint256 => Participation) public participants; // tOLPTokenID => Participation
65       mapping(uint256 => mapping(uint256 => uint256)) public oTAPCalls; // oTAPTokenID => epoch => amountExercised
66   
67       mapping(uint256 => mapping(uint256 => uint256)) public singularityGauges; // epoch => sglAssetId => availableTAP
68   
69       mapping(ERC20 => PaymentTokenOracle) public paymentTokens; // Token address => PaymentTokenOracle
70       address public paymentTokenBeneficiary; // Where to collect the payment tokens
71   
72       /// ===== TWAML ======
73       mapping(uint256 => TWAMLPool) public twAML; // sglAssetId => twAMLPool
74   
75       uint256 constant MIN_WEIGHT_FACTOR = 10; // In BPS, 0.1%
76       uint256 constant dMAX = 50 * 1e4; // 5% - 50% discount
77       uint256 constant dMIN = 5 * 1e4;
78       uint256 public immutable EPOCH_DURATION; // 7 days = 604800
79   
80       /// =====-------======
81       constructor(
82           address _tOLP,
83           address _oTAP,
84           address payable _tapOFT,
85           address _paymentTokenBeneficiary,
86           uint256 _epochDuration,
87           address _owner
88       ) {
89           paymentTokenBeneficiary = _paymentTokenBeneficiary;
90           tOLP = TapiocaOptionLiquidityProvision(_tOLP);
91           tapOFT = TapOFT(_tapOFT);
92           oTAP = OTAP(_oTAP);
93           EPOCH_DURATION = _epochDuration;
94           owner = _owner;
95       }
96   
97       // ==========
98       //   EVENTS
99       // ==========
100      event Participate(
101          uint256 indexed epoch,
102          uint256 indexed sglAssetID,
103          uint256 totalDeposited,
104          LockPosition lock,
105          uint256 discount
106      );
107      event AMLDivergence(
108          uint256 indexed epoch,
109          uint256 cumulative,
110          uint256 averageMagnitude,
111          uint256 totalParticipants
112      );
113      event ExerciseOption(
114          uint256 indexed epoch,
115          address indexed to,
116          ERC20 indexed paymentToken,
117          uint256 oTapTokenID,
118          uint256 amount
119      );
120      event NewEpoch(
121          uint256 indexed epoch,
122          uint256 extractedTAP,
123          uint256 epochTAPValuation
124      );
125      event ExitPosition(
126          uint256 indexed epoch,
127          uint256 indexed tokenId,
128          uint256 amount
129      );
130      event SetPaymentToken(ERC20 paymentToken, IOracle oracle, bytes oracleData);
131      event SetTapOracle(IOracle oracle, bytes oracleData);
132  
133      // ==========
134      //    READ
135      // ==========
136  
137      /// @notice Returns the details of an OTC deal for a given oTAP token ID and a payment token.
138      ///         The oracle uses the last peeked value, and not the latest one, so the payment amount may be different.
139      /// @param _oTAPTokenID The oTAP token ID
140      /// @param _paymentToken The payment token
141      /// @param _tapAmount The amount of TAP to be exchanged. If 0 it will use the full amount of TAP eligible for the deal
142      /// @return eligibleTapAmount The amount of TAP eligible for the deal
143      /// @return paymentTokenAmount The amount of payment tokens required for the deal
144      /// @return tapAmount The amount of TAP to be exchanged
145      function getOTCDealDetails(
146          uint256 _oTAPTokenID,
147          ERC20 _paymentToken,
148          uint256 _tapAmount
149      )
150          external
151          view
152          returns (
153              uint256 eligibleTapAmount,
154              uint256 paymentTokenAmount,
155              uint256 tapAmount
156          )
157      {
158          // Load data
159          (, TapOption memory oTAPPosition) = oTAP.attributes(_oTAPTokenID);
160          (bool isPositionActive, LockPosition memory tOLPLockPosition) = tOLP
161              .getLock(oTAPPosition.tOLP);
162  
163          uint256 cachedEpoch = epoch;
164  
165          PaymentTokenOracle memory paymentTokenOracle = paymentTokens[
166              _paymentToken
167          ];
168  
169          // Check requirements
170          require(
171              paymentTokenOracle.oracle != IOracle(address(0)),
172              "tOB: Payment token not supported"
173          );
174  
175          require(isPositionActive, "tOB: Option expired");
176  
177          // Get eligible OTC amount
178          uint256 gaugeTotalForEpoch = singularityGauges[cachedEpoch][
179              tOLPLockPosition.sglAssetID
180          ];
181          eligibleTapAmount = muldiv(
182              tOLPLockPosition.amount,
183              gaugeTotalForEpoch,
184              tOLP.getTotalPoolDeposited(tOLPLockPosition.sglAssetID)
185          );
186          eligibleTapAmount -= oTAPCalls[_oTAPTokenID][cachedEpoch]; // Subtract already exercised amount
187          require(eligibleTapAmount >= _tapAmount, "tOB: Too high");
188  
189          tapAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;
190          require(tapAmount >= 1e18, "tOB: Too low");
191          // Get TAP valuation
192          uint256 otcAmountInUSD = tapAmount * epochTAPValuation; // Divided by TAP decimals
193          // Get payment token valuation
194          (, uint256 paymentTokenValuation) = paymentTokenOracle.oracle.peek(
195              paymentTokenOracle.oracleData
196          );
197          // Get payment token amount
198          paymentTokenAmount = _getDiscountedPaymentAmount(
199              otcAmountInUSD,
200              paymentTokenValuation,
201              oTAPPosition.discount,
202              _paymentToken.decimals()
203          );
204      }
205  
206      // ===========
207      //    WRITE
208      // ===========
209  
210      /// @notice Participate in twAMl voting and mint an oTAP position
211      /// @param _tOLPTokenID The tokenId of the tOLP position
212      function participate(
213          uint256 _tOLPTokenID
214      ) external returns (uint256 oTAPTokenID) {
215          // Compute option parameters
216          (bool isPositionActive, LockPosition memory lock) = tOLP.getLock(
217              _tOLPTokenID
218          );
219          require(isPositionActive, "tOB: Position is not active");
220          require(lock.lockDuration >= EPOCH_DURATION, "tOB: Duration too short");
221  
222          TWAMLPool memory pool = twAML[lock.sglAssetID];
223  
224          require(
225              tOLP.isApprovedOrOwner(msg.sender, _tOLPTokenID),
226              "tOB: Not approved or owner"
227          );
228  
229          // Transfer tOLP position to this contract
230          tOLP.transferFrom(msg.sender, address(this), _tOLPTokenID);
231  
232          uint256 magnitude = computeMagnitude(
233              uint256(lock.lockDuration),
234              pool.cumulative
235          );
236          bool divergenceForce;
237          uint256 target = computeTarget(dMIN, dMAX, magnitude, pool.cumulative);
238  
239          // Participate in twAMl voting
240          bool hasVotingPower = lock.amount >=
241              computeMinWeight(pool.totalDeposited, MIN_WEIGHT_FACTOR);
242          if (hasVotingPower) {
243              pool.totalParticipants++; // Save participation
244              pool.averageMagnitude =
245                  (pool.averageMagnitude + magnitude) /
246                  pool.totalParticipants; // compute new average magnitude
247  
248              // Compute and save new cumulative
249              divergenceForce = lock.lockDuration > pool.cumulative;
250              if (divergenceForce) {
251                  pool.cumulative += pool.averageMagnitude;
252              } else {
253                  if (pool.cumulative > pool.averageMagnitude) {
254                      pool.cumulative -= pool.averageMagnitude;
255                  } else {
256                      pool.cumulative = 0;
257                  }
258              }
259  
260              // Save new weight
261              pool.totalDeposited += lock.amount;
262  
263              twAML[lock.sglAssetID] = pool; // Save twAML participation
264              emit AMLDivergence(
265                  epoch,
266                  pool.cumulative,
267                  pool.averageMagnitude,
268                  pool.totalParticipants
269              ); // Register new voting power event
270          }
271          // Save twAML participation
272          participants[_tOLPTokenID] = Participation(
273              hasVotingPower,
274              divergenceForce,
275              pool.averageMagnitude
276          );
277  
278          // Mint oTAP position
279          oTAPTokenID = oTAP.mint(
280              msg.sender,
281              lock.lockTime + lock.lockDuration,
282              uint128(target),
283              _tOLPTokenID
284          );
285          emit Participate(
286              epoch,
287              lock.sglAssetID,
288              pool.totalDeposited,
289              lock,
290              target
291          );
292      }
293  
294      /// @notice Exit a twAML participation and delete the voting power if existing
295      /// @param _oTAPTokenID The tokenId of the oTAP position
296      function exitPosition(uint256 _oTAPTokenID) external {
297          require(oTAP.exists(_oTAPTokenID), "tOB: oTAP position does not exist");
298  
299          // Load data
300          (, TapOption memory oTAPPosition) = oTAP.attributes(_oTAPTokenID);
301          (, LockPosition memory lock) = tOLP.getLock(oTAPPosition.tOLP);
302  
303          require(
304              block.timestamp >= lock.lockTime + lock.lockDuration,
305              "tOB: Lock not expired"
306          );
307  
308          Participation memory participation = participants[oTAPPosition.tOLP];
309  
310          // Remove participation
311          if (participation.hasVotingPower) {
312              TWAMLPool memory pool = twAML[lock.sglAssetID];
313  
314              if (participation.divergenceForce) {
315                  if (pool.cumulative > pool.averageMagnitude) {
316                      pool.cumulative -= pool.averageMagnitude;
317                  } else {
318                      pool.cumulative = 0;
319                  }
320              } else {
321                  pool.cumulative += pool.averageMagnitude;
322              }
323  
324              pool.totalDeposited -= lock.amount;
325              pool.totalParticipants--;
326  
327              twAML[lock.sglAssetID] = pool; // Save twAML exit
328              emit AMLDivergence(
329                  epoch,
330                  pool.cumulative,
331                  pool.averageMagnitude,
332                  pool.totalParticipants
333              ); // Register new voting power event
334          }
335  
336          // Delete participation and burn oTAP position
337          address otapOwner = oTAP.ownerOf(_oTAPTokenID);
338          delete participants[oTAPPosition.tOLP];
339          oTAP.burn(_oTAPTokenID);
340  
341          // Transfer position back to oTAP owner
342          tOLP.transferFrom(address(this), otapOwner, oTAPPosition.tOLP);
343  
344          emit ExitPosition(epoch, oTAPPosition.tOLP, lock.amount);
345      }
346  
347      /// @notice Exercise an oTAP position
348      /// @param _oTAPTokenID tokenId of the oTAP position, position must be active
349      /// @param _paymentToken Address of the payment token to use, must be whitelisted
350      /// @param _tapAmount Amount of TAP to exercise. If 0, the full amount is exercised
351      function exerciseOption(
352          uint256 _oTAPTokenID,
353          ERC20 _paymentToken,
354          uint256 _tapAmount
355      ) external {
356          // Load data
357          (, TapOption memory oTAPPosition) = oTAP.attributes(_oTAPTokenID);
358          (bool isPositionActive, LockPosition memory tOLPLockPosition) = tOLP
359              .getLock(oTAPPosition.tOLP);
360  
361          uint256 cachedEpoch = epoch;
362  
363          PaymentTokenOracle memory paymentTokenOracle = paymentTokens[
364              _paymentToken
365          ];
366  
367          // Check requirements
368          require(
369              paymentTokenOracle.oracle != IOracle(address(0)),
370              "tOB: Payment token not supported"
371          );
372          require(
373              oTAP.isApprovedOrOwner(msg.sender, _oTAPTokenID),
374              "tOB: Not approved or owner"
375          );
376          require(isPositionActive, "tOB: Option expired");
377  
378          // Get eligible OTC amount
379          uint256 gaugeTotalForEpoch = singularityGauges[cachedEpoch][
380              tOLPLockPosition.sglAssetID
381          ];
382          uint256 eligibleTapAmount = muldiv(
383              tOLPLockPosition.amount,
384              gaugeTotalForEpoch,
385              tOLP.getTotalPoolDeposited(tOLPLockPosition.sglAssetID)
386          );
387          eligibleTapAmount -= oTAPCalls[_oTAPTokenID][cachedEpoch]; // Subtract already exercised amount
388          require(eligibleTapAmount >= _tapAmount, "tOB: Too high");
389  
390          uint256 chosenAmount = _tapAmount == 0 ? eligibleTapAmount : _tapAmount;
391          require(chosenAmount >= 1e18, "tOB: Too low");
392          oTAPCalls[_oTAPTokenID][cachedEpoch] += chosenAmount; // Adds up exercised amount to current epoch
393  
394          // Finalize the deal
395          _processOTCDeal(
396              _paymentToken,
397              paymentTokenOracle,
398              chosenAmount,
399              oTAPPosition.discount
400          );
401  
402          emit ExerciseOption(
403              cachedEpoch,
404              msg.sender,
405              _paymentToken,
406              _oTAPTokenID,
407              chosenAmount
408          );
409      }
410  
411      /// @notice Start a new epoch, extract TAP from the TapOFT contract,
412      ///         emit it to the active singularities and get the price of TAP for the epoch.
413      function newEpoch() external {
414          require(
415              block.timestamp >= lastEpochUpdate + EPOCH_DURATION,
416              "tOB: too soon"
417          );
418          uint256[] memory singularities = tOLP.getSingularities();
419          require(singularities.length > 0, "tOB: No active singularities");
420  
421          // Update epoch info
422          lastEpochUpdate = block.timestamp;
423          epoch++;
424  
425          // Extract TAP
426          uint256 epochTAP = tapOFT.emitForWeek();
427          _emitToGauges(epochTAP);
428  
429          // Get epoch TAP valuation
430          (, epochTAPValuation) = tapOracle.get(tapOracleData);
431          emit NewEpoch(epoch, epochTAP, epochTAPValuation);
432      }
433  
434      /// @notice Claim the Broker role of the oTAP contract
435      function oTAPBrokerClaim() external {
436          oTAP.brokerClaim();
437      }
438  
439      // =========
440      //   OWNER
441      // =========
442  
443      /// @notice Set the TapOFT Oracle address and data
444      /// @param _tapOracle The new TapOFT Oracle address
445      /// @param _tapOracleData The new TapOFT Oracle data
446      function setTapOracle(
447          IOracle _tapOracle,
448          bytes calldata _tapOracleData
449      ) external onlyOwner {
450          tapOracle = _tapOracle;
451          tapOracleData = _tapOracleData;
452  
453          emit SetTapOracle(_tapOracle, _tapOracleData);
454      }
455  
456      /// @notice Activate or deactivate a payment token
457      /// @dev set the oracle to address(0) to deactivate, expect the same decimal precision as TAP oracle
458      function setPaymentToken(
459          ERC20 _paymentToken,
460          IOracle _oracle,
461          bytes calldata _oracleData
462      ) external onlyOwner {
463          paymentTokens[_paymentToken].oracle = _oracle;
464          paymentTokens[_paymentToken].oracleData = _oracleData;
465  
466          emit SetPaymentToken(_paymentToken, _oracle, _oracleData);
467      }
468  
469      /// @notice Set the payment token beneficiary
470      /// @param _paymentTokenBeneficiary The new payment token beneficiary
471      function setPaymentTokenBeneficiary(
472          address _paymentTokenBeneficiary
473      ) external onlyOwner {
474          paymentTokenBeneficiary = _paymentTokenBeneficiary;
475      }
476  
477      /// @notice Collect the payment tokens from the OTC deals
478      /// @param _paymentTokens The payment tokens to collect
479      function collectPaymentTokens(
480          address[] calldata _paymentTokens
481      ) external onlyOwner {
482          require(
483              paymentTokenBeneficiary != address(0),
484              "tOB: Payment token beneficiary not set"
485          );
486          uint256 len = _paymentTokens.length;
487  
488          unchecked {
489              for (uint256 i = 0; i < len; ++i) {
490                  ERC20 paymentToken = ERC20(_paymentTokens[i]);
491                  paymentToken.transfer(
492                      paymentTokenBeneficiary,
493                      paymentToken.balanceOf(address(this))
494                  );
495              }
496          }
497      }
498  
499      // ============
500      //   INTERNAL
501      // ============
502  
503      /// @notice Process the OTC deal, transfer the payment token to the broker and the TAP amount to the user
504      /// @param _paymentToken The payment token
505      /// @param _paymentTokenOracle The oracle of the payment token
506      /// @param tapAmount The amount of TAP that the user has to receive
507      /// @param discount The discount that the user has to apply to the OTC deal
508      function _processOTCDeal(
509          ERC20 _paymentToken,
510          PaymentTokenOracle memory _paymentTokenOracle,
511          uint256 tapAmount,
512          uint256 discount
513      ) internal {
514          // Get TAP valuation
515          uint256 otcAmountInUSD = tapAmount * epochTAPValuation;
516  
517          // Get payment token valuation
518          (, uint256 paymentTokenValuation) = _paymentTokenOracle.oracle.get(
519              _paymentTokenOracle.oracleData
520          );
521  
522          // Calculate payment amount and initiate the transfers
523          uint256 discountedPaymentAmount = _getDiscountedPaymentAmount(
524              otcAmountInUSD,
525              paymentTokenValuation,
526              discount,
527              _paymentToken.decimals()
528          );
529  
530          _paymentToken.transferFrom(
531              msg.sender,
532              address(this),
533              discountedPaymentAmount
534          );
535          tapOFT.extractTAP(msg.sender, tapAmount);
536      }
537  
538      /// @notice Computes the discounted payment amount for a given OTC amount in USD
539      /// @param _otcAmountInUSD The OTC amount in USD, 18 decimals
540      /// @param _paymentTokenValuation The payment token valuation in USD, 18 decimals
541      /// @param _discount The discount in BPS
542      /// @param _paymentTokenDecimals The payment token decimals
543      /// @return paymentAmount The discounted payment amount
544      function _getDiscountedPaymentAmount(
545          uint256 _otcAmountInUSD,
546          uint256 _paymentTokenValuation,
547          uint256 _discount,
548          uint256 _paymentTokenDecimals
549      ) internal pure returns (uint256 paymentAmount) {
550          // Calculate payment amount
551          uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;
552          paymentAmount =
553              rawPaymentAmount -
554              muldiv(rawPaymentAmount, _discount, 100e4); // 1e4 is discount decimals, 100 is discount percentage
555          paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));
556      }
557  
558      /// @notice Emit TAP to the gauges equitably
559      function _emitToGauges(uint256 _epochTAP) internal {
560          SingularityPool[] memory sglPools = tOLP.getSingularityPools();
561          uint256 totalWeights = tOLP.totalSingularityPoolWeights();
562  
563          uint256 len = sglPools.length;
564          unchecked {
565              for (uint256 i = 0; i < len; ++i) {
566                  uint256 currentPoolWeight = sglPools[i].poolWeight;
567                  uint256 quotaPerSingularity = muldiv(
568                      currentPoolWeight,
569                      _epochTAP,
570                      totalWeights
571                  );
572                  singularityGauges[epoch][
573                      sglPools[i].sglAssetID
574                  ] = quotaPerSingularity;
575              }
576          }
577      }
578: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L53-L578

File: contracts/options/TapiocaOptionLiquidityProvision.sol

48   contract TapiocaOptionLiquidityProvision is
49       ERC721,
50       ERC721Permit,
51       BaseBoringBatchable,
52       Pausable,
53       BoringOwnable
54   {
55       uint256 public tokenCounter; // Counter for token IDs
56       mapping(uint256 => LockPosition) public lockPositions; // TokenID => LockPosition
57   
58       IYieldBox public immutable yieldBox;
59   
60       // Singularity market address => SingularityPool (YieldBox Asset ID is 0 if not active)
61       mapping(IERC20 => SingularityPool) public activeSingularities;
62       mapping(uint256 => IERC20) public sglAssetIDToAddress; // Singularity market YieldBox asset ID => Singularity market address
63       uint256[] public singularities; // Array of active singularity asset IDs
64   
65       uint256 public totalSingularityPoolWeights; // Total weight of all active singularity pools
66   
67       constructor(
68           address _yieldBox,
69           address _owner
70       )
71           ERC721("TapiocaOptionLiquidityProvision", "tOLP")
72           ERC721Permit("TapiocaOptionLiquidityProvision")
73       {
74           yieldBox = IYieldBox(_yieldBox);
75           owner = _owner;
76       }
77   
78       // ==========
79       //   EVENTS
80       // ==========
81       event Mint(
82           address indexed to,
83           uint128 indexed sglAssetID,
84           LockPosition lockPosition
85       );
86       event Burn(
87           address indexed to,
88           uint128 indexed sglAssetID,
89           LockPosition lockPosition
90       );
91       event UpdateTotalSingularityPoolWeights(
92           uint256 totalSingularityPoolWeights
93       );
94       event SetSGLPoolWeight(address sgl, uint256 poolWeight);
95       event RegisterSingularity(address sgl, uint256 assetID);
96       event UnregisterSingularity(address sgl, uint256 assetID);
97   
98       // ===============
99       //    MODIFIERS
100      // ===============
101      modifier updateTotalSGLPoolWeights() {
102          _;
103          totalSingularityPoolWeights = _computeSGLPoolWeights();
104          emit UpdateTotalSingularityPoolWeights(totalSingularityPoolWeights);
105      }
106  
107      // =========
108      //    READ
109      // =========
110      /// @notice Returns the lock position of a given tOLP NFT and if it's active
111      /// @param _tokenId tOLP NFT ID
112      function getLock(
113          uint256 _tokenId
114      ) external view returns (bool, LockPosition memory) {
115          LockPosition memory lockPosition = lockPositions[_tokenId];
116  
117          return (_isPositionActive(_tokenId), lockPosition);
118      }
119  
120      /// @notice Returns the active singularity YieldBox ID markets
121      function getSingularities() external view returns (uint256[] memory) {
122          return singularities;
123      }
124  
125      /// @notice Returns the active singularity pool data
126      function getSingularityPools()
127          external
128          view
129          returns (SingularityPool[] memory)
130      {
131          uint256[] memory _singularities = singularities;
132          uint256 len = _singularities.length;
133  
134          SingularityPool[] memory pools = new SingularityPool[](len);
135          unchecked {
136              for (uint256 i = 0; i < len; ++i) {
137                  pools[i] = activeSingularities[
138                      sglAssetIDToAddress[_singularities[i]]
139                  ];
140              }
141          }
142          return pools;
143      }
144  
145      /// @notice Returns the total amount of locked tokens for a given singularity market
146      function getTotalPoolDeposited(
147          uint256 _sglAssetId
148      ) external view returns (uint256) {
149          return
150              activeSingularities[sglAssetIDToAddress[_sglAssetId]]
151                  .totalDeposited;
152      }
153  
154      function isApprovedOrOwner(
155          address _spender,
156          uint256 _tokenId
157      ) external view returns (bool) {
158          return _isApprovedOrOwner(_spender, _tokenId);
159      }
160  
161      // ==========
162      //    WRITE
163      // ==========
164  
165      /// @notice Locks tOLR tokens for a given duration
166      /// @param _to Address to mint the tOLP NFT to
167      /// @param _singularity Singularity market address
168      /// @param _lockDuration Duration of the lock
169      /// @param _amount Amount of tOLR tokens to lock
170      /// @return tokenId The ID of the minted NFT
171      function lock(
172          address _to,
173          IERC20 _singularity,
174          uint128 _lockDuration,
175          uint128 _amount
176      ) external returns (uint256 tokenId) {
177          require(_lockDuration > 0, "tOLP: lock duration must be > 0");
178          require(_amount > 0, "tOLP: amount must be > 0");
179  
180          uint256 sglAssetID = activeSingularities[_singularity].sglAssetID;
181          require(sglAssetID > 0, "tOLP: singularity not active");
182  
183          // Transfer the Singularity position to this contract
184          uint256 sharesIn = yieldBox.toShare(sglAssetID, _amount, false);
185  
186          yieldBox.transfer(msg.sender, address(this), sglAssetID, sharesIn);
187          activeSingularities[_singularity].totalDeposited += _amount;
188  
189          // Mint the tOLP NFT position
190          tokenId = ++tokenCounter;
191          _safeMint(_to, tokenId);
192  
193          // Create the lock position
194          LockPosition storage lockPosition = lockPositions[tokenId];
195          lockPosition.lockTime = uint128(block.timestamp);
196          lockPosition.sglAssetID = uint128(sglAssetID);
197          lockPosition.lockDuration = _lockDuration;
198          lockPosition.amount = _amount;
199  
200          emit Mint(_to, uint128(sglAssetID), lockPosition);
201      }
202  
203      /// @notice Unlocks tOLP tokens
204      /// @param _tokenId ID of the position to unlock
205      /// @param _singularity Singularity market address
206      /// @param _to Address to send the tokens to
207      function unlock(
208          uint256 _tokenId,
209          IERC20 _singularity,
210          address _to
211      ) external returns (uint256 sharesOut) {
212          require(_exists(_tokenId), "tOLP: Expired position");
213  
214          LockPosition memory lockPosition = lockPositions[_tokenId];
215          require(
216              block.timestamp >=
217                  lockPosition.lockTime + lockPosition.lockDuration,
218              "tOLP: Lock not expired"
219          );
220          require(
221              activeSingularities[_singularity].sglAssetID ==
222                  lockPosition.sglAssetID,
223              "tOLP: Invalid singularity"
224          );
225  
226          require(
227              _isApprovedOrOwner(msg.sender, _tokenId),
228              "tOLP: not owner nor approved"
229          );
230  
231          _burn(_tokenId);
232          delete lockPositions[_tokenId];
233  
234          // Transfer the tOLR tokens back to the owner
235          sharesOut = yieldBox.toShare(
236              lockPosition.sglAssetID,
237              lockPosition.amount,
238              false
239          );
240  
241          yieldBox.transfer(
242              address(this),
243              _to,
244              lockPosition.sglAssetID,
245              sharesOut
246          );
247          activeSingularities[_singularity].totalDeposited -= lockPosition.amount;
248  
249          emit Burn(_to, lockPosition.sglAssetID, lockPosition);
250      }
251  
252      // =========
253      //   OWNER
254      // =========
255  
256      /// @notice Sets the pool weight of a given singularity market
257      /// @param singularity Singularity market address
258      /// @param weight Weight of the pool
259      function setSGLPoolWEight(
260          IERC20 singularity,
261          uint256 weight
262      ) external onlyOwner updateTotalSGLPoolWeights {
263          require(
264              activeSingularities[singularity].sglAssetID > 0,
265              "tOLP: not registered"
266          );
267          activeSingularities[singularity].poolWeight = weight;
268  
269          emit SetSGLPoolWeight(address(singularity), weight);
270      }
271  
272      /// @notice Registers a new singularity market
273      /// @param singularity Singularity market address
274      /// @param assetID YieldBox asset ID of the singularity market
275      /// @param weight Weight of the pool
276      function registerSingularity(
277          IERC20 singularity,
278          uint256 assetID,
279          uint256 weight
280      ) external onlyOwner updateTotalSGLPoolWeights {
281          require(assetID > 0, "tOLP: invalid asset ID");
282          require(
283              activeSingularities[singularity].sglAssetID == 0,
284              "tOLP: already registered"
285          );
286  
287          activeSingularities[singularity].sglAssetID = assetID;
288          activeSingularities[singularity].poolWeight = weight > 0 ? weight : 1;
289          sglAssetIDToAddress[assetID] = singularity;
290          singularities.push(assetID);
291  
292          emit RegisterSingularity(address(singularity), assetID);
293      }
294  
295      /// @notice Un-registers a singularity market
296      /// @param singularity Singularity market address
297      function unregisterSingularity(
298          IERC20 singularity
299      ) external onlyOwner updateTotalSGLPoolWeights {
300          uint256 sglAssetID = activeSingularities[singularity].sglAssetID;
301          require(sglAssetID > 0, "tOLP: not registered");
302  
303          unchecked {
304              uint256[] memory _singularities = singularities;
305              uint256 sglLength = _singularities.length;
306              uint256 sglLastIndex = sglLength - 1;
307  
308              for (uint256 i = 0; i < sglLength; i++) {
309                  // If last element, just pop
310                  if (i == sglLastIndex) {
311                      delete activeSingularities[singularity];
312                      delete sglAssetIDToAddress[sglAssetID];
313                      singularities.pop();
314                  } else if (
315                      _singularities[i] == sglAssetID && i < sglLastIndex
316                  ) {
317                      // If in the middle, copy last element on deleted element, then pop
318                      delete activeSingularities[singularity];
319                      delete sglAssetIDToAddress[sglAssetID];
320  
321                      singularities[i] = _singularities[sglLastIndex];
322                      singularities.pop();
323                      break;
324                  }
325              }
326          }
327  
328          emit UnregisterSingularity(address(singularity), sglAssetID);
329      }
330  
331      // =========
332      //  INTERNAL
333      // =========
334  
335      /// @notice Compute the total pool weight of all active singularity markets
336      function _computeSGLPoolWeights() internal view returns (uint256) {
337          uint256 total;
338          uint256 len = singularities.length;
339          for (uint256 i = 0; i < len; i++) {
340              total += activeSingularities[sglAssetIDToAddress[singularities[i]]]
341                  .poolWeight;
342          }
343  
344          return total;
345      }
346  
347      /// @notice Checks if the lock position is still active
348      function _isPositionActive(uint256 tokenId) internal view returns (bool) {
349          LockPosition memory lockPosition = lockPositions[tokenId];
350  
351          return
352              (lockPosition.lockTime + lockPosition.lockDuration) >=
353              block.timestamp;
354      }
355  
356      /// @notice ERC1155 compliance
357      function onERC1155Received(
358          address,
359          address,
360          uint256,
361          uint256,
362          bytes calldata
363      ) external pure returns (bytes4) {
364          return
365              bytes4(
366                  keccak256(
367                      "onERC1155Received(address,address,uint256,uint256,bytes)"
368                  )
369              );
370      }
371: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L48-L371

File: contracts/tokens/BaseTapOFT.sol

31   abstract contract BaseTapOFT is OFTV2 {
32       using ExcessivelySafeCall for address;
33       using BytesLib for bytes;
34   
35       TwTAP public twTap;
36   
37       uint16 internal constant PT_LOCK_TWTAP = 870;
38       uint16 internal constant PT_UNLOCK_TWTAP = 871;
39       uint16 internal constant PT_CLAIM_REWARDS = 872;
40   
41       event CallFailedStr(uint16 _srcChainId, bytes _payload, string _reason);
42       event CallFailedBytes(uint16 _srcChainId, bytes _payload, bytes _reason);
43   
44       constructor(
45           string memory _name,
46           string memory _symbol,
47           uint8 _sharedDec,
48           address _lzEndpoint
49       ) OFTV2(_name, _symbol, _sharedDec, _lzEndpoint) {}
50   
51       //---LZ---
52       function _nonblockingLzReceive(
53           uint16 _srcChainId,
54           bytes memory _srcAddress,
55           uint64 _nonce,
56           bytes memory _payload
57       ) internal virtual override {
58           uint256 packetType = _payload.toUint256(0);
59   
60           if (packetType == PT_LOCK_TWTAP) {
61               _lockTwTapPosition(_srcChainId, _payload);
62           } else if (packetType == PT_UNLOCK_TWTAP) {
63               _unlockTwTapPosition(_srcChainId, _payload);
64           } else if (packetType == PT_CLAIM_REWARDS) {
65               _claimRewards(_srcChainId, _payload);
66           } else {
67               packetType = _payload.toUint8(0);
68               if (packetType == PT_SEND) {
69                   _sendAck(_srcChainId, _srcAddress, _nonce, _payload);
70               } else if (packetType == PT_SEND_AND_CALL) {
71                   _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);
72               } else {
73                   revert("TOFT_packet");
74               }
75           }
76       }
77   
78       /// --------------------------
79       /// ------- LOCK TWTAP -------
80       /// --------------------------
81   
82       /// @notice Opens a twTAP by participating in twAML.
83       /// @param to The address to add the twTAP position to.
84       /// @param amount The amount to add.
85       /// @param lzDstChainId The destination chain id.
86       /// @param zroPaymentAddress The address to send the ZRO payment to.
87       /// @param adapterParams The adapter params.
88       function lockTwTapPosition(
89           address to,
90           uint256 amount, // Amount to add
91           uint256 duration, // Duration of the position.
92           uint16 lzDstChainId,
93           address zroPaymentAddress,
94           bytes calldata adapterParams
95       ) external payable {
96           bytes memory lzPayload = abi.encode(
97               PT_LOCK_TWTAP, // packet type
98               msg.sender,
99               to,
100              amount,
101              duration
102          );
103  
104          require(duration > 0, "TapOFT: Small duration");
105          bytes32 senderBytes = LzLib.addressToBytes32(msg.sender);
106          _debitFrom(msg.sender, lzEndpoint.getChainId(), senderBytes, amount);
107  
108          _lzSend(
109              lzDstChainId,
110              lzPayload,
111              payable(msg.sender),
112              zroPaymentAddress,
113              adapterParams,
114              msg.value
115          );
116  
117          emit SendToChain(
118              lzDstChainId,
119              msg.sender,
120              LzLib.addressToBytes32(to),
121              0
122          );
123      }
124  
125      function _lockTwTapPosition(
126          uint16 _srcChainId,
127          bytes memory _payload
128      ) internal virtual {
129          (, , address to, uint256 amount, uint duration) = abi.decode(
130              _payload,
131              (uint16, address, address, uint256, uint256)
132          );
133  
134          _creditTo(_srcChainId, address(this), amount);
135          approve(address(twTap), amount);
136  
137          // We participate and mint with TapOFT as a receiver
138          try twTap.participate(to, amount, duration) {} catch Error(
139              string memory _reason
140          ) {
141              // If the process fails, we send back the funds to the user
142              // We send back the funds to the user
143              emit CallFailedStr(_srcChainId, _payload, _reason);
144              _transferFrom(address(this), to, amount);
145          } catch (bytes memory _reason) {
146              emit CallFailedBytes(_srcChainId, _payload, _reason);
147              _transferFrom(address(this), to, amount);
148          }
149      }
150  
151      /// ------------------------------
152      /// ------- CLAIM REWARDS --------
153      /// ------------------------------
154  
155      /// @notice Claim rewards from a twTAP position.
156      /// @param to The address to add the twTAP position to.
157      /// @param tokenID Token ID of the twTAP position.
158      /// @param rewardTokens The address of the reward tokens.
159      /// @param lzDstChainId The destination chain id.
160      /// @param zroPaymentAddress The address to send the ZRO payment to.
161      /// @param adapterParams The adapter params.
162      /// @param rewardClaimSendParams The adapter params to send back the TAP token.
163      function claimRewards(
164          address to,
165          uint256 tokenID,
166          address[] memory rewardTokens,
167          uint16 lzDstChainId,
168          address zroPaymentAddress,
169          bytes calldata adapterParams,
170          IRewardClaimSendFromParams[] calldata rewardClaimSendParams
171      ) external payable {
172          bytes memory lzPayload = abi.encode(
173              PT_CLAIM_REWARDS, // packet type
174              msg.sender,
175              to,
176              tokenID,
177              rewardTokens,
178              rewardClaimSendParams
179          );
180  
181          _lzSend(
182              lzDstChainId,
183              lzPayload,
184              payable(msg.sender),
185              zroPaymentAddress,
186              adapterParams,
187              msg.value
188          );
189  
190          emit SendToChain(
191              lzDstChainId,
192              msg.sender,
193              LzLib.addressToBytes32(to),
194              0
195          );
196      }
197  
198      function _claimRewards(
199          uint16 _srcChainId,
200          bytes memory _payload
201      ) internal virtual {
202          (
203              ,
204              ,
205              address to,
206              uint256 tokenID,
207              IERC20[] memory rewardTokens,
208              IRewardClaimSendFromParams[] memory rewardClaimSendParams
209          ) = abi.decode(
210                  _payload,
211                  (
212                      uint16,
213                      address,
214                      address,
215                      uint256,
216                      IERC20[],
217                      IRewardClaimSendFromParams[]
218                  )
219              );
220  
221          // Only the owner can unlock
222          require(twTap.ownerOf(tokenID) == to, "TapOFT: Not owner");
223  
224          // Exit and receive tokens to this contract
225          try twTap.claimAndSendRewards(tokenID, rewardTokens) {
226              // Transfer them to the user
227              uint256 len = rewardTokens.length;
228              for (uint i = 0; i < len; ) {
229                  ISendFrom(address(rewardTokens[i])).sendFrom{
230                      value: rewardClaimSendParams[i].ethValue
231                  }(
232                      address(this),
233                      _srcChainId,
234                      LzLib.addressToBytes32(to),
235                      IERC20(rewardTokens[i]).balanceOf(address(this)),
236                      rewardClaimSendParams[i].callParams
237                  );
238                  ++i;
239              }
240          } catch Error(string memory _reason) {
241              emit CallFailedStr(_srcChainId, _payload, _reason);
242          } catch (bytes memory _reason) {
243              emit CallFailedBytes(_srcChainId, _payload, _reason);
244          }
245      }
246  
247      /// --------------------------
248      /// ------- UNLOCK TWTAP -------
249      /// --------------------------
250  
251      /// @notice Exit a twTAP by participating in twAML.
252      /// @param to The address to add the twTAP position to.
253      /// @param tokenID Token ID of the twTAP position.
254      /// @param lzDstChainId The destination chain id.
255      /// @param zroPaymentAddress The address to send the ZRO payment to.
256      /// @param adapterParams The adapter params.
257      /// @param twTapSendBackAdapterParams The adapter params to send back the TAP token.
258      function unlockTwTapPosition(
259          address to,
260          uint256 tokenID,
261          uint16 lzDstChainId,
262          address zroPaymentAddress,
263          bytes calldata adapterParams,
264          LzCallParams calldata twTapSendBackAdapterParams
265      ) external payable {
266          bytes memory lzPayload = abi.encode(
267              PT_UNLOCK_TWTAP, // packet type
268              msg.sender,
269              to,
270              tokenID,
271              twTapSendBackAdapterParams
272          );
273  
274          _lzSend(
275              lzDstChainId,
276              lzPayload,
277              payable(msg.sender),
278              zroPaymentAddress,
279              adapterParams,
280              msg.value
281          );
282  
283          emit SendToChain(
284              lzDstChainId,
285              msg.sender,
286              LzLib.addressToBytes32(to),
287              0
288          );
289      }
290  
291      function _unlockTwTapPosition(
292          uint16 _srcChainId,
293          bytes memory _payload
294      ) internal virtual {
295          (
296              ,
297              ,
298              address to,
299              uint256 tokenID,
300              LzCallParams memory twTapSendBackAdapterParams
301          ) = abi.decode(
302                  _payload,
303                  (uint16, address, address, uint256, LzCallParams)
304              );
305  
306          // Only the owner can unlock
307          require(twTap.ownerOf(tokenID) == to, "TapOFT: Not owner");
308  
309          // Exit and receive tokens to this contract
310          try twTap.exitPositionAndSendTap(tokenID) returns (uint256 _amount) {
311              // Transfer them to the user
312              this.sendFrom{value: address(this).balance}(
313                  address(this),
314                  _srcChainId,
315                  LzLib.addressToBytes32(to),
316                  _amount,
317                  twTapSendBackAdapterParams
318              );
319          } catch Error(string memory _reason) {
320              emit CallFailedStr(_srcChainId, _payload, _reason);
321          } catch (bytes memory _reason) {
322              emit CallFailedBytes(_srcChainId, _payload, _reason);
323          }
324      }
325  
326      function setTwTap(address _twTap) external onlyOwner {
327          twTap = TwTAP(_twTap);
328      }
329  
330      receive() external payable virtual {}
331  
332      function _callApproval(ICommonData.IApproval[] memory approvals) private {
333          for (uint256 i = 0; i < approvals.length; ) {
334              try
335                  IERC20Permit(approvals[i].target).permit(
336                      approvals[i].owner,
337                      approvals[i].spender,
338                      approvals[i].value,
339                      approvals[i].deadline,
340                      approvals[i].v,
341                      approvals[i].r,
342                      approvals[i].s
343                  )
344              {} catch Error(string memory reason) {
345                  if (!approvals[i].allowFailure) {
346                      revert(reason);
347                  }
348              }
349  
350              unchecked {
351                  ++i;
352              }
353          }
354      }
355: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L31-L355

File: contracts/tokens/LTap.sol

23   contract LTap is BoringOwnable, ERC20Permit {
24       IERC20 tapToken;
25       uint256 public lockedUntil;
26       uint256 public maxLockedUntil;
27   
28       /// @notice Creates a new LTAP token
29       /// @dev LTAP tokens are minted by depositing TAP
30       /// @param _tapToken Address of the TAP token
31       /// @param _maxLockedUntil Latest possible end of locking period
32       constructor(
33           IERC20 _tapToken,
34           uint256 _maxLockedUntil
35       ) ERC20("LTAP", "LTAP") ERC20Permit("LTAP") {
36           tapToken = _tapToken;
37           lockedUntil = _maxLockedUntil;
38           maxLockedUntil = _maxLockedUntil;
39       }
40   
41       function deposit(uint256 amount) external {
42           tapToken.transferFrom(msg.sender, address(this), amount);
43           _mint(msg.sender, amount);
44       }
45   
46       function redeem() external {
47           require(block.timestamp > lockedUntil, "Still locked");
48           uint256 amount = balanceOf(msg.sender);
49           _burn(msg.sender, amount);
50           tapToken.transfer(msg.sender, amount);
51       }
52   
53       function setLockedUntil(uint256 _lockedUntil) external onlyOwner {
54           require(_lockedUntil <= maxLockedUntil, "Too late");
55           lockedUntil = _lockedUntil;
56       }
57:  }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L23-L57

File: contracts/tokens/TapOFT.sol

26   contract TapOFT is BaseTapOFT, ERC20Permit {
27       // ==========
28       // *DATA*
29       // ==========
30   
31       //  Allocation:
32       // =========
33       // * DSO: 53,313,405
34       // * DAO: 8m
35       // * Contributors: 15m
36       // * Early supporters: 3,686,595
37       // * Supporters: 12.5m
38       // * LBP: 5m
39       // * Airdrop: 2.5m
40       // == 100M ==
41       uint256 public constant INITIAL_SUPPLY = 46_686_595 * 1e18; // Everything minus DSO
42       uint256 public dso_supply = 53_313_405 * 1e18;
43   
44       /// @notice the a parameter used in the emission function;
45       uint256 constant decay_rate = 8800000000000000; // 0.88%
46       uint256 constant DECAY_RATE_DECIMAL = 1e18;
47   
48       /// @notice seconds in a week
49       uint256 public constant WEEK = 604800;
50   
51       /// @notice starts time for emissions
52       /// @dev initialized in the constructor with block.timestamp
53       uint256 public immutable emissionsStartTime;
54   
55       /// @notice returns the amount of emitted TAP for a specific week
56       /// @dev week is computed using (timestamp - emissionStartTime) / WEEK
57       mapping(uint256 => uint256) public emissionForWeek;
58   
59       /// @notice returns the amount minted for a specific week
60       /// @dev week is computed using (timestamp - emissionStartTime) / WEEK
61       mapping(uint256 => uint256) public mintedInWeek;
62   
63       /// @notice returns the minter address
64       address public minter;
65   
66       /// @notice LayerZero governance chain identifier
67       uint256 public governanceChainIdentifier;
68   
69       /// @notice returns the pause state of the contract
70       bool public paused;
71   
72       // ==========
73       // *EVENTS*
74       // ==========
75       /// @notice event emitted when a new minter is set
76       event MinterUpdated(address indexed _old, address indexed _new);
77       /// @notice event emitted when a new emission is called
78       event Emitted(uint256 week, uint256 amount);
79       /// @notice event emitted when new TAP is minted
80       event Minted(address indexed _by, address indexed _to, uint256 _amount);
81       /// @notice event emitted when new TAP is burned
82       event Burned(address indexed _from, uint256 _amount);
83       /// @notice event emitted when the governance chain identifier is updated
84       event GovernanceChainIdentifierUpdated(uint256 _old, uint256 _new);
85       /// @notice event emitted when pause state is changed
86       event PausedUpdated(bool oldState, bool newState);
87   
88       modifier notPaused() {
89           require(!paused, "TAP: paused");
90           _;
91       }
92   
93       // ==========
94       // * METHODS *
95       // ==========
96       /// @notice Creates a new TAP OFT type token
97       /// @dev The initial supply of 100M is not minted here as we have the wrap method
98       /// @param _lzEndpoint the layer zero address endpoint deployed on the current chain
99       /// @param _contributors address of the  contributors. 15m
100      /// @param _earlySupporters address of early supporters. 3,686,595
101      /// @param _supporters address of supporters. 12.5m
102      /// @param _lbp address of the LBP. 5m
103      /// @param _dao address of the DAO. 8m
104      /// @param _airdrop address of the airdrop contract. 2.5m
105      /// @param _governanceChainId LayerZero governance chain identifier
106      /// @param _conservator address of the conservator/owner
107      constructor(
108          address _lzEndpoint,
109          address _contributors,
110          address _earlySupporters,
111          address _supporters,
112          address _lbp,
113          address _dao,
114          address _airdrop,
115          uint256 _governanceChainId,
116          address _conservator
117      ) BaseTapOFT("TapOFT", "TAP", 8, _lzEndpoint) ERC20Permit("TapOFT") {
118          require(_lzEndpoint != address(0), "LZ endpoint not valid");
119          governanceChainIdentifier = _governanceChainId;
120          if (_getChainId() == governanceChainIdentifier) {
121              _mint(_contributors, 1e18 * 15_000_000);
122              _mint(_earlySupporters, 1e18 * 3_686_595);
123              _mint(_supporters, 1e18 * 12_500_000);
124              _mint(_lbp, 1e18 * 5_000_000);
125              _mint(_dao, 1e18 * 8_000_000);
126              _mint(_airdrop, 1e18 * 2_500_000);
127              require(
128                  totalSupply() == INITIAL_SUPPLY,
129                  "initial supply not valid"
130              );
131          }
132          emissionsStartTime = block.timestamp;
133  
134          transferOwnership(_conservator);
135      }
136  
137      ///-- Owner methods --
138      /// @notice sets the governance chain identifier
139      /// @param _identifier LayerZero chain identifier
140      function setGovernanceChainIdentifier(
141          uint256 _identifier
142      ) external onlyOwner {
143          emit GovernanceChainIdentifierUpdated(
144              governanceChainIdentifier,
145              _identifier
146          );
147          governanceChainIdentifier = _identifier;
148      }
149  
150      /// @notice updates the pause state of the contract
151      /// @param val the new value
152      function updatePause(bool val) external onlyOwner {
153          require(val != paused, "TAP: same state");
154          emit PausedUpdated(paused, val);
155          paused = val;
156      }
157  
158      /// @notice sets a new minter address
159      /// @param _minter the new address
160      function setMinter(address _minter) external onlyOwner {
161          require(_minter != address(0), "address not valid");
162          emit MinterUpdated(minter, _minter);
163          minter = _minter;
164      }
165  
166      //-- View methods --
167      /// @notice returns token's decimals
168      function decimals() public pure override returns (uint8) {
169          return 18;
170      }
171  
172      /// @notice Returns the current week given a timestamp
173      function timestampToWeek(
174          uint256 timestamp
175      ) external view returns (uint256) {
176          if (timestamp == 0) {
177              timestamp = block.timestamp;
178          }
179          if (timestamp < emissionsStartTime) return 0;
180  
181          return _timestampToWeek(timestamp);
182      }
183  
184      /// @notice Returns the current week
185      function getCurrentWeek() external view returns (uint256) {
186          return _timestampToWeek(block.timestamp);
187      }
188  
189      /// @notice Returns the current week emission
190      function getCurrentWeekEmission() external view returns (uint256) {
191          return emissionForWeek[_timestampToWeek(block.timestamp)];
192      }
193  
194      ///-- Write methods --
195      /// @notice Emit the TAP for the current week
196      /// @return the emitted amount
197      function emitForWeek() external notPaused returns (uint256) {
198          require(_getChainId() == governanceChainIdentifier, "chain not valid");
199  
200          uint256 week = _timestampToWeek(block.timestamp);
201          if (emissionForWeek[week] > 0) return 0;
202  
203          // Update DSO supply from last minted emissions
204          dso_supply -= mintedInWeek[week - 1];
205  
206          // Compute unclaimed emission from last week and add it to the current week emission
207          uint256 unclaimed = emissionForWeek[week - 1] - mintedInWeek[week - 1];
208          uint256 emission = uint256(_computeEmission());
209          emission += unclaimed;
210          emissionForWeek[week] = emission;
211  
212          emit Emitted(week, emission);
213  
214          return emission;
215      }
216  
217      /// @notice extracts from the minted TAP
218      /// @param _to Address to send the minted TAP to
219      /// @param _amount TAP amount
220      function extractTAP(address _to, uint256 _amount) external notPaused {
221          require(msg.sender == minter, "unauthorized");
222          require(_amount > 0, "amount not valid");
223  
224          uint256 week = _timestampToWeek(block.timestamp);
225          require(emissionForWeek[week] >= _amount, "exceeds allowable amount");
226          _mint(_to, _amount);
227          mintedInWeek[week] += _amount;
228          emit Minted(msg.sender, _to, _amount);
229      }
230  
231      /// @notice burns TAP
232      /// @param _amount TAP amount
233      function removeTAP(uint256 _amount) external notPaused {
234          _burn(msg.sender, _amount);
235          emit Burned(msg.sender, _amount);
236      }
237  
238      ///-- Internal methods --
239      function _timestampToWeek(
240          uint256 timestamp
241      ) internal view returns (uint256) {
242          return ((timestamp - emissionsStartTime) / WEEK) + 1; // Starts at week 1
243      }
244  
245      ///-- Private methods --
246      /// @notice Return the current chain ID.
247      /// @dev Useful for testing.
248      function _getChainId() private view returns (uint256) {
249          return block.chainid;
250      }
251  
252      /// @notice returns the available emissions for a given supply
253      function _computeEmission() internal view returns (uint256 result) {
254          result = (dso_supply * decay_rate) / DECAY_RATE_DECIMAL;
255      }
256: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L26-L256

File: contracts/Swapper/UniswapV3Swapper.sol

28   contract UniswapV3Swapper is BaseSwapper {
29       using SafeERC20 for IERC20;
30   
31       // ************ //
32       // *** VARS *** //
33       // ************ //
34       IYieldBox private immutable yieldBox;
35       ISwapRouter public immutable swapRouter;
36       IUniswapV3Factory public immutable factory;
37   
38       uint24 public poolFee = 3000;
39   
40       // ************** //
41       // *** EVENTS *** //
42       // ************** //
43       event PoolFee(uint256 _old, uint256 _new);
44   
45       constructor(
46           IYieldBox _yieldBox,
47           ISwapRouter _swapRouter,
48           IUniswapV3Factory _factory
49       )
50           validAddress(address(_yieldBox))
51           validAddress(address(_swapRouter))
52           validAddress(address(_factory))
53       {
54           yieldBox = _yieldBox;
55           swapRouter = _swapRouter;
56           factory = _factory;
57       }
58   
59       /// *** OWNER METHODS ***
60       /// ***  ***
61       function setPoolFee(uint24 _newFee) external onlyOwner {
62           emit PoolFee(poolFee, _newFee);
63           poolFee = _newFee;
64       }
65   
66       /// *** VIEW METHODS ***
67       /// ***  ***
68       /// @notice returns default bytes swap data
69       function getDefaultDexOptions()
70           public
71           view
72           override
73           returns (bytes memory)
74       {
75           return abi.encode(block.timestamp + 1 hours);
76       }
77   
78       /// @notice Computes amount out for amount in
79       /// @param swapData operation data
80       function getOutputAmount(
81           SwapData calldata swapData,
82           bytes calldata
83       ) external view override returns (uint256 amountOut) {
84           (address tokenIn, address tokenOut) = _getTokens(
85               swapData.tokensData,
86               yieldBox
87           );
88   
89           (uint256 amountIn, ) = _getAmounts(
90               swapData.amountData,
91               swapData.tokensData.tokenInId,
92               swapData.tokensData.tokenOutId,
93               yieldBox
94           );
95   
96           address pool = factory.getPool(tokenIn, tokenOut, poolFee);
97           (int24 tick, ) = OracleLibrary.consult(pool, 60);
98   
99           amountOut = OracleLibrary.getQuoteAtTick(
100              tick,
101              uint128(amountIn),
102              tokenIn,
103              tokenOut
104          );
105      }
106  
107      /// @notice Comutes amount in for amount out
108      function getInputAmount(
109          SwapData calldata swapData,
110          bytes calldata
111      ) external view override returns (uint256 amountIn) {
112          (address tokenIn, address tokenOut) = _getTokens(
113              swapData.tokensData,
114              yieldBox
115          );
116  
117          (, uint256 amountOut) = _getAmounts(
118              swapData.amountData,
119              swapData.tokensData.tokenInId,
120              swapData.tokensData.tokenOutId,
121              yieldBox
122          );
123  
124          address pool = factory.getPool(tokenIn, tokenOut, poolFee);
125  
126          (int24 tick, ) = OracleLibrary.consult(pool, 60);
127          amountIn = OracleLibrary.getQuoteAtTick(
128              tick,
129              uint128(amountOut),
130              tokenOut,
131              tokenIn
132          );
133      }
134  
135      /// *** PUBLIC METHODS ***
136      /// ***  ***
137      /// @notice swaps amount in
138      /// @param swapData operation data
139      /// @param amountOutMin min amount out to receive
140      /// @param to receiver address
141      /// @param data AMM data
142      function swap(
143          SwapData calldata swapData,
144          uint256 amountOutMin,
145          address to,
146          bytes memory data
147      ) external override returns (uint256 amountOut, uint256 shareOut) {
148          // Get tokens' addresses
149          (address tokenIn, address tokenOut) = _getTokens(
150              swapData.tokensData,
151              yieldBox
152          );
153  
154          // Get tokens' amounts
155          (uint256 amountIn, ) = _getAmounts(
156              swapData.amountData,
157              swapData.tokensData.tokenInId,
158              swapData.tokensData.tokenOutId,
159              yieldBox
160          );
161  
162          // Retrieve tokens from sender or from YieldBox
163          amountIn = _extractTokens(
164              swapData.yieldBoxData,
165              yieldBox,
166              tokenIn,
167              swapData.tokensData.tokenInId,
168              amountIn,
169              swapData.amountData.shareIn
170          );
171  
172          TransferHelper.safeApprove(tokenIn, address(swapRouter), amountIn);
173  
174          // Perform the swap operation
175          if (data.length == 0) {
176              data = getDefaultDexOptions();
177          }
178          uint256 deadline = abi.decode(data, (uint256));
179  
180          ISwapRouter.ExactInputSingleParams memory params = ISwapRouter
181              .ExactInputSingleParams({
182                  tokenIn: tokenIn,
183                  tokenOut: tokenOut,
184                  fee: poolFee,
185                  recipient: swapData.yieldBoxData.depositToYb
186                      ? address(this)
187                      : to,
188                  deadline: deadline,
189                  amountIn: amountIn,
190                  amountOutMinimum: amountOutMin,
191                  sqrtPriceLimitX96: 0
192              });
193  
194          // Compute outputs
195          amountOut = swapRouter.exactInputSingle(params);
196          if (swapData.yieldBoxData.depositToYb) {
197              _safeApprove(tokenOut, address(yieldBox), amountOut);
198              (, shareOut) = yieldBox.depositAsset(
199                  swapData.tokensData.tokenOutId,
200                  address(this),
201                  to,
202                  amountOut,
203                  0
204              );
205          }
206      }
207: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L28-L207

File: contracts/NativeTokenFactory.sol

21   contract NativeTokenFactory is AssetRegister {
22       using BoringMath for uint256;
23   
24       mapping(uint256 => NativeToken) public nativeTokens;
25       mapping(uint256 => address) public owner;
26       mapping(uint256 => address) public pendingOwner;
27   
28       event TokenCreated(address indexed creator, string name, string symbol, uint8 decimals, uint256 tokenId);
29       event OwnershipTransferred(uint256 indexed tokenId, address indexed previousOwner, address indexed newOwner);
30   
31       // ***************** //
32       // *** MODIFIERS *** //
33       // ***************** //
34   
35       /// Modifier to check if the msg.sender is allowed to use funds belonging to the 'from' address.
36       /// If 'from' is msg.sender, it's allowed.
37       /// If 'msg.sender' is an address (an operator) that is approved by 'from', it's allowed.
38       modifier allowed(address _from, uint256 _id) {
39           _requireTransferAllowed(_from, isApprovedForAsset[_from][msg.sender][_id]);
40           _;
41       }
42   
43       /// @notice Only allows the `owner` to execute the function.
44       /// @param tokenId The `tokenId` that the sender has to be owner of.
45       modifier onlyOwner(uint256 tokenId) {
46           require(msg.sender == owner[tokenId], "NTF: caller is not the owner");
47           _;
48       }
49   
50       /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner.
51       /// Can only be invoked by the current `owner`.
52       /// @param tokenId The `tokenId` of the token that ownership whose ownership will be transferred/renounced.
53       /// @param newOwner Address of the new owner.
54       /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`.
55       /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise.
56       function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {
57           if (direct) {
58               // Checks
59               require(newOwner != address(0) || renounce, "NTF: zero address");
60   
61               // Effects
62               emit OwnershipTransferred(tokenId, owner[tokenId], newOwner);
63               owner[tokenId] = newOwner;
64               pendingOwner[tokenId] = address(0);
65           } else {
66               // Effects
67               pendingOwner[tokenId] = newOwner;
68           }
69       }
70   
71       /// @notice Needs to be called by `pendingOwner` to claim ownership.
72       /// @param tokenId The `tokenId` of the token that ownership is claimed for.
73       function claimOwnership(uint256 tokenId) public {
74           address _pendingOwner = pendingOwner[tokenId];
75   
76           // Checks
77           require(msg.sender == _pendingOwner, "NTF: caller != pending owner");
78   
79           // Effects
80           emit OwnershipTransferred(tokenId, owner[tokenId], _pendingOwner);
81           owner[tokenId] = _pendingOwner;
82           pendingOwner[tokenId] = address(0);
83       }
84   
85       /// @notice Create a new native token. This will be an ERC1155 token. If later it's needed as an ERC20 token it can
86       /// be wrapped into an ERC20 token. Native support for ERC1155 tokens is growing though.
87       /// @param name The name of the token.
88       /// @param symbol The symbol of the token.
89       /// @param decimals The number of decimals of the token (this is just for display purposes). Should be set to 18 in normal cases.
90       function createToken(string calldata name, string calldata symbol, uint8 decimals, string calldata uri) public returns (uint32 tokenId) {
91           // To keep each Token unique in the AssetRegister, we use the assetId as the tokenId. So for native assets, the tokenId is always equal to the assetId.
92           tokenId = assets.length.to32();
93           _registerAsset(TokenType.Native, address(0), NO_STRATEGY, tokenId);
94           // Initial supply is 0, use owner can mint. For a fixed supply the owner can mint and revoke ownership.
95           // The msg.sender is the initial owner, can be changed after.
96           nativeTokens[tokenId] = NativeToken(name, symbol, decimals, uri);
97           owner[tokenId] = msg.sender;
98   
99           emit TokenCreated(msg.sender, name, symbol, decimals, tokenId);
100          emit TransferSingle(msg.sender, address(0), address(0), tokenId, 0);
101          emit OwnershipTransferred(tokenId, address(0), msg.sender);
102      }
103  
104      /// @notice The `owner` can mint tokens. If a fixed supply is needed, the `owner` should mint the totalSupply and renounce ownership.
105      /// @param tokenId The token to be minted.
106      /// @param to The account to transfer the minted tokens to.
107      /// @param amount The amount of tokens to mint.
108      /// @dev For security reasons, operators are not allowed to mint. Only the actual owner can do this. Of course the owner can be a contract.
109      function mint(uint256 tokenId, address to, uint256 amount) public onlyOwner(tokenId) {
110          _mint(to, tokenId, amount);
111      }
112  
113      /// @notice Burns tokens. Only the holder of tokens can burn them or an approved operator.
114      /// @param tokenId The token to be burned.
115      /// @param amount The amount of tokens to burn.
116      function burn(uint256 tokenId, address from, uint256 amount) public allowed(from, tokenId) {
117          require(assets[tokenId].tokenType == TokenType.Native, "NTF: Not native");
118          _burn(from, tokenId, amount);
119      }
120  
121      /// @notice The `owner` can mint tokens. If a fixed supply is needed, the `owner` should mint the totalSupply and renounce ownership.
122      /// @param tokenId The token to be minted.
123      /// @param tos The accounts to transfer the minted tokens to.
124      /// @param amounts The amounts of tokens to mint.
125      /// @dev If the tos array is longer than the amounts array there will be an out of bounds error. If the amounts array is longer, the extra amounts are simply ignored.
126      /// @dev For security reasons, operators are not allowed to mint. Only the actual owner can do this. Of course the owner can be a contract.
127      function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {
128          uint256 len = tos.length;
129          for (uint256 i = 0; i < len; i++) {
130              _mint(tos[i], tokenId, amounts[i]);
131          }
132      }
133  
134      /// @notice Burns tokens. This is only useful to be used by an operator.
135      /// @param tokenId The token to be burned.
136      /// @param froms The accounts to burn tokens from.
137      /// @param amounts The amounts of tokens to burn.
138      function batchBurn(uint256 tokenId, address[] calldata froms, uint256[] calldata amounts) public {
139          require(assets[tokenId].tokenType == TokenType.Native, "NTF: Not native");
140          uint256 len = froms.length;
141          for (uint256 i = 0; i < len; i++) {
142              _requireTransferAllowed(froms[i], isApprovedForAsset[froms[i]][msg.sender][tokenId]);
143              _burn(froms[i], tokenId, amounts[i]);
144          }
145      }
146: }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L21-L146

[N‑13] Events may be emitted out of order due to reentrancy

Ensure that events follow the best practice of check-effects-interaction, and are emitted before external calls

There are 23 instances of this issue:

see instances
File: contracts/markets/bigBang/BigBang.sol

/// @audit swappers() prior to emission of Liquidated()
629          emit Liquidated(
630              msg.sender,
631              _users,
632              callerShare,
633              feeShare,
634              borrowAmount,
635              collateralShare
636:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L629-L636

File: contracts/markets/singularity/SGLLiquidation.sol

/// @audit swappers() prior to emission of Liquidated()
360          emit Liquidated(
361              msg.sender,
362              _users,
363              callerShare,
364              feeShare,
365              borrowAmount,
366              collateralShare
367:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L360-L367

File: contracts/usd0/modules/USDOLeverageModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
187:         emit ReceiveFromChain(_srcChainId, leverageFor, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L187-L187

File: contracts/usd0/modules/USDOMarketModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
188:         emit ReceiveFromChain(_srcChainId, to, lendParams.depositAmount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L188-L188

File: contracts/usd0/modules/USDOOptionsModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
199          emit ReceiveFromChain(
200              _srcChainId,
201              optionsData.from,
202              optionsData.paymentTokenAmount
203:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L199-L203

File: contracts/TapiocaWrapper.sol

/// @audit push() prior to emission of CreateOFT()
177:         emit CreateOFT(iOFT, _erc20);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L177-L177

File: contracts/tOFT/mTapiocaOFT.sol

/// @audit safeTransfer() prior to emission of Rebalancing()
151:         emit Rebalancing(msg.sender, _amount, _isNative);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L151-L151

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
202:         emit ReceiveFromChain(_srcChainId, leverageFor, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L202-L202

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
177:         emit ReceiveFromChain(_srcChainId, _from, borrowParams.amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L177-L177

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
214          emit ReceiveFromChain(
215              _srcChainId,
216              optionsData.from,
217              optionsData.paymentTokenAmount
218:         );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L214-L218

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

/// @audit safeTransfer() prior to emission of ReceiveFromChain()
170:         emit ReceiveFromChain(_srcChainId, onBehalfOf, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L170-L170

File: contracts/Vesting.sol

/// @audit safeTransfer() prior to emission of Claimed()
120:         emit Claimed(msg.sender, _claimable);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L120-L120

File: contracts/aave/AaveStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
274:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L274-L274

File: contracts/balancer/BalancerStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
215:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L215-L215

File: contracts/compound/CompoundStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
161:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L161-L161

File: contracts/convex/ConvexTricryptoStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
351:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L351-L351

File: contracts/curve/TricryptoLPStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
253:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L253-L253

File: contracts/curve/TricryptoNativeStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
244:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L244-L244

File: contracts/lido/LidoEthStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
166:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L166-L166

File: contracts/stargate/StargateStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
268:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L268-L268

File: contracts/yearn/YearnStrategy.sol

/// @audit safeTransfer() prior to emission of AmountWithdrawn()
149:         emit AmountWithdrawn(to, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L149-L149

File: contracts/YieldBox.sol

/// @audit safeTransferFrom() prior to emission of Deposited()
157:         emit Deposited(msg.sender, from, to, assetId, amount, share, amountOut, shareOut, false);

/// @audit safeTransfer() prior to emission of Deposited()
212:         emit Deposited(msg.sender, msg.sender, to, assetId, amount, share, amountOut, shareOut, false);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L157-L157

[N‑14] Function names should use lowerCamelCase

According to the Solidity style guide function names should be in mixedCase (lowerCamelCase)

There are 17 instances of this issue:

File: contracts/markets/Market.sol

305      function computeTVLInfo(
306          address user,
307          uint256 _exchangeRate
308      )
309          public
310          view
311          returns (uint256 amountToSolvency, uint256 minTVL, uint256 maxTVL)
312:     {

428      function _computeMaxAndMinLTVInAsset(
429          uint256 collateralShare,
430          uint256 _exchangeRate
431:     ) internal view returns (uint256 min, uint256 max) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L305-L312

File: contracts/TapiocaWrapper.sol

75:      function tapiocaOFTLength() external view returns (uint256) {

85:      function lastTOFT() external view returns (ITapiocaOFT) {

115      function executeTOFT(
116          address _toft,
117          bytes calldata _bytecode,
118          bool _revertOnFailure
119:     ) external payable onlyOwner returns (bool success, bytes memory result) {

154      function createTOFT(
155          address _erc20,
156          bytes calldata _bytecode,
157          bytes32 _salt,
158          bool _linked
159:     ) external onlyOwner {

183      function _createTOFT(
184          address _erc20,
185          bytes calldata _bytecode,
186          bytes32 _salt,
187          bool _linked
188:     ) private returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L75-L75

File: contracts/option-airdrop/AirdropBroker.sol

141      function getOTCDealDetails(
142          uint256 _aoTAPTokenID,
143          ERC20 _paymentToken,
144          uint256 _tapAmount
145      )
146          external
147          view
148          returns (
149              uint256 eligibleTapAmount,
150              uint256 paymentTokenAmount,
151              uint256 tapAmount
152          )
153:     {

297:     function aoTAPBrokerClaim() external {

487      function _processOTCDeal(
488          ERC20 _paymentToken,
489          PaymentTokenOracle memory _paymentTokenOracle,
490          uint256 tapAmount,
491          uint256 discount
492:     ) internal {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L141-L153

File: contracts/options/TapiocaOptionBroker.sol

145      function getOTCDealDetails(
146          uint256 _oTAPTokenID,
147          ERC20 _paymentToken,
148          uint256 _tapAmount
149      )
150          external
151          view
152          returns (
153              uint256 eligibleTapAmount,
154              uint256 paymentTokenAmount,
155              uint256 tapAmount
156          )
157:     {

435:     function oTAPBrokerClaim() external {

508      function _processOTCDeal(
509          ERC20 _paymentToken,
510          PaymentTokenOracle memory _paymentTokenOracle,
511          uint256 tapAmount,
512          uint256 discount
513:     ) internal {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L145-L157

File: contracts/options/TapiocaOptionLiquidityProvision.sol

259      function setSGLPoolWEight(
260          IERC20 singularity,
261          uint256 weight
262:     ) external onlyOwner updateTotalSGLPoolWeights {

336:     function _computeSGLPoolWeights() internal view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L259-L262

File: contracts/YieldBox.sol

168      function depositNFTAsset(
169          uint256 assetId,
170          address from,
171          address to
172:     ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

196:     function depositETHAsset(uint256 assetId, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L168-L172

[N‑15] Consider bounding input array length

The functions below take in an unbounded array, and make function calls for entries in the array. While the function will revert if it eventually runs out of gas, it may be a nicer user experience to require() that the length of the array is below some reasonable maximum, so that the user doesn't have to use up a full transaction's gas only to see that the transaction reverts.

There are 29 instances of this issue:

see instances
File: contracts/Penrose.sol

437          for (uint256 i = 0; i < len; ) {
438              require(
439                  isSingularityMasterContractRegistered[
440                      masterContractOf[mc[i]]
441                  ] || isBigBangMasterContractRegistered[masterContractOf[mc[i]]],
442                  "Penrose: MC not registered"
443              );
444              (success[i], result[i]) = mc[i].call(data[i]);
445              if (forceSuccess) {
446                  require(success[i], _getRevertMsg(result[i]));
447              }
448              ++i;
449:         }

492              for (uint256 i = 0; i < length; ) {
493                  _depositFeesToYieldBox(markets_[i], swappers_[i], swapData_[i]);
494                  ++i;
495:             }

550              for (uint256 i = 0; i < _masterContractLength; ) {
551                  marketsLength += clonesOfCount(array[i].location);
552  
553                  ++i;
554:             }

564              for (uint256 i = 0; i < _masterContractLength; ) {
565                  address mcLocation = array[i].location;
566                  clonesOfLength = clonesOfCount(mcLocation);
567  
568                  // Loop through clones of the current MC.
569                  for (uint256 j = 0; j < clonesOfLength; ) {
570                      markets[marketIndex] = clonesOf[mcLocation][j];
571                      ++marketIndex;
572                      ++j;
573                  }
574                  ++i;
575:             }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L437-L449

File: contracts/markets/bigBang/BigBang.sol

215          for (uint256 i = 0; i < calls.length; i++) {
216              (bool success, bytes memory result) = address(this).delegatecall(
217                  calls[i]
218              );
219              require(success || !revertOnFail, _getRevertMsg(result));
220              successes[i] = success;
221              results[i] = _getRevertMsg(result);
222:         }

666          for (uint256 i = 0; i < users.length; i++) {
667              address user = users[i];
668              if (!_isSolvent(user, _exchangeRate)) {
669                  liquidatedCount++;
670                  _liquidateUser(
671                      user,
672                      maxBorrowParts[i],
673                      swapper,
674                      _exchangeRate,
675                      swapData
676                  );
677              }
678:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L215-L222

File: contracts/markets/singularity/SGLLiquidation.sol

107          for (uint256 i = 0; i < users.length; i++) {
108              address user = users[i];
109              if (!_isSolvent(user, _exchangeRate)) {
110                  uint256 borrowAmount = _computeAssetAmountToSolvency(
111                      user,
112                      _exchangeRate
113                  );
114  
115                  if (borrowAmount == 0) {
116                      continue;
117                  }
118  
119                  uint256 borrowPart;
120                  {
121                      uint256 availableBorrowPart = userBorrowPart[user];
122                      borrowPart = _totalBorrow.toBase(borrowAmount, false);
123                      userBorrowPart[user] = availableBorrowPart - borrowPart;
124                  }
125                  uint256 amountWithBonus = borrowAmount +
126                      (borrowAmount * liquidationMultiplier) /
127                      FEE_PRECISION;
128                  uint256 collateralShare = yieldBox.toShare(
129                      collateralId,
130                      (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,
131                      false
132                  );
133                  userCollateralShare[user] -= collateralShare;
134                  emit LogRemoveCollateral(
135                      user,
136                      address(liquidationQueue),
137                      collateralShare
138                  );
139                  emit LogRepay(
140                      address(liquidationQueue),
141                      user,
142                      borrowAmount,
143                      borrowPart
144                  );
145  
146                  // Keep totals
147                  allCollateralShare += collateralShare;
148                  allBorrowAmount += borrowAmount;
149                  allBorrowPart += borrowPart;
150              }
151:         }

384          for (uint256 i = 0; i < users.length; i++) {
385              address user = users[i];
386              if (!_isSolvent(user, _exchangeRate)) {
387                  liquidatedCount++;
388                  _liquidateUser(
389                      user,
390                      maxBorrowParts[i],
391                      swapper,
392                      _exchangeRate,
393                      swapData
394                  );
395              }
396:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L107-L151

File: contracts/markets/singularity/Singularity.sol

187          for (uint256 i = 0; i < calls.length; i++) {
188              (bool success, bytes memory result) = address(this).delegatecall(
189                  calls[i]
190              );
191              require(success || !revertOnFail, _getRevertMsg(result));
192              successes[i] = success;
193              results[i] = _getRevertMsg(result);
194:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L187-L194

File: contracts/usd0/modules/USDOLeverageModule.sol

255          for (uint256 i = 0; i < approvals.length; ) {
256              if (approvals[i].permitBorrow) {
257                  try
258                      IPermitBorrow(approvals[i].target).permitBorrow(
259                          approvals[i].owner,
260                          approvals[i].spender,
261                          approvals[i].value,
262                          approvals[i].deadline,
263                          approvals[i].v,
264                          approvals[i].r,
265                          approvals[i].s
266                      )
267                  {} catch Error(string memory reason) {
268                      if (!approvals[i].allowFailure) {
269                          revert(reason);
270                      }
271                  }
272              } else if (approvals[i].permitAll) {
273                  try
274                      IPermitAll(approvals[i].target).permitAll(
275                          approvals[i].owner,
276                          approvals[i].spender,
277                          approvals[i].deadline,
278                          approvals[i].v,
279                          approvals[i].r,
280                          approvals[i].s
281                      )
282                  {} catch Error(string memory reason) {
283                      if (!approvals[i].allowFailure) {
284                          revert(reason);
285                      }
286                  }
287              } else {
288                  try
289                      IERC20Permit(approvals[i].target).permit(
290                          approvals[i].owner,
291                          approvals[i].spender,
292                          approvals[i].value,
293                          approvals[i].deadline,
294                          approvals[i].v,
295                          approvals[i].r,
296                          approvals[i].s
297                      )
298                  {} catch Error(string memory reason) {
299                      if (!approvals[i].allowFailure) {
300                          revert(reason);
301                      }
302                  }
303              }
304  
305              unchecked {
306                  ++i;
307              }
308:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L255-L308

File: contracts/usd0/modules/USDOMarketModule.sol

244          for (uint256 i = 0; i < approvals.length; ) {
245              if (approvals[i].permitBorrow) {
246                  try
247                      IPermitBorrow(approvals[i].target).permitBorrow(
248                          approvals[i].owner,
249                          approvals[i].spender,
250                          approvals[i].value,
251                          approvals[i].deadline,
252                          approvals[i].v,
253                          approvals[i].r,
254                          approvals[i].s
255                      )
256                  {} catch Error(string memory reason) {
257                      if (!approvals[i].allowFailure) {
258                          revert(reason);
259                      }
260                  }
261              } else if (approvals[i].permitAll) {
262                  try
263                      IPermitAll(approvals[i].target).permitAll(
264                          approvals[i].owner,
265                          approvals[i].spender,
266                          approvals[i].deadline,
267                          approvals[i].v,
268                          approvals[i].r,
269                          approvals[i].s
270                      )
271                  {} catch Error(string memory reason) {
272                      if (!approvals[i].allowFailure) {
273                          revert(reason);
274                      }
275                  }
276              } else {
277                  try
278                      IERC20Permit(approvals[i].target).permit(
279                          approvals[i].owner,
280                          approvals[i].spender,
281                          approvals[i].value,
282                          approvals[i].deadline,
283                          approvals[i].v,
284                          approvals[i].r,
285                          approvals[i].s
286                      )
287                  {} catch Error(string memory reason) {
288                      if (!approvals[i].allowFailure) {
289                          revert(reason);
290                      }
291                  }
292              }
293  
294              unchecked {
295                  ++i;
296              }
297:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L244-L297

File: contracts/usd0/modules/USDOOptionsModule.sol

245          for (uint256 i = 0; i < approvals.length; ) {
246              if (approvals[i].permitBorrow) {
247                  try
248                      IPermitBorrow(approvals[i].target).permitBorrow(
249                          approvals[i].owner,
250                          approvals[i].spender,
251                          approvals[i].value,
252                          approvals[i].deadline,
253                          approvals[i].v,
254                          approvals[i].r,
255                          approvals[i].s
256                      )
257                  {} catch Error(string memory reason) {
258                      if (!approvals[i].allowFailure) {
259                          revert(reason);
260                      }
261                  }
262              } else if (approvals[i].permitAll) {
263                  try
264                      IPermitAll(approvals[i].target).permitAll(
265                          approvals[i].owner,
266                          approvals[i].spender,
267                          approvals[i].deadline,
268                          approvals[i].v,
269                          approvals[i].r,
270                          approvals[i].s
271                      )
272                  {} catch Error(string memory reason) {
273                      if (!approvals[i].allowFailure) {
274                          revert(reason);
275                      }
276                  }
277              } else {
278                  try
279                      IERC20Permit(approvals[i].target).permit(
280                          approvals[i].owner,
281                          approvals[i].spender,
282                          approvals[i].value,
283                          approvals[i].deadline,
284                          approvals[i].v,
285                          approvals[i].r,
286                          approvals[i].s
287                      )
288                  {} catch Error(string memory reason) {
289                      if (!approvals[i].allowFailure) {
290                          revert(reason);
291                      }
292                  }
293              }
294  
295              unchecked {
296                  ++i;
297              }
298:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L245-L298

File: contracts/TapiocaWrapper.sol

140          for (uint256 i = 0; i < _call.length; i++) {
141              (success, results[i]) = payable(_call[i].toft).call{
142                  value: msg.value
143              }(_call[i].bytecode);
144              if (_call[i].revertOnFailure && !success) {
145                  revert TapiocaWrapper__TOFTExecutionFailed(results[i]);
146              }
147:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L140-L147

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

285          for (uint256 i = 0; i < approvals.length; ) {
286              if (approvals[i].permitBorrow) {
287                  try
288                      IPermitBorrow(approvals[i].target).permitBorrow(
289                          approvals[i].owner,
290                          approvals[i].spender,
291                          approvals[i].value,
292                          approvals[i].deadline,
293                          approvals[i].v,
294                          approvals[i].r,
295                          approvals[i].s
296                      )
297                  {} catch Error(string memory reason) {
298                      if (!approvals[i].allowFailure) {
299                          revert(reason);
300                      }
301                  }
302              } else if (approvals[i].permitAll) {
303                  try
304                      IPermitAll(approvals[i].target).permitAll(
305                          approvals[i].owner,
306                          approvals[i].spender,
307                          approvals[i].deadline,
308                          approvals[i].v,
309                          approvals[i].r,
310                          approvals[i].s
311                      )
312                  {} catch Error(string memory reason) {
313                      if (!approvals[i].allowFailure) {
314                          revert(reason);
315                      }
316                  }
317              } else {
318                  try
319                      IERC20Permit(approvals[i].target).permit(
320                          approvals[i].owner,
321                          approvals[i].spender,
322                          approvals[i].value,
323                          approvals[i].deadline,
324                          approvals[i].v,
325                          approvals[i].r,
326                          approvals[i].s
327                      )
328                  {} catch Error(string memory reason) {
329                      if (!approvals[i].allowFailure) {
330                          revert(reason);
331                      }
332                  }
333              }
334  
335              unchecked {
336                  ++i;
337              }
338:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L285-L338

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

261          for (uint256 i = 0; i < approvals.length; ) {
262              if (approvals[i].permitBorrow) {
263                  try
264                      IPermitBorrow(approvals[i].target).permitBorrow(
265                          approvals[i].owner,
266                          approvals[i].spender,
267                          approvals[i].value,
268                          approvals[i].deadline,
269                          approvals[i].v,
270                          approvals[i].r,
271                          approvals[i].s
272                      )
273                  {} catch Error(string memory reason) {
274                      if (!approvals[i].allowFailure) {
275                          revert(reason);
276                      }
277                  }
278              } else if (approvals[i].permitAll) {
279                  try
280                      IPermitAll(approvals[i].target).permitAll(
281                          approvals[i].owner,
282                          approvals[i].spender,
283                          approvals[i].deadline,
284                          approvals[i].v,
285                          approvals[i].r,
286                          approvals[i].s
287                      )
288                  {} catch Error(string memory reason) {
289                      if (!approvals[i].allowFailure) {
290                          revert(reason);
291                      }
292                  }
293              } else {
294                  try
295                      IERC20Permit(approvals[i].target).permit(
296                          approvals[i].owner,
297                          approvals[i].spender,
298                          approvals[i].value,
299                          approvals[i].deadline,
300                          approvals[i].v,
301                          approvals[i].r,
302                          approvals[i].s
303                      )
304                  {} catch Error(string memory reason) {
305                      if (!approvals[i].allowFailure) {
306                          revert(reason);
307                      }
308                  }
309              }
310  
311              unchecked {
312                  ++i;
313              }
314:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L261-L314

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

260          for (uint256 i = 0; i < approvals.length; ) {
261              if (approvals[i].permitBorrow) {
262                  try
263                      IPermitBorrow(approvals[i].target).permitBorrow(
264                          approvals[i].owner,
265                          approvals[i].spender,
266                          approvals[i].value,
267                          approvals[i].deadline,
268                          approvals[i].v,
269                          approvals[i].r,
270                          approvals[i].s
271                      )
272                  {} catch Error(string memory reason) {
273                      if (!approvals[i].allowFailure) {
274                          revert(reason);
275                      }
276                  }
277              } else if (approvals[i].permitAll) {
278                  try
279                      IPermitAll(approvals[i].target).permitAll(
280                          approvals[i].owner,
281                          approvals[i].spender,
282                          approvals[i].deadline,
283                          approvals[i].v,
284                          approvals[i].r,
285                          approvals[i].s
286                      )
287                  {} catch Error(string memory reason) {
288                      if (!approvals[i].allowFailure) {
289                          revert(reason);
290                      }
291                  }
292              } else {
293                  try
294                      IERC20Permit(approvals[i].target).permit(
295                          approvals[i].owner,
296                          approvals[i].spender,
297                          approvals[i].value,
298                          approvals[i].deadline,
299                          approvals[i].v,
300                          approvals[i].r,
301                          approvals[i].s
302                      )
303                  {} catch Error(string memory reason) {
304                      if (!approvals[i].allowFailure) {
305                          revert(reason);
306                      }
307                  }
308              }
309  
310              unchecked {
311                  ++i;
312              }
313:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L260-L313

File: contracts/governance/twTAP.sol

507              for (uint256 i = 0; i < len; ) {
508                  uint256 claimableIndex = rewardTokenIndex[_rewardTokens[i]];
509                  uint256 amount = amounts[i];
510  
511                  if (amount > 0) {
512                      // Math is safe: `amount` calculated safely in `claimable()`
513                      claimed[_tokenId][claimableIndex] += amount;
514                      rewardTokens[claimableIndex].safeTransfer(_to, amount);
515                  }
516                  ++i;
517:             }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L507-L517

File: contracts/option-airdrop/AirdropBroker.sol

375              for (uint256 i = 0; i < len; ++i) {
376                  ERC20 paymentToken = ERC20(_paymentTokens[i]);
377                  paymentToken.transfer(
378                      paymentTokenBeneficiary,
379                      paymentToken.balanceOf(address(this))
380                  );
381:             }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L375-L381

File: contracts/options/TapiocaOptionBroker.sol

489              for (uint256 i = 0; i < len; ++i) {
490                  ERC20 paymentToken = ERC20(_paymentTokens[i]);
491                  paymentToken.transfer(
492                      paymentTokenBeneficiary,
493                      paymentToken.balanceOf(address(this))
494                  );
495:             }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L489-L495

File: contracts/tokens/BaseTapOFT.sol

333          for (uint256 i = 0; i < approvals.length; ) {
334              try
335                  IERC20Permit(approvals[i].target).permit(
336                      approvals[i].owner,
337                      approvals[i].spender,
338                      approvals[i].value,
339                      approvals[i].deadline,
340                      approvals[i].v,
341                      approvals[i].r,
342                      approvals[i].s
343                  )
344              {} catch Error(string memory reason) {
345                  if (!approvals[i].allowFailure) {
346                      revert(reason);
347                  }
348              }
349  
350              unchecked {
351                  ++i;
352              }
353:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L333-L353

File: contracts/Magnetar/MagnetarV2.sol

202          for (uint256 i = 0; i < length; i++) {
203              Call calldata _action = calls[i];
204              if (!_action.allowFailure) {
205                  require(
206                      _action.call.length > 0,
207                      string.concat(
208                          "MagnetarV2: Missing call for action with index",
209                          string(abi.encode(i))
210                      )
211                  );
212              }
213  
214              unchecked {
215                  valAccumulator += _action.value;
216              }
217  
218              if (_action.id == PERMIT_ALL) {
219                  _permit(
220                      _action.target,
221                      _action.call,
222                      true,
223                      _action.allowFailure
224                  );
225              } else if (_action.id == PERMIT) {
226                  _permit(
227                      _action.target,
228                      _action.call,
229                      false,
230                      _action.allowFailure
231                  );
232              } else if (_action.id == TOFT_WRAP) {
233                  WrapData memory data = abi.decode(_action.call[4:], (WrapData));
234                  _checkSender(data.from);
235                  if (_action.value > 0) {
236                      unchecked {
237                          valAccumulator += _action.value;
238                      }
239                      ITapiocaOFT(_action.target).wrapNative{
240                          value: _action.value
241                      }(data.to);
242                  } else {
243                      ITapiocaOFT(_action.target).wrap(
244                          msg.sender,
245                          data.to,
246                          data.amount
247                      );
248                  }
249              } else if (_action.id == TOFT_SEND_FROM) {
250                  (
251                      address from,
252                      uint16 dstChainId,
253                      bytes32 to,
254                      uint256 amount,
255                      ISendFrom.LzCallParams memory lzCallParams
256                  ) = abi.decode(
257                          _action.call[4:],
258                          (
259                              address,
260                              uint16,
261                              bytes32,
262                              uint256,
263                              (ISendFrom.LzCallParams)
264                          )
265                      );
266                  _checkSender(from);
267  
268                  ISendFrom(_action.target).sendFrom{value: _action.value}(
269                      msg.sender,
270                      dstChainId,
271                      to,
272                      amount,
273                      lzCallParams
274                  );
275              } else if (_action.id == YB_DEPOSIT_ASSET) {
276                  YieldBoxDepositData memory data = abi.decode(
277                      _action.call[4:],
278                      (YieldBoxDepositData)
279                  );
280                  _checkSender(data.from);
281  
282                  (uint256 amountOut, uint256 shareOut) = IYieldBoxBase(
283                      _action.target
284                  ).depositAsset(
285                          data.assetId,
286                          msg.sender,
287                          data.to,
288                          data.amount,
289                          data.share
290                      );
291                  returnData[i] = Result({
292                      success: true,
293                      returnData: abi.encode(amountOut, shareOut)
294                  });
295              } else if (_action.id == MARKET_ADD_COLLATERAL) {
296                  SGLAddCollateralData memory data = abi.decode(
297                      _action.call[4:],
298                      (SGLAddCollateralData)
299                  );
300                  _checkSender(data.from);
301  
302                  IMarket(_action.target).addCollateral(
303                      msg.sender,
304                      data.to,
305                      data.skim,
306                      data.amount,
307                      data.share
308                  );
309              } else if (_action.id == MARKET_BORROW) {
310                  SGLBorrowData memory data = abi.decode(
311                      _action.call[4:],
312                      (SGLBorrowData)
313                  );
314                  _checkSender(data.from);
315  
316                  (uint256 part, uint256 share) = IMarket(_action.target).borrow(
317                      msg.sender,
318                      data.to,
319                      data.amount
320                  );
321                  returnData[i] = Result({
322                      success: true,
323                      returnData: abi.encode(part, share)
324                  });
325              } else if (_action.id == YB_WITHDRAW_TO) {
326                  (
327                      address yieldBox,
328                      address from,
329                      uint256 assetId,
330                      uint16 dstChainId,
331                      bytes32 receiver,
332                      uint256 amount,
333                      uint256 share,
334                      bytes memory adapterParams,
335                      address payable refundAddress
336                  ) = abi.decode(
337                          _action.call[4:],
338                          (
339                              address,
340                              address,
341                              uint256,
342                              uint16,
343                              bytes32,
344                              uint256,
345                              uint256,
346                              bytes,
347                              address
348                          )
349                      );
350  
351                  _executeModule(
352                      Module.Market,
353                      abi.encodeWithSelector(
354                          MagnetarMarketModule.withdrawToChain.selector,
355                          yieldBox,
356                          from,
357                          assetId,
358                          dstChainId,
359                          receiver,
360                          amount,
361                          share,
362                          adapterParams,
363                          refundAddress,
364                          _action.value
365                      )
366                  );
367              } else if (_action.id == MARKET_LEND) {
368                  SGLLendData memory data = abi.decode(
369                      _action.call[4:],
370                      (SGLLendData)
371                  );
372                  _checkSender(data.from);
373  
374                  uint256 fraction = IMarket(_action.target).addAsset(
375                      msg.sender,
376                      data.to,
377                      data.skim,
378                      data.share
379                  );
380                  returnData[i] = Result({
381                      success: true,
382                      returnData: abi.encode(fraction)
383                  });
384              } else if (_action.id == MARKET_REPAY) {
385                  SGLRepayData memory data = abi.decode(
386                      _action.call[4:],
387                      (SGLRepayData)
388                  );
389                  _checkSender(data.from);
390  
391                  uint256 amount = IMarket(_action.target).repay(
392                      msg.sender,
393                      data.to,
394                      data.skim,
395                      data.part
396                  );
397                  returnData[i] = Result({
398                      success: true,
399                      returnData: abi.encode(amount)
400                  });
401              } else if (_action.id == TOFT_SEND_AND_BORROW) {
402                  (
403                      address from,
404                      address to,
405                      uint16 lzDstChainId,
406                      bytes memory airdropAdapterParams,
407                      ITapiocaOFT.IBorrowParams memory borrowParams,
408                      ICommonData.IWithdrawParams memory withdrawParams,
409                      ICommonData.ISendOptions memory options,
410                      ICommonData.IApproval[] memory approvals
411                  ) = abi.decode(
412                          _action.call[4:],
413                          (
414                              address,
415                              address,
416                              uint16,
417                              bytes,
418                              ITapiocaOFT.IBorrowParams,
419                              ICommonData.IWithdrawParams,
420                              ICommonData.ISendOptions,
421                              ICommonData.IApproval[]
422                          )
423                      );
424                  _checkSender(from);
425  
426                  ITapiocaOFT(_action.target).sendToYBAndBorrow{
427                      value: _action.value
428                  }(
429                      msg.sender,
430                      to,
431                      lzDstChainId,
432                      airdropAdapterParams,
433                      borrowParams,
434                      withdrawParams,
435                      options,
436                      approvals
437                  );
438              } else if (_action.id == TOFT_SEND_AND_LEND) {
439                  (
440                      address from,
441                      address to,
442                      uint16 dstChainId,
443                      address zroPaymentAddress,
444                      IUSDOBase.ILendOrRepayParams memory lendParams,
445                      ICommonData.IApproval[] memory approvals,
446                      ICommonData.IWithdrawParams memory withdrawParams,
447                      bytes memory adapterParams
448                  ) = abi.decode(
449                          _action.call[4:],
450                          (
451                              address,
452                              address,
453                              uint16,
454                              address,
455                              (IUSDOBase.ILendOrRepayParams),
456                              (ICommonData.IApproval[]),
457                              (ICommonData.IWithdrawParams),
458                              bytes
459                          )
460                      );
461                  _checkSender(from);
462  
463                  IUSDOBase(_action.target).sendAndLendOrRepay{
464                      value: _action.value
465                  }(
466                      msg.sender,
467                      to,
468                      dstChainId,
469                      zroPaymentAddress,
470                      lendParams,
471                      approvals,
472                      withdrawParams,
473                      adapterParams
474                  );
475              } else if (_action.id == TOFT_DEPOSIT_TO_STRATEGY) {
476                  TOFTSendToStrategyData memory data = abi.decode(
477                      _action.call[4:],
478                      (TOFTSendToStrategyData)
479                  );
480                  _checkSender(data.from);
481  
482                  ITapiocaOFT(_action.target).sendToStrategy{
483                      value: _action.value
484                  }(
485                      msg.sender,
486                      data.to,
487                      data.amount,
488                      data.share,
489                      data.assetId,
490                      data.lzDstChainId,
491                      data.options
492                  );
493              } else if (_action.id == TOFT_RETRIEVE_FROM_STRATEGY) {
494                  (
495                      address from,
496                      uint256 amount,
497                      uint256 share,
498                      uint256 assetId,
499                      uint16 lzDstChainId,
500                      address zroPaymentAddress,
501                      bytes memory airdropAdapterParam
502                  ) = abi.decode(
503                          _action.call[4:],
504                          (
505                              address,
506                              uint256,
507                              uint256,
508                              uint256,
509                              uint16,
510                              address,
511                              bytes
512                          )
513                      );
514  
515                  _checkSender(from);
516  
517                  ITapiocaOFT(_action.target).retrieveFromStrategy{
518                      value: _action.value
519                  }(
520                      msg.sender,
521                      amount,
522                      share,
523                      assetId,
524                      lzDstChainId,
525                      zroPaymentAddress,
526                      airdropAdapterParam
527                  );
528              } else if (_action.id == MARKET_YBDEPOSIT_AND_LEND) {
529                  HelperLendData memory data = abi.decode(
530                      _action.call[4:],
531                      (HelperLendData)
532                  );
533  
534                  _executeModule(
535                      Module.Market,
536                      abi.encodeWithSelector(
537                          MagnetarMarketModule.mintFromBBAndLendOnSGL.selector,
538                          data.user,
539                          data.lendAmount,
540                          data.mintData,
541                          data.depositData,
542                          data.lockData,
543                          data.participateData,
544                          data.externalContracts
545                      )
546                  );
547              } else if (_action.id == MARKET_YBDEPOSIT_COLLATERAL_AND_BORROW) {
548                  (
549                      address market,
550                      address user,
551                      uint256 collateralAmount,
552                      uint256 borrowAmount,
553                      ,
554                      bool deposit,
555                      ICommonData.IWithdrawParams memory withdrawParams
556                  ) = abi.decode(
557                          _action.call[4:],
558                          (
559                              address,
560                              address,
561                              uint256,
562                              uint256,
563                              bool,
564                              bool,
565                              ICommonData.IWithdrawParams
566                          )
567                      );
568  
569                  _executeModule(
570                      Module.Market,
571                      abi.encodeWithSelector(
572                          MagnetarMarketModule
573                              .depositAddCollateralAndBorrowFromMarket
574                              .selector,
575                          market,
576                          user,
577                          collateralAmount,
578                          borrowAmount,
579                          false,
580                          deposit,
581                          withdrawParams
582                      )
583                  );
584              } else if (_action.id == MARKET_REMOVE_ASSET) {
585                  HelperMarketRemoveAndRepayAsset memory data = abi.decode(
586                      _action.call[4:],
587                      (HelperMarketRemoveAndRepayAsset)
588                  );
589  
590                  _executeModule(
591                      Module.Market,
592                      abi.encodeWithSelector(
593                          MagnetarMarketModule
594                              .exitPositionAndRemoveCollateral
595                              .selector,
596                          data.user,
597                          data.externalData,
598                          data.removeAndRepayData
599                      )
600                  );
601              } else if (_action.id == MARKET_DEPOSIT_REPAY_REMOVE_COLLATERAL) {
602                  HelperDepositRepayRemoveCollateral memory data = abi.decode(
603                      _action.call[4:],
604                      (HelperDepositRepayRemoveCollateral)
605                  );
606  
607                  _executeModule(
608                      Module.Market,
609                      abi.encodeWithSelector(
610                          MagnetarMarketModule
611                              .depositRepayAndRemoveCollateralFromMarket
612                              .selector,
613                          data.market,
614                          data.user,
615                          data.depositAmount,
616                          data.repayAmount,
617                          data.collateralAmount,
618                          data.extractFromSender,
619                          data.withdrawCollateralParams
620                      )
621                  );
622              } else if (_action.id == MARKET_BUY_COLLATERAL) {
623                  HelperBuyCollateral memory data = abi.decode(
624                      _action.call[4:],
625                      (HelperBuyCollateral)
626                  );
627  
628                  IMarket(data.market).buyCollateral(
629                      data.from,
630                      data.borrowAmount,
631                      data.supplyAmount,
632                      data.minAmountOut,
633                      address(data.swapper),
634                      data.dexData
635                  );
636              } else if (_action.id == MARKET_SELL_COLLATERAL) {
637                  HelperSellCollateral memory data = abi.decode(
638                      _action.call[4:],
639                      (HelperSellCollateral)
640                  );
641  
642                  IMarket(data.market).sellCollateral(
643                      data.from,
644                      data.share,
645                      data.minAmountOut,
646                      address(data.swapper),
647                      data.dexData
648                  );
649              } else if (_action.id == TAP_EXERCISE_OPTION) {
650                  HelperExerciseOption memory data = abi.decode(
651                      _action.call[4:],
652                      (HelperExerciseOption)
653                  );
654  
655                  ITapiocaOptionsBrokerCrossChain(_action.target).exerciseOption(
656                      data.optionsData,
657                      data.lzData,
658                      data.tapSendData,
659                      data.approvals
660                  );
661              } else if (_action.id == MARKET_MULTIHOP_BUY) {
662                  HelperMultiHopBuy memory data = abi.decode(
663                      _action.call[4:],
664                      (HelperMultiHopBuy)
665                  );
666  
667                  IUSDOBase(_action.target).initMultiHopBuy(
668                      data.from,
669                      data.collateralAmount,
670                      data.borrowAmount,
671                      data.swapData,
672                      data.lzData,
673                      data.externalData,
674                      data.airdropAdapterParams,
675                      data.approvals
676                  );
677              } else if (_action.id == MARKET_MULTIHOP_BUY) {
678                  HelperMultiHopBuy memory data = abi.decode(
679                      _action.call[4:],
680                      (HelperMultiHopBuy)
681                  );
682  
683                  IUSDOBase(_action.target).initMultiHopBuy(
684                      data.from,
685                      data.collateralAmount,
686                      data.borrowAmount,
687                      data.swapData,
688                      data.lzData,
689                      data.externalData,
690                      data.airdropAdapterParams,
691                      data.approvals
692                  );
693              } else if (_action.id == TOFT_REMOVE_AND_REPAY) {
694                  HelperTOFTRemoveAndRepayAsset memory data = abi.decode(
695                      _action.call[4:],
696                      (HelperTOFTRemoveAndRepayAsset)
697                  );
698  
699                  IUSDOBase(_action.target).removeAsset(
700                      data.from,
701                      data.to,
702                      data.lzDstChainId,
703                      data.zroPaymentAddress,
704                      data.adapterParams,
705                      data.externalData,
706                      data.removeAndRepayData,
707                      data.approvals
708                  );
709              } else {
710                  revert("MagnetarV2: action not valid");
711              }
712:         }

973          for (uint256 i = 0; i < len; i++) {
974              ISingularity sgl = markets[i];
975  
976              result[i].market = _commonInfo(who, IMarket(address(sgl)));
977  
978              (uint128 totalAssetElastic, uint128 totalAssetBase) = sgl //
979                  .totalAsset(); //
980              _totalAsset = Rebase(totalAssetElastic, totalAssetBase); //
981              result[i].totalAsset = _totalAsset; //
982              result[i].userAssetFraction = sgl.balanceOf(who); //
983  
984              (
985                  ISingularity.AccrueInfo memory _accrueInfo,
986                  uint256 _utilization
987              ) = sgl.getInterestDetails();
988  
989              result[i].accrueInfo = _accrueInfo;
990              result[i].utilization = _utilization;
991:         }

1004         for (uint256 i = 0; i < len; i++) {
1005             IBigBang bigBang = markets[i];
1006             result[i].market = _commonInfo(who, IMarket(address(bigBang)));
1007 
1008             (uint64 debtRate, uint64 lastAccrued) = bigBang.accrueInfo();
1009             _accrueInfo = IBigBang.AccrueInfo(debtRate, lastAccrued);
1010             result[i].accrueInfo = _accrueInfo;
1011             result[i].minDebtRate = bigBang.minDebtRate();
1012             result[i].maxDebtRate = bigBang.maxDebtRate();
1013             result[i].debtRateAgainstEthMarket = bigBang
1014                 .debtRateAgainstEthMarket();
1015             result[i].currentDebtRate = bigBang.getDebtRate();
1016 
1017             IPenrose penrose = IPenrose(bigBang.penrose());
1018             result[i].mainBBMarket = penrose.bigBangEthMarket();
1019             result[i].mainBBDebtRate = penrose.bigBangEthDebtRate();
1020:        }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L202-L712

File: contracts/NativeTokenFactory.sol

129          for (uint256 i = 0; i < len; i++) {
130              _mint(tos[i], tokenId, amounts[i]);
131:         }

141          for (uint256 i = 0; i < len; i++) {
142              _requireTransferAllowed(froms[i], isApprovedForAsset[froms[i]][msg.sender][tokenId]);
143              _burn(froms[i], tokenId, amounts[i]);
144:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L129-L131

File: contracts/YieldBox.sol

309          for (uint256 i = 0; i < len; i++) {
310              _requireTransferAllowed(from, isApprovedForAsset[from][msg.sender][assetIds_[i]]);
311:         }

320          for (uint256 i = 0; i < len; i++) {
321              uint256 id = ids[i];
322              _requireTransferAllowed(from, isApprovedForAsset[from][msg.sender][id]);
323              uint256 value = values[i];
324              balanceOf[from][id] -= value;
325              balanceOf[to][id] += value;
326:         }

339          for (uint256 i = 0; i < len; i++) {
340              require(tos[i] != address(0), "YieldBox: to not set"); // To avoid a bad UI from burning funds
341:         }

345          for (uint256 i = 0; i < len; i++) {
346              address to = tos[i];
347              uint256 share_ = shares[i];
348              balanceOf[to][assetId] += share_;
349              _totalShares += share_;
350              emit TransferSingle(msg.sender, from, to, assetId, share_);
351:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L309-L311

[N‑16] Consider moving msg.sender checks to a common authorization modifier

There are 10 instances of this issue:

see instances
File: contracts/Penrose.sol

272:         require(msg.sender == conservator, "Penrose: unauthorized");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L272-L272

File: contracts/markets/Market.sol

246:         require(msg.sender == conservator, "Market: unauthorized");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L246-L246

File: contracts/usd0/BaseUSDO.sol

115:         require(msg.sender == conservator, "USDO: unauthorized");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L115-L115

File: contracts/governance/twTAP.sol

365:         require(msg.sender == address(tapOFT), "twTAP: only tapOFT");

390:         require(msg.sender == address(tapOFT), "twTAP: only tapOFT");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L365-L365

File: contracts/option-airdrop/AirdropBroker.sol

447:         require(PCNFT.ownerOf(_tokenID) == msg.sender, "adb: Not eligible");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L447-L447

File: contracts/tokens/TapOFT.sol

221:         require(msg.sender == minter, "unauthorized");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L221-L221

File: contracts/Magnetar/MagnetarV2Storage.sol

337:         require(_from == msg.sender, "MagnetarV2: operator not approved");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L337-L337

File: contracts/glp/GlpStrategy.sol

91:          require(msg.sender == address(gmxWethPool), "Not the pool");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L91-L91

File: contracts/NativeTokenFactory.sol

77:          require(msg.sender == _pendingOwner, "NTF: caller != pending owner");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L77-L77

[N‑17] Imports could be organized more systematically

The contract's interface should be imported first, followed by each of the interfaces it uses, followed by all other files. The examples below do not follow this layout.

There are 27 instances of this issue:

see instances
File: contracts/Penrose.sol

8:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

10:  import "tapioca-periph/contracts/interfaces/ISingularity.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L8-L8

File: contracts/markets/Market.sol

8:   import "tapioca-periph/contracts/interfaces/IOracle.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L8-L8

File: contracts/usd0/modules/USDOLeverageModule.sol

8:   import {IUSDOBase} from "tapioca-periph/contracts/interfaces/IUSDO.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L8-L8

File: contracts/usd0/modules/USDOOptionsModule.sol

8:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L8-L8

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

8:   import {IUSDOBase} from "tapioca-periph/contracts/interfaces/IUSDO.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L8-L8

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

8:   import {IUSDOBase} from "tapioca-periph/contracts/interfaces/IUSDO.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L8-L8

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

8:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L8-L8

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

8:   import {IUSDOBase} from "tapioca-periph/contracts/interfaces/IUSDO.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L8-L8

File: contracts/option-airdrop/AirdropBroker.sol

7:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L7-L7

File: contracts/option-airdrop/aoTAP.sol

7:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L7-L7

File: contracts/options/TapiocaOptionLiquidityProvision.sol

9:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

12:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L9-L9

File: contracts/options/oTAP.sol

6:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L6-L6

File: contracts/tokens/BaseTapOFT.sol

7:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L7-L7

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

10:  import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L10-L10

File: contracts/Swapper/UniswapV3Swapper.sol

8:   import "@uniswap/v3-periphery/contracts/interfaces/IQuoterV2.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L8-L8

File: contracts/aave/AaveStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L7-L7

File: contracts/balancer/BalancerStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L7-L7

File: contracts/compound/CompoundStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L7-L7

File: contracts/convex/ConvexTricryptoStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L7-L7

File: contracts/curve/TricryptoLPStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L7-L7

File: contracts/curve/TricryptoNativeStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L7-L7

File: contracts/lido/LidoEthStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L7-L7

File: contracts/stargate/StargateStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L7-L7

File: contracts/yearn/YearnStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L7-L7

File: contracts/YieldBox.sol

29:  import "@boringcrypto/boring-solidity/contracts/interfaces/IERC1155.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L29-L29

[N‑18] Overridden function has no body

Consider adding a NatSpec comment describing why the function doesn't need a body and or the purpose it serves

There are 4 instances of this issue:

File: contracts/markets/MarketERC20.sol

114:     function totalSupply() public view virtual override returns (uint256) {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L114-L114

File: contracts/markets/bigBang/BigBang.sol

426      function transfer(
427          address to,
428          uint256 amount
429:     ) public override returns (bool) {}

431      function transferFrom(
432          address from,
433          address to,
434          uint256 amount
435:     ) public override returns (bool) {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L426-L429

File: contracts/markets/singularity/SGLStorage.sol

195:     function _accrue() internal virtual override {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L195-L195

[N‑19] Use OpenZeppelin's or Solady's Ownable, rather than re-inventing the wheel

Both implementations have been optimized and are usage-hardened, so writing your own is unnecessary

There are 20 instances of this issue:

see instances
File: contracts/Penrose.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L4-L4

File: contracts/markets/Market.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L4-L4

File: contracts/markets/bigBang/BigBang.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L4-L4

File: contracts/markets/singularity/SGLStorage.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L4-L4

File: contracts/Vesting.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L6-L6

File: contracts/option-airdrop/AirdropBroker.sol

5:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L5-L5

File: contracts/option-airdrop/aoTAP.sol

5:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L5-L5

File: contracts/options/TapiocaOptionBroker.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L4-L4

File: contracts/options/TapiocaOptionLiquidityProvision.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L6-L6

File: contracts/tokens/LTap.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L4-L4

File: contracts/aave/AaveStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L6-L6

File: contracts/balancer/BalancerStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L6-L6

File: contracts/compound/CompoundStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L6-L6

File: contracts/convex/ConvexTricryptoStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L6-L6

File: contracts/curve/TricryptoLPStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L6-L6

File: contracts/curve/TricryptoNativeStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L6-L6

File: contracts/glp/GlpStrategy.sol

7:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L7-L7

File: contracts/lido/LidoEthStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L6-L6

File: contracts/stargate/StargateStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L6-L6

File: contracts/yearn/YearnStrategy.sol

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L6-L6

[N‑20] Array is push()ed but not pop()ed

Array entries are added but are never removed. Consider whether this should be the case, or whether there should be a maximum, or whether old entries should be removed. Cases where there are specific potential problems will be flagged separately under a different issue.

There are 5 instances of this issue:

File: contracts/Penrose.sol

329:         singularityMasterContracts.push(mc);

351:         bigbangMasterContracts.push(mc);

386:         clonesOf[mc].push(_contract);

419:         clonesOf[mc].push(_contract);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L329-L329

File: contracts/options/TapiocaOptionLiquidityProvision.sol

290:         singularities.push(assetID);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L290-L290

[N‑21] Long functions should be refactored into multiple, smaller, functions

There are 7 instances of this issue:

File: contracts/markets/Market.sol

158      function setMarketConfig(
159          uint256 _borrowOpeningFee,
160          IOracle _oracle,
161          bytes calldata _oracleData,
162          address _conservator,
163          uint256 _callerFee,
164          uint256 _protocolFee,
165          uint256 _liquidationBonusAmount,
166          uint256 _minLiquidatorReward,
167          uint256 _maxLiquidatorReward,
168          uint256 _totalBorrowCap,
169          uint256 _collateralizationRate
170:     ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L158-L170

File: contracts/markets/singularity/SGLCommon.sol

35       function _getInterestRate()
36           internal
37           view
38           returns (
39               ISingularity.AccrueInfo memory _accrueInfo,
40               Rebase memory _totalBorrow,
41               Rebase memory _totalAsset,
42               uint256 extraAmount,
43               uint256 feeFraction,
44               uint256 utilization,
45               bool logStartingInterest
46           )
47:      {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L35-L47

File: contracts/markets/singularity/SGLLiquidation.sol

97       function _orderBookLiquidation(
98           address[] calldata users,
99           uint256 _exchangeRate,
100          bytes memory swapData
101:     ) private {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L97-L101

File: contracts/markets/singularity/Singularity.sol

62:      function init(bytes calldata data) external onlyOnce {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L62-L62

File: contracts/Magnetar/MagnetarV2.sol

194      function burst(
195          Call[] calldata calls
196:     ) external payable returns (Result[] memory returnData) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L194-L196

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

292      function _mintFromBBAndLendOnSGL(
293          address user,
294          uint256 lendAmount,
295          IUSDOBase.IMintData calldata mintData,
296          ICommonData.IDepositData calldata depositData,
297          ITapiocaOptionLiquidityProvision.IOptionsLockData calldata lockData,
298          ITapiocaOptionsBroker.IOptionsParticipateData calldata participateData,
299          ICommonData.ICommonExternalContracts calldata externalContracts
300:     ) private {

495      function _exitPositionAndRemoveCollateral(
496          address user,
497          ICommonData.ICommonExternalContracts calldata externalData,
498          IUSDOBase.IRemoveAndRepay calldata removeAndRepayData
499:     ) private {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L292-L300

[N‑22] Mixed usage of int/uint with int256/uint256

int256/uint256 are the preferred type names (they're what are used for function signatures), so they should be used consistently

There are 7 instances of this issue:

File: contracts/markets/MarketERC20.sol

75:      function _allowedLend(address from, uint share) internal {

84:      function _allowedBorrow(address from, uint share) internal {

94:      modifier allowedLend(address from, uint share) virtual {

99:      modifier allowedBorrow(address from, uint share) virtual {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L75-L75

File: contracts/governance/twTAP.sol

156:         uint _tokenId

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L156-L156

File: contracts/tokens/BaseTapOFT.sol

129:         (, , address to, uint256 amount, uint duration) = abi.decode(

228:             for (uint i = 0; i < len; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L129-L129

[N‑23] Unsafe conversion from unsigned to signed values

Solidity follows two's complement rules for its integers, meaning that the most significant bit for signed integers is used to denote the sign, and converting between the two requires inverting all of the bits and adding one. Because of this, casting an unsigned integer to a signed one may result in a change of the sign and or magnitude of the value. For example, int8(type(uint8).max) is not equal to type(int8).max, but is equal to -1. type(uint8).max in binary is 11111111, which if cast to a signed value, means the first binary 1 indicates a negative value, and the binary 1s, invert to all zeroes, and when one is added, it becomes one, but negative, and therefore the decimal value of binary 11111111 is -1.

There are 10 instances of this issue:

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit uint256 minLiquidatorReward -> int256
/// @audit uint256 maxLiquidatorReward -> int256
456:          int256 diff = int256(minLiquidatorReward) - int256(maxLiquidatorReward);

/// @audit uint256 rewardPercentage -> int256
457:          int256 reward = (diff * int256(rewardPercentage)) /

/// @audit uint256 FEE_PRECISION -> int256
458:              int256(FEE_PRECISION) +

/// @audit uint256 maxLiquidatorReward -> int256
459:              int256(maxLiquidatorReward);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L456

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit uint256 votes -> int256
343:          weekTotals[w0 + 1].netActiveVotes += int256(votes);

/// @audit uint256 votes -> int256
344:          weekTotals[w1 + 1].netActiveVotes -= int256(votes);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L343

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit uint256 i -> int256
159:                  index = int256(i);

/// @audit uint256 i -> int256
228:                  index = int256(i);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L159

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit uint256 gmxAmount -> int256
327:              int256(gmxAmount),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L327

[N‑24] public functions not called by the contract should be declared external instead

Contracts are allowed to override their parents' functions and change the visibility from external to public.

There are 74 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

242       function borrow(
243           address from,
244           address to,
245           uint256 amount
246:      ) public notPaused solvent(from) returns (uint256 part, uint256 share) {

263       function repay(
264           address from,
265           address to,
266           bool,
267           uint256 part
268:      ) public notPaused allowedBorrow(from, part) returns (uint256 amount) {

282       function addCollateral(
283           address from,
284           address to,
285           bool skim,
286           uint256 amount,
287           uint256 share
288:      ) public allowedBorrow(from, share) notPaused {

296       function removeCollateral(
297           address from,
298           address to,
299           uint256 share
300:      ) public notPaused solvent(from) allowedBorrow(from, share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L242-L246

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

116:      function nonces(address owner) public view returns (uint256) {

201       function approveBorrow(
202           address spender,
203           uint256 amount
204:      ) public returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L116

File: tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol

21        function borrow(
22            address from,
23            address to,
24            uint256 amount
25:       ) public notPaused solvent(from) returns (uint256 part, uint256 share) {

45        function repay(
46            address from,
47            address to,
48            bool skim,
49            uint256 part
50:       ) public notPaused allowedBorrow(from, part) returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L21-L25

File: tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol

21        function addCollateral(
22            address from,
23            address to,
24            bool skim,
25            uint256 amount,
26            uint256 share
27:       ) public notPaused allowedBorrow(from, share) {

35        function removeCollateral(
36            address from,
37            address to,
38            uint256 share
39:       ) public notPaused solvent(from) allowedBorrow(from, share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L21-L27

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

17        function accrue() public {
18:           _accrue();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L17-L18

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

154:      function symbol() public view returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L154

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

204       function addAsset(
205           address from,
206           address to,
207           bool skim,
208           uint256 share
209:      ) public notPaused allowedLend(from, share) returns (uint256 fraction) {

219       function removeAsset(
220           address from,
221           address to,
222           uint256 fraction
223:      ) public notPaused returns (uint256 share) {

235       function addCollateral(
236           address from,
237           address to,
238           bool skim,
239           uint256 amount,
240:          uint256 share

259:      function removeCollateral(address from, address to, uint256 share) public {

277       function borrow(
278           address from,
279           address to,
280           uint256 amount
281:      ) public returns (uint256 part, uint256 share) {

296       function repay(
297           address from,
298           address to,
299           bool skim,
300           uint256 part
301:      ) public returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L204-L209

File: tapioca-bar-audit/contracts/Penrose.sol

199       function singularityMarkets()
200           public
201           view
202:          returns (address[] memory markets)

209:      function bigBangMarkets() public view returns (address[] memory markets) {

214:      function singularityMasterContractLength() public view returns (uint256) {

219:      function bigBangMasterContractLength() public view returns (uint256) {

232       function withdrawAllMarketFees(
233           IMarket[] calldata markets_,
234           ISwapper[] calldata swappers_,
235           IPenrose.SwapData[] calldata swapData_
236:      ) public notPaused {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L199-L202

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

93:       function multiHop(bytes memory _payload) public {

133       function leverageUp(
134           address module,
135           uint16 _srcChainId,
136           bytes memory _srcAddress,
137           uint64 _nonce,
138:          bytes memory _payload

190       function leverageUpInternal(
191           uint256 amount,
192           IUSDOBase.ILeverageSwapData memory swapData,
193           IUSDOBase.ILeverageExternalContractsData memory externalData,
194           IUSDOBase.ILeverageLZData memory lzData,
195:          address leverageFor

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L93

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

104:      function remove(bytes memory _payload) public {

134       function lend(
135           address module,
136           uint16 _srcChainId,
137           bytes memory _srcAddress,
138           uint64 _nonce,
139:          bytes memory _payload

191       function lendInternal(
192           address to,
193           IUSDOBase.ILendOrRepayParams memory lendParams,
194           ICommonData.IApproval[] memory approvals,
195:          ICommonData.IWithdrawParams memory withdrawParams

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L104

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

103:      function sendFromDestination(bytes memory _payload) public {

138       function exercise(
139           address module,
140           uint16 _srcChainId,
141           bytes memory _srcAddress,
142           uint64 _nonce,
143:          bytes memory _payload

206       function exerciseInternal(
207           address from,
208           uint256 oTAPTokenID,
209           address paymentToken,
210           uint256 tapAmount,
211           address target,
212           ITapiocaOptionsBrokerCrossChain.IExerciseLZSendTapData
213               memory tapSendData,
214:          ICommonData.IApproval[] memory approvals

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L103

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

111:      function multiHop(bytes memory _payload) public {

148       function leverageDown(
149           address module,
150           uint16 _srcChainId,
151           bytes memory _srcAddress,
152           uint64 _nonce,
153:          bytes memory _payload

205       function leverageDownInternal(
206           uint256 amount,
207           IUSDOBase.ILeverageSwapData memory swapData,
208           IUSDOBase.ILeverageExternalContractsData memory externalData,
209           IUSDOBase.ILeverageLZData memory lzData,
210:          address leverageFor

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L111

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

126       function borrow(
127           address module,
128           uint16 _srcChainId,
129           bytes memory _srcAddress,
130           uint64 _nonce,
131:          bytes memory _payload

180       function borrowInternal(
181           bytes32 _to,
182           ITapiocaOFT.IBorrowParams memory borrowParams,
183           ICommonData.IWithdrawParams memory withdrawParams,
184:          ICommonData.IApproval[] memory approvals

204:      function remove(bytes memory _payload) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L126-L131

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

118:      function sendFromDestination(bytes memory _payload) public {

153       function exercise(
154           address module,
155           uint16 _srcChainId,
156           bytes memory _srcAddress,
157           uint64 _nonce,
158:          bytes memory _payload

221       function exerciseInternal(
222           address from,
223           uint256 oTAPTokenID,
224           address paymentToken,
225           uint256 tapAmount,
226           address target,
227           ITapiocaOptionsBrokerCrossChain.IExerciseLZSendTapData
228               memory tapSendData,
229:          ICommonData.IApproval[] memory approvals

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L118

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

122       function strategyDeposit(
123           address module,
124           uint16 _srcChainId,
125           bytes memory _srcAddress,
126           uint64 _nonce,
127           bytes memory _payload,
128:          IERC20 _erc20

173       function depositToYieldbox(
174           uint256 _assetId,
175           uint256 _amount,
176           uint256 _share,
177           IERC20 _erc20,
178           address _from,
179:          address _to

188       function strategyWithdraw(
189           uint16 _srcChainId,
190:          bytes memory _payload

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L122-L128

File: tap-token-audit/contracts/governance/twTAP.sol

155       function getParticipation(
156           uint _tokenId
157:      ) public view returns (Participation memory participant) {

397:      function advanceWeek(uint256 _limit) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L155-L157

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

76        function getCollateralAmountForShare(
77            IMarket market,
78            uint256 share
79:       ) public view returns (uint256 amount) {

89        function getCollateralSharesForBorrowPart(
90            IMarket market,
91            uint256 borrowPart,
92            uint256 liquidationMultiplierPrecision,
93            uint256 exchangeRatePrecision
94:       ) public view returns (uint256 collateralShares) {

117       function getAmountForBorrowPart(
118           IMarket market,
119           uint256 borrowPart
120:      ) public view returns (uint256 amount) {

133       function getBorrowPartForAmount(
134           IMarket market,
135           uint256 amount
136:      ) public view returns (uint256 part) {

150       function getAmountForAssetFraction(
151           ISingularity singularity,
152           uint256 fraction
153:      ) public view returns (uint256 amount) {

171       function getFractionForAmount(
172           ISingularity singularity,
173           uint256 amount
174:      ) public view returns (uint256 fraction) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L76-L79

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

41        function multicall(
42            Call[] calldata calls
43:       ) public payable returns (Result[] memory returnData) {

63        function multicallValue(
64            CallValue[] calldata calls
65:       ) public payable returns (Result[] memory returnData) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L41-L43

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

117:      function compound(bytes memory) public {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L117

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

80:       function compoundAmount() public pure returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L80

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

103:      function compoundAmount() public returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L103

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

104:      function harvestGmx(uint256 priceNum, uint256 priceDenom) public onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L104

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

84:       function compoundAmount() public pure returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L84

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

81:       function compoundAmount() public pure returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L81

File: YieldBox/contracts/NativeTokenFactory.sol

56:       function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {

73:       function claimOwnership(uint256 tokenId) public {

90:       function createToken(string calldata name, string calldata symbol, uint8 decimals, string calldata uri) public returns (uint32 tokenId) {

109:      function mint(uint256 tokenId, address to, uint256 amount) public onlyOwner(tokenId) {

116:      function burn(uint256 tokenId, address from, uint256 amount) public allowed(from, tokenId) {

127:      function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {

138:      function batchBurn(uint256 tokenId, address[] calldata froms, uint256[] calldata amounts) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L56

File: YieldBox/contracts/YieldBox.sol

168       function depositNFTAsset(
169           uint256 assetId,
170           address from,
171           address to
172:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

223       function withdraw(
224           uint256 assetId,
225           address from,
226           address to,
227           uint256 amount,
228           uint256 share
229:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

303:      function transfer(address from, address to, uint256 assetId, uint256 share) public allowed(from, assetId) {

307:      function batchTransfer(address from, address to, uint256[] calldata assetIds_, uint256[] calldata shares_) public {

336:      function transferMultiple(address from, address[] calldata tos, uint256 assetId, uint256[] calldata shares) public allowed(from, assetId) {

477       function deposit(
478           TokenType tokenType,
479           address contractAddress,
480           IStrategy strategy,
481           uint256 tokenId,
482           address from,
483           address to,
484           uint256 amount,
485           uint256 share
486:      ) public returns (uint256 amountOut, uint256 shareOut) {

500:      function depositETH(IStrategy strategy, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L168-L172

[N‑25] constants should be defined rather than using magic numbers

Even assembly can benefit from using readable constants instead of hex/numeric literals

There are 194 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit 90000
148:          callerFee = 90000; // 90%

/// @audit 10000
149:          protocolFee = 10000; // 10%

/// @audit 75000
150:          collateralizationRate = 75000; // 75%

/// @audit 1e18
154:              : 1e18;

/// @audit 1e3
164:          minLiquidatorReward = 1e3;

/// @audit 1e4
165:          maxLiquidatorReward = 1e4;

/// @audit 1e4
166:          liquidationBonusAmount = 1e4;

/// @audit 50
167:          borrowOpeningFee = 50; // 0.05%

/// @audit 12000
168:          liquidationMultiplier = 12000; //12%

/// @audit 1e18
188:              debtRateAgainstEthMarket) / 1e18;

/// @audit 31536000
521:          _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second

/// @audit 1e18
534:              1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L148

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit 18
264:          if (borrowPartDecimals > 18) {

/// @audit 18
265:              borrowPartScaled = borrowPart / (10 ** (borrowPartDecimals - 18));

/// @audit 18
267:          if (borrowPartDecimals < 18) {

/// @audit 18
268:              borrowPartScaled = borrowPart * (10 ** (18 - borrowPartDecimals));

/// @audit 18
272:          if (collateralPartDecimals > 18) {

/// @audit 18
275:                  (10 ** (collateralPartDecimals - 18));

/// @audit 18
277:          if (collateralPartDecimals < 18) {

/// @audit 18
280:                  (10 ** (18 - collateralPartDecimals));

/// @audit 18
293:              (10 ** ratesPrecision)) * (10 ** (18 - ratesPrecision));

/// @audit 1e18
295:          uint256 x = (numerator * 1e18) / denominator;

/// @audit 68
376:          if (_returnData.length < 68) return "Market: no return data";

/// @audit 0x04
380:              _returnData := add(_returnData, 0x04)

/// @audit 5
489:          uint256 _quotient = ((_numerator / denominator) + 5) / 10;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L264

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit 1e18
103:              1e18;

/// @audit 1000
210:          if (_totalAsset.base + uint128(fraction) < 1000) {

/// @audit 1000
240:          require(_totalAsset.base >= 1000, "SGL: min limit");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L103

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

/// @audit 1000
75:           require(_totalAsset.base >= 1000, "SGL: min limit");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L75

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit 951293760
112:          minimumInterestPerSecond = 951293760; // approx 3% APR

/// @audit 2536783360
113:          maximumInterestPerSecond = 2536783360; // approx 8% APR

/// @audit 7200e36
114:          interestElasticity = 7200e36; // Half or double in 28800 seconds (1 hours) if linear

/// @audit 1000
122:          callerFee = 1000; // 1%

/// @audit 10000
123:          protocolFee = 10000; // 10%

/// @audit 50
124:          borrowOpeningFee = 50; // 0.05%

/// @audit 12000
127:          liquidationMultiplier = 12000; //12%

/// @audit 75000
129:          collateralizationRate = 75000;

/// @audit 25000
130:          lqCollateralizationRate = 25000;

/// @audit 1e18
133:              : 1e18;

/// @audit 1e3
135:          minLiquidatorReward = 1e3;

/// @audit 1e4
136:          maxLiquidatorReward = 1e4;

/// @audit 1e4
137:          liquidationBonusAmount = 1e4;

/// @audit 3e17
139:          minimumTargetUtilization = 3e17;

/// @audit 5e17
140:          maximumTargetUtilization = 5e17;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L112

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit 5e15
131:          bigBangEthDebtRate = 5e15;

/// @audit 68
476:          if (_returnData.length < 68) return "SGL: no return data";

/// @audit 0x04
480:              _returnData := add(_returnData, 0x04)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L131

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

/// @audit 100_000
/// @audit 1e18
78:           maxFlashMint = 100_000 * 1e18; // 100k USDO

/// @audit 8
73:       ) OFTV2("USDO", "USDO", 8, _lzEndpoint) {

/// @audit 68
91:           if (_returnData.length < 68) return "USDO: no return data";

/// @audit 0x04
95:               _returnData := add(_returnData, 0x04)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L78

File: tapiocaz-audit/contracts/Balancer.sol

/// @audit 1e5
118:          if (_slippage >= 1e5) revert SlippageNotValid();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L118

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

/// @audit 0x0
160:          if (address(tapiocaOFTsByErc20[_erc20]) != address(0x0)) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L160

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit 18
85:           if (_decimalCache == 0) return 18; //temporary fix for LZ _sharedDecimals check

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L85

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

/// @audit 68
71:           if (_returnData.length < 68) return "TOFT_data";

/// @audit 0x04
75:               _returnData := add(_returnData, 0x04)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L71

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit 4
33:       uint8[4] amountsPerUsers;

/// @audit 4
34:       uint8[4] discountsPerUsers;

/// @audit 1e18
177:          require(tapAmount >= 1e18, "adb: Too low");

/// @audit 4
204:          require(cachedEpoch <= 4, "adb: Airdrop ended");

/// @audit 3
211:          } else if (cachedEpoch == 3) {

/// @audit 4
213:          } else if (cachedEpoch == 4) {

/// @audit 1e18
258:          require(chosenAmount >= 1e18, "adb: Too low");

/// @audit 4
319:          bytes32[4] calldata _merkleRoots

/// @audit 4
335:          } else if (_phase == 4) {

/// @audit 20
424:          uint256 subPhase = 20 + _role;

/// @audit 1e18
434:          uint256 eligibleAmount = uint256(PHASE_2_AMOUNT_PER_USER[_role]) * 1e18;

/// @audit 1e4
435:          uint128 discount = uint128(PHASE_2_DISCOUNT_PER_USER[_role]) * 1e4;

/// @audit 3
450:              userParticipation[tokenIDToAddress][3] == false,

/// @audit 3
456:          userParticipation[tokenIDToAddress][3] = true;

/// @audit 100e4
533:              muldiv(rawPaymentAmount, _discount, 100e4); // 1e4 is discount decimals, 100 is discount percentage

/// @audit 18
535:          paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L33

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit 1e18
190:          require(tapAmount >= 1e18, "tOB: Too low");

/// @audit 1e18
391:          require(chosenAmount >= 1e18, "tOB: Too low");

/// @audit 100e4
554:              muldiv(rawPaymentAmount, _discount, 100e4); // 1e4 is discount decimals, 100 is discount percentage

/// @audit 18
555:          paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L190

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit 1e18
/// @audit 15_000_000
121:              _mint(_contributors, 1e18 * 15_000_000);

/// @audit 1e18
/// @audit 3_686_595
122:              _mint(_earlySupporters, 1e18 * 3_686_595);

/// @audit 1e18
/// @audit 12_500_000
123:              _mint(_supporters, 1e18 * 12_500_000);

/// @audit 1e18
/// @audit 5_000_000
124:              _mint(_lbp, 1e18 * 5_000_000);

/// @audit 1e18
/// @audit 8_000_000
125:              _mint(_dao, 1e18 * 8_000_000);

/// @audit 1e18
/// @audit 2_500_000
126:              _mint(_airdrop, 1e18 * 2_500_000);

/// @audit 8
117:      ) BaseTapOFT("TapOFT", "TAP", 8, _lzEndpoint) ERC20Permit("TapOFT") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L121

File: tap-token-audit/contracts/twAML.sol

/// @audit 1
76:               twos := add(div(sub(0, twos), twos), 1)

/// @audit 3
86:           uint256 inv = (3 * denominator) ^ 2;

/// @audit 1e4
120:          return mul >= 1e4 ? mul / 1e4 : _totalWeight;

/// @audit 3
148:          if (y > 3) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L76

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit 4
233:                  WrapData memory data = abi.decode(_action.call[4:], (WrapData));

/// @audit 4
257:                          _action.call[4:],

/// @audit 4
277:                      _action.call[4:],

/// @audit 4
297:                      _action.call[4:],

/// @audit 4
311:                      _action.call[4:],

/// @audit 4
337:                          _action.call[4:],

/// @audit 4
369:                      _action.call[4:],

/// @audit 4
386:                      _action.call[4:],

/// @audit 4
412:                          _action.call[4:],

/// @audit 4
449:                          _action.call[4:],

/// @audit 4
477:                      _action.call[4:],

/// @audit 4
503:                          _action.call[4:],

/// @audit 4
530:                      _action.call[4:],

/// @audit 4
557:                          _action.call[4:],

/// @audit 4
586:                      _action.call[4:],

/// @audit 4
603:                      _action.call[4:],

/// @audit 4
624:                      _action.call[4:],

/// @audit 4
638:                      _action.call[4:],

/// @audit 4
651:                      _action.call[4:],

/// @audit 4
663:                      _action.call[4:],

/// @audit 4
679:                      _action.call[4:],

/// @audit 4
695:                      _action.call[4:],

/// @audit 4
1033:                 actionCalldata[4:],

/// @audit 4
1039:                 actionCalldata[4:],

/// @audit 68
1080:         if (_returnData.length < 68) revert("MagnetarV2: Reason unknown");

/// @audit 0x04
1084:             _returnData := add(_returnData, 0x04)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L233

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

/// @audit 68
96:           if (_returnData.length < 68) revert("Reason unknown");

/// @audit 0x04
100:              _returnData := add(_returnData, 0x04)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L96

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit 1e10
121:          uint256 _btcPrice = uint256(BTC_FEED.latestAnswer()) * 1e10;

/// @audit 1e10
122:          uint256 _wbtcPrice = uint256(WBTC_FEED.latestAnswer()) * 1e10;

/// @audit 1e10
123:          uint256 _ethPrice = uint256(ETH_FEED.latestAnswer()) * 1e10;

/// @audit 1e10
124:          uint256 _usdtPrice = uint256(USDT_FEED.latestAnswer()) * 1e10;

/// @audit 1e18
126:          uint256 _minWbtcPrice = (_wbtcPrice < 1e18)

/// @audit 1e18
127:              ? (_wbtcPrice * _btcPrice) / 1e18

/// @audit 3
132:          _maxPrice = (3 * _vp * FixedPointMathLib.cbrt(_basePrices)) / 1 ether;

/// @audit 1e34
137:          uint256 _discount = Math.max((_g ** 2 / 1 ether) * _a, 1e34); // handle qbrt nonconvergence

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L121

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

/// @audit 0x095ea7b3
100:              abi.encodeWithSelector(0x095ea7b3, to, value)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L100

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit 60
97:           (int24 tick, ) = OracleLibrary.consult(pool, 60);

/// @audit 60
126:          (int24 tick, ) = OracleLibrary.consult(pool, 60);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L97

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

/// @audit 0x20
41:               addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)

/// @audit 0x40
74:               let ptr := mload(0x40) // Get free memory pointer

/// @audit 0x40
86:               mstore(add(ptr, 0x40), bytecodeHash)

/// @audit 0x20
87:               mstore(add(ptr, 0x20), salt)

/// @audit 0x0b
89:               let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff

/// @audit 0xff
90:               mstore8(start, 0xff)

/// @audit 85
91:               addr := keccak256(start, 85)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L41

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit 50
/// @audit 10_000
113:              result = result - (result * 50) / 10_000; //0.5%

/// @audit 12
170:              bool daysPassed = (currentCooldown + 12 days) < block.timestamp;

/// @audit 50
/// @audit 10_000
193:              uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L113

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit 50
/// @audit 10_000
122:          toWithdraw = toWithdraw - (toWithdraw * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
177:          bptOut = bptOut - (bptOut * 50) / 10_000; //0.5%

/// @audit 250
/// @audit 10_000
250:          bptIn = bptIn + (bptIn * 250) / 10_000; //2.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L122

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit 18
116:          uint256 invested = (shares * pricePerShare) / (10 ** 18);

/// @audit 18
146:              uint256 toWithdraw = (((amount - queued) * (10 ** 18)) /

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L116

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit 50
/// @audit 10_000
143:              result = result - (result * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
154:          uint256 minAmount = (calcWithdraw * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
207:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

/// @audit 1e18
312:          if (calcAmount >= 1e18) {

/// @audit 50
/// @audit 10_000
313:              uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
336:              uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L143

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit 50
/// @audit 10_000
179:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
186:                  minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L179

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit 50
/// @audit 10_000
116:              result = result - (result * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
170:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
188:          uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
232:              uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
249:          uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L116

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit 10_000
171:              uint256 fee = (wethAmount * FEE_BPS) / 10_000;

/// @audit 20
310:          uint256 buffer = (freeEsGmx + stakedEsGmx) / 20;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L171

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit 50
/// @audit 10_000
108:          uint256 minAmount = (toWithdraw * 50) / 10_000; //0.5%

/// @audit 250
/// @audit 10_000
151:              uint256 minAmount = toWithdraw - (toWithdraw * 250) / 10_000; //2.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L108

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit 50
/// @audit 10_000
133:              result = result - (result * 50) / 10_000; //0.5%

/// @audit 50
/// @audit 10_000
182:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L133

File: YieldBox/contracts/YieldBoxRebase.sol

/// @audit 1e8
29:           totalShares_ += 1e8;

/// @audit 1e8
52:           totalShares_ += 1e8;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L29

File: YieldBox/contracts/YieldBoxURIBuilder.sol

/// @audit 20
37:                                       uint256(uint160(asset.contractAddress)).toHexString(20),

/// @audit 20
90:                   abi.encodePacked("ERC1155:", uint256(uint160(asset.contractAddress)).toHexString(20), "/", asset.tokenId.toString())

/// @audit 20
106:                  ? abi.encodePacked(',"tokenAddress":"', uint256(uint160(asset.contractAddress)).toHexString(20), '"')

/// @audit 20
124:                              uint256(uint160(address(asset.strategy))).toHexString(20),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L37

[N‑26] Event is not properly indexed

Index event fields make the field more quickly accessible to off-chain tools that parse events. This is especially useful when it comes to filtering based on an address. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Where applicable, each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three applicable fields, all of the applicable fields should be indexed.

There are 22 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/Market.sol

102       event Liquidated(
103           address liquidator,
104           address[] users,
105           uint256 liquidatorReward,
106           uint256 protocolReward,
107           uint256 repayedAmount,
108           uint256 collateralShareRemoved
109:      );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L102-L109

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

136:      event BidExecutionSwapperUpdated(address newAddress);

138:      event UsdoSwapperUpdated(address newAddress);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L136

File: tapioca-bar-audit/contracts/Penrose.sol

140       event RegisterSingularityMasterContract(
141           address location,
142           IPenrose.ContractType risk
143:      );

145       event RegisterBigBangMasterContract(
146           address location,
147           IPenrose.ContractType risk
148:      );

150:      event RegisterSingularity(address location, address masterContract);

152:      event RegisterBigBang(address location, address masterContract);

154:      event FeeToUpdate(address newFeeTo);

156:      event SwapperUpdate(address swapper, bool isRegistered);

158:      event UsdoTokenUpdated(address indexed usdoToken, uint256 assetId);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L140-L143

File: tapiocaz-audit/contracts/Balancer.sol

69        event ConnectedChainUpdated(
70            address indexed _srcOft,
71            uint16 _dstChainId,
72            address indexed _dstOft
73:       );

76        event Rebalanced(
77            address indexed _srcOft,
78            uint16 _dstChainId,
79            uint256 _slippage,
80            uint256 _amount,
81            bool _isNative
82:       );

84        event RebalanceAmountUpdated(
85            address _srcOft,
86            uint16 _dstChainId,
87            uint256 _amount,
88            uint256 _totalAmount
89:       );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L69-L73

File: tap-token-audit/contracts/governance/twTAP.sol

144:      event ExitPosition(uint256 tokenId, uint256 amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L144

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

115:      event Participate(uint256 indexed epoch, uint256 aoTAPTokenID);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L115

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

94:       event SetSGLPoolWeight(address sgl, uint256 poolWeight);

95:       event RegisterSingularity(address sgl, uint256 assetID);

96:       event UnregisterSingularity(address sgl, uint256 assetID);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L94

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

41:       event CallFailedStr(uint16 _srcChainId, bytes _payload, string _reason);

42:       event CallFailedBytes(uint16 _srcChainId, bytes _payload, bytes _reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L41

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

331:      event ApprovalForAll(address owner, address operator, bool approved);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L331

File: YieldBox/contracts/NativeTokenFactory.sol

28:       event TokenCreated(address indexed creator, string name, string symbol, uint8 decimals, uint256 tokenId);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L28

[N‑27] Duplicated require()/revert() checks should be refactored to a modifier or function

The compiler will inline the function, which will avoid JUMP instructions usually associated with functions

There are 33 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

391:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

413:          require(amountOut >= minAmountOut, "SGL: not enough");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L391

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

167:              require(srcBalance >= amount, "ERC20: balance too low");

179:                  require(to != address(0), "ERC20: no zero address"); // Moved down so other failed calls safe some gas

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L167

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

65            require(
66                penrose.swappers(ISwapper(externalData.swapper)),
67                "SGL: Invalid swapper"
68:           );

155:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

182:          require(amountOut >= minAmountOut, "SGL: not enough");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L65-L68

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

640:              revert(_getRevertMsg(returnData));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L640

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

284:                          revert(reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L284

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

273:                          revert(reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L273

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

274:                          revert(reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L274

File: tapioca-bar-audit/contracts/usd0/USDO.sol

87:           require(token == address(this), "USDO: token not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L87

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

314:                          revert(reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L314

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

290:                          revert(reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L290

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

289:                          revert(reason);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L289

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

98:           require(amount > 0, "TOFT_0");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L98

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

106:          require(!balancers[msg.sender], "TOFT_auth");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L106

File: tap-token-audit/contracts/governance/twTAP.sol

390:          require(msg.sender == address(tapOFT), "twTAP: only tapOFT");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L390

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

233:          require(aoTapOption.expiry > block.timestamp, "adb: Option expired");

242           require(
243               paymentTokenOracle.oracle != IOracle(address(0)),
244               "adb: Payment token not supported"
245:          );

255:          require(eligibleTapAmount >= _tapAmount, "adb: Too high");

467:          require(_eligibleAmount > 0, "adb: Not eligible");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L233

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

129           require(
130               _isApprovedOrOwner(msg.sender, _tokenId),
131               "AOTAP: only approved or owner"
132:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L129-L132

File: tap-token-audit/contracts/options/oTAP.sol

116           require(
117               _isApprovedOrOwner(msg.sender, _tokenId),
118               "OTAP: only approved or owner"
119:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L116-L119

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

368           require(
369               paymentTokenOracle.oracle != IOracle(address(0)),
370               "tOB: Payment token not supported"
371:          );

376:          require(isPositionActive, "tOB: Option expired");

388:          require(eligibleTapAmount >= _tapAmount, "tOB: Too high");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L368-L371

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

307:          require(twTap.ownerOf(tokenID) == to, "TapOFT: Not owner");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L307

File: YieldBox/contracts/NativeTokenFactory.sol

139:          require(assets[tokenId].tokenType == TokenType.Native, "NTF: Not native");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L139

File: YieldBox/contracts/YieldBoxPermit.sol

80:           require(block.timestamp <= deadline, "YieldBoxPermit: expired deadline");

87:           require(signer == owner, "YieldBoxPermit: invalid signature");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L80

File: YieldBox/contracts/YieldBox.sol

382:          require(operator != address(0), "YieldBox: operator not set"); // Important for security

383:          require(operator != address(this), "YieldBox: can't approve yieldBox");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L382

[N‑28] Vulnerable versions of packages are being used

This project's specific package versions are vulnerable to the specific CVEs listed below. Consider switching to more recent versions of these packages that don't have these vulnerabilities

There are 6 instances of this issue:

File: Various Files

/// @audit Vulnerabilities:
///          
  • CVE-2022-34338 - MEDIUM - (@types/node >=21.0.0 <21.0.3) - IBM Robotic Process Automation 21.0.0, 21.0.1, and 21.0.2 could disclose sensitive information due to improper privilege management for storage provider types. IBM X-Force ID: 229962.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

File: Various Files

/// @audit Vulnerabilities:
///          
  • CVE-2022-34338 - MEDIUM - (@types/node >=21.0.0 <21.0.3) - IBM Robotic Process Automation 21.0.0, 21.0.1, and 21.0.2 could disclose sensitive information due to improper privilege management for storage provider types. IBM X-Force ID: 229962.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol

File: Various Files

/// @audit Vulnerabilities:
///          
  • CVE-2022-34338 - MEDIUM - (@types/node >=21.0.0 <21.0.3) - IBM Robotic Process Automation 21.0.0, 21.0.1, and 21.0.2 could disclose sensitive information due to improper privilege management for storage provider types. IBM X-Force ID: 229962.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol

File: Various Files

/// @audit Vulnerabilities:
///          
  • CVE-2022-34338 - MEDIUM - (@types/node >=21.0.0 <21.0.3) - IBM Robotic Process Automation 21.0.0, 21.0.1, and 21.0.2 could disclose sensitive information due to improper privilege management for storage provider types. IBM X-Force ID: 229962.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

File: Various Files

/// @audit Vulnerabilities:
///          
  • CVE-2022-34338 - MEDIUM - (@types/node >=21.0.0 <21.0.3) - IBM Robotic Process Automation 21.0.0, 21.0.1, and 21.0.2 could disclose sensitive information due to improper privilege management for storage provider types. IBM X-Force ID: 229962.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

File: Various Files

/// @audit Vulnerabilities:
///          
  • CVE-2022-34338 - MEDIUM - (@types/node >=21.0.0 <21.0.3) - IBM Robotic Process Automation 21.0.0, 21.0.1, and 21.0.2 could disclose sensitive information due to improper privilege management for storage provider types. IBM X-Force ID: 229962.

[N‑29] Import declarations should import specific identifiers, rather than the whole file

Using import declarations of the form import {<identifier_name>} from "some/file.sol" avoids polluting the symbol namespace making flattened files smaller, and speeds up compilation (but does not save any gas)

There are 345 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

4:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:    import "@boringcrypto/boring-solidity/contracts/ERC20.sol";

7:    import "tapioca-periph/contracts/interfaces/IBigBang.sol";

8:    import "tapioca-periph/contracts/interfaces/ISendFrom.sol";

9:    import "tapioca-periph/contracts/interfaces/ISwapper.sol";

12:   import "../Market.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L4

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

6:    import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L6

File: tapioca-bar-audit/contracts/markets/Market.sol

4:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

7:    import "tapioca-sdk/dist/contracts/YieldBox/contracts/YieldBox.sol";

8:    import "tapioca-periph/contracts/interfaces/IOracle.sol";

9:    import "tapioca-periph/contracts/interfaces/IPenrose.sol";

10:   import "./MarketERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol

4:    import "./SGLLendingCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol

4:    import "./SGLLendingCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

4:    import "./SGLStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

4:    import "./SGLCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

4:    import "./SGLLendingCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

4:    import "./SGLCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

4:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

6:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

8:    import "tapioca-periph/contracts/interfaces/ISwapper.sol";

9:    import "tapioca-periph/contracts/interfaces/IPenrose.sol";

10:   import "tapioca-periph/contracts/interfaces/ISingularity.sol";

11:   import "tapioca-periph/contracts/interfaces/ILiquidationQueue.sol";

12:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/YieldBox.sol";

14:   import "../Market.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L4

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

4:    import "./SGLCommon.sol";

5:    import "./SGLLiquidation.sol";

6:    import "./SGLCollateral.sol";

7:    import "./SGLBorrow.sol";

8:    import "./SGLLeverage.sol";

10:   import "tapioca-periph/contracts/interfaces/ISendFrom.sol";

11:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L4

File: tapioca-bar-audit/contracts/Penrose.sol

4:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:    import "@boringcrypto/boring-solidity/contracts/BoringFactory.sol";

7:    import "tapioca-sdk/dist/contracts/YieldBox/contracts/YieldBox.sol";

8:    import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

9:    import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/ERC20WithoutStrategy.sol";

10:   import "tapioca-periph/contracts/interfaces/ISingularity.sol";

11:   import "tapioca-periph/contracts/interfaces/IPenrose.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L4

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

5:    import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

8:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

12:   import "tapioca-periph/contracts/interfaces/IYieldBoxBase.sol";

14:   import "tapioca-periph/contracts/interfaces/ICommonData.sol";

16:   import "./BaseUSDOStorage.sol";

17:   import "./modules/USDOLeverageModule.sol";

18:   import "./modules/USDOMarketModule.sol";

19:   import "./modules/USDOOptionsModule.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L5

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

5:    import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

8:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

12:   import "tapioca-periph/contracts/interfaces/IYieldBoxBase.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L5

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:    import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

11:   import "tapioca-periph/contracts/interfaces/ISingularity.sol";

12:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

13:   import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

15:   import "../BaseUSDOStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L5

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

10:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

11:   import "tapioca-periph/contracts/interfaces/IMagnetar.sol";

12:   import "tapioca-periph/contracts/interfaces/IMarket.sol";

13:   import "tapioca-periph/contracts/interfaces/ISingularity.sol";

14:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

15:   import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

17:   import "../BaseUSDOStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L5

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:    import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

9:    import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

10:   import "tapioca-periph/contracts/interfaces/ITapiocaOptionsBroker.sol";

11:   import "tapioca-periph/contracts/interfaces/ISendFrom.sol";

12:   import "../BaseUSDOStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L5

File: tapioca-bar-audit/contracts/usd0/USDO.sol

4:    import "tapioca-sdk/dist/contracts/interfaces/ILayerZeroEndpoint.sol";

5:    import "tapioca-periph/contracts/interfaces/IERC3156FlashLender.sol";

6:    import "./BaseUSDO.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L4

File: tapiocaz-audit/contracts/Balancer.sol

4:    import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

5:    import "tapioca-periph/contracts/interfaces/IStargateRouter.sol";

6:    import "@rari-capital/solmate/src/auth/Owned.sol";

7:    import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L4

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

4:    import "./tOFT/TapiocaOFT.sol";

5:    import "./tOFT/mTapiocaOFT.sol";

6:    import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

8:    import "@openzeppelin/contracts/utils/Create2.sol";

9:    import "@openzeppelin/contracts/access/Ownable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L4

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

4:    import "./BaseTOFTStorage.sol";

7:    import "./modules/BaseTOFTLeverageModule.sol";

8:    import "./modules/BaseTOFTStrategyModule.sol";

9:    import "./modules/BaseTOFTMarketModule.sol";

10:   import "./modules/BaseTOFTOptionsModule.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L4

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

5:    import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

6:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

10:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

11:   import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

14:   import "tapioca-periph/contracts/interfaces/IYieldBoxBase.sol";

15:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

16:   import "tapioca-periph/contracts/interfaces/ICommonData.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L5

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:    import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:   import "tapioca-periph/contracts/interfaces/IMagnetar.sol";

11:   import "tapioca-periph/contracts/interfaces/ISingularity.sol";

12:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

13:   import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

14:   import "tapioca-periph/contracts/interfaces/ITapiocaOptionsBroker.sol";

15:   import "tapioca-periph/contracts/interfaces/ITapiocaOptionLiquidityProvision.sol";

17:   import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L5

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:    import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

11:   import "tapioca-periph/contracts/interfaces/IMagnetar.sol";

12:   import "tapioca-periph/contracts/interfaces/IMarket.sol";

13:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

14:   import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

16:   import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L5

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:    import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

9:    import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

10:   import "tapioca-periph/contracts/interfaces/ITapiocaOptionsBroker.sol";

12:   import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L5

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:    import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

12:   import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L5

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

3:    import "./BaseTOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L3

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

3:    import "./BaseTOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L3

File: tap-token-audit/contracts/governance/twTAP.sol

6:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

7:    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

8:    import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

9:    import "../tokens/TapOFT.sol";

10:   import "../twAML.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L6

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

4:    import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

5:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

6:    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

7:    import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

8:    import "@openzeppelin/contracts/security/Pausable.sol";

9:    import "tapioca-periph/contracts/interfaces/IOracle.sol";

10:   import "../tokens/TapOFT.sol";

11:   import "../twAML.sol";

12:   import "./aoTAP.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L4

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

5:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

6:    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

7:    import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

9:    import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L5

File: tap-token-audit/contracts/options/oTAP.sol

5:    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

6:    import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

7:    import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L5

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

4:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

6:    import "@openzeppelin/contracts/security/Pausable.sol";

7:    import "tapioca-periph/contracts/interfaces/IOracle.sol";

8:    import "./TapiocaOptionLiquidityProvision.sol";

9:    import "../tokens/TapOFT.sol";

10:   import "../twAML.sol";

11:   import "./oTAP.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L4

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

5:    import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

8:    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

9:    import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

10:   import "@openzeppelin/contracts/security/Pausable.sol";

11:   import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

12:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L5

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

5:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

7:    import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

8:    import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L5

File: tap-token-audit/contracts/tokens/LTap.sol

4:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:    import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L4

File: tap-token-audit/contracts/tokens/TapOFT.sol

5:    import "./BaseTapOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L5

File: tap-token-audit/contracts/Vesting.sol

4:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

5:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L4

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

5:    import "@openzeppelin/contracts/access/Ownable.sol";

6:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:    import "./MagnetarV2Storage.sol";

10:   import "./modules/MagnetarMarketModule.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L5

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

5:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

8:    import "../interfaces/IOracle.sol";

9:    import "../interfaces/ISingularity.sol";

10:   import "../interfaces/IBigBang.sol";

11:   import "../interfaces/ITapiocaOFT.sol";

12:   import "../interfaces/ISwapper.sol";

13:   import "../interfaces/ITapiocaOptionsBroker.sol";

14:   import "../interfaces/ITapiocaOptionLiquidityProvision.sol";

15:   import "../interfaces/IPenrose.sol";

16:   import "../interfaces/ITapiocaOptionsBroker.sol";

21:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/enums/YieldBoxTokenType.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L5

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

5:    import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:    import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

9:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

10:   import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

13:   import "../../interfaces/IYieldBoxBase.sol";

14:   import "../../interfaces/ITapiocaOptions.sol";

16:   import "../MagnetarV2Storage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L5

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

4:    import "@openzeppelin/contracts/access/Ownable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L4

File: tapioca-periph-audit/contracts/oracle/Seer.sol

4:    import "./OracleMulti.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L4

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

4:    import "@openzeppelin/contracts/access/Ownable.sol";

5:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

7:    import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

9:    import "../interfaces/ISwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L4

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

4:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

5:    import "./interfaces/ICurvePool.sol";

6:    import "./BaseSwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L4

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

4:    import "./interfaces/IUniswapV2Factory.sol";

5:    import "./interfaces/IUniswapV2Router02.sol";

6:    import "./BaseSwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L4

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

4:    import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";

5:    import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";

6:    import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";

7:    import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";

8:    import "@uniswap/v3-periphery/contracts/interfaces/IQuoterV2.sol";

9:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

11:   import "./libraries/OracleLibrary.sol";

12:   import "./BaseSwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:   import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

12:   import "./interfaces/IStkAave.sol";

13:   import "./interfaces/ILendingPool.sol";

14:   import "./interfaces/IIncentivesController.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:   import "./interfaces/IBalancerVault.sol";

12:   import "./interfaces/IBalancerPool.sol";

13:   import "./interfaces/IBalancerHelpers.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

12:   import "../../tapioca-periph/contracts/interfaces/INative.sol";

13:   import "./interfaces/ICToken.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:   import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

12:   import "../curve/interfaces/ITricryptoLPGetter.sol";

14:   import "./interfaces/IConvexBooster.sol";

15:   import "./interfaces/IConvexRewardPool.sol";

16:   import "./interfaces/IConvexZap.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:   import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

13:   import "./interfaces/ITricryptoLPGetter.sol";

14:   import "./interfaces/ITricryptoLPGauge.sol";

15:   import "./interfaces/ICurveMinter.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:   import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

13:   import "./interfaces/ITricryptoLPGetter.sol";

14:   import "./interfaces/ITricryptoLPGauge.sol";

15:   import "./interfaces/ICurveMinter.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

5:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

6:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

7:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

9:    import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";

11:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/enums/YieldBoxTokenType.sol";

12:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

14:   import "../interfaces/IFeeCollector.sol";

15:   import "../interfaces/gmx/IGlpManager.sol";

16:   import "../interfaces/gmx/IGmxRewardDistributor.sol";

17:   import "../interfaces/gmx/IGmxRewardRouter.sol";

18:   import "../interfaces/gmx/IGmxRewardTracker.sol";

19:   import "../interfaces/gmx/IGmxVester.sol";

20:   import "../interfaces/gmx/IGmxVault.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L5

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

12:   import "./interfaces/IStEth.sol";

13:   import "./interfaces/ICurveEthStEthPool.sol";

14:   import "../../tapioca-periph/contracts/interfaces/INative.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:   import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

13:   import "./interfaces/IRouter.sol";

14:   import "./interfaces/IRouterETH.sol";

15:   import "./interfaces/ILPStaking.sol";

16:   import "../../tapioca-periph/contracts/interfaces/INative.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L4

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

4:    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:    import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

12:   import "./interfaces/IYearnVault.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L4

File: YieldBox/contracts/NativeTokenFactory.sol

3:    import "./AssetRegister.sol";

4:    import "./BoringMath.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L3

File: YieldBox/contracts/YieldBoxPermit.sol

5:    import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

6:    import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

7:    import "@openzeppelin/contracts/utils/Counters.sol";

8:    import "./interfaces/IYieldBox.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L5

File: YieldBox/contracts/YieldBoxRebase.sol

5:    import "./interfaces/IStrategy.sol";

6:    import "@boringcrypto/boring-solidity/contracts/interfaces/IERC1155.sol";

7:    import "@boringcrypto/boring-solidity/contracts/libraries/Base64.sol";

8:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringAddress.sol";

9:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:   import "@boringcrypto/boring-solidity/contracts/Domain.sol";

11:   import "./ERC1155TokenReceiver.sol";

12:   import "./ERC1155.sol";

13:   import "@boringcrypto/boring-solidity/contracts/BoringBatchable.sol";

14:   import "@boringcrypto/boring-solidity/contracts/BoringFactory.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L5

File: YieldBox/contracts/YieldBox.sol

26:   import "./interfaces/IWrappedNative.sol";

27:   import "./interfaces/IStrategy.sol";

28:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC721.sol";

29:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC1155.sol";

30:   import "@boringcrypto/boring-solidity/contracts/libraries/Base64.sol";

31:   import "@boringcrypto/boring-solidity/contracts/Domain.sol";

32:   import "./ERC721TokenReceiver.sol";

33:   import "./ERC1155TokenReceiver.sol";

34:   import "./ERC1155.sol";

35:   import "@boringcrypto/boring-solidity/contracts/BoringBatchable.sol";

36:   import "@openzeppelin/contracts/utils/Strings.sol";

37:   import "./AssetRegister.sol";

38:   import "./NativeTokenFactory.sol";

39:   import "./YieldBoxRebase.sol";

40:   import "./YieldBoxURIBuilder.sol";

41:   import "./YieldBoxPermit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L26

File: YieldBox/contracts/YieldBoxURIBuilder.sol

3:    import "@openzeppelin/contracts/utils/Strings.sol";

4:    import "@boringcrypto/boring-solidity/contracts/libraries/Base64.sol";

5:    import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

6:    import "./interfaces/IYieldBox.sol";

7:    import "./NativeTokenFactory.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L3

[N‑30] Return values of approve() not checked

Not all IERC20 implementations revert() when there's a failure in approve(). The function signature has a boolean return value and they indicate errors that way instead. By not checking the return value, operations that should have marked as failed, may potentially go through without actually approving anything

There are 45 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

217:          IERC20(swapData.tokenOut).approve(externalData.tOft, amountOut);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L217

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

215:          IERC20(erc20).approve(externalData.swapper, amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L215

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

184:          _erc20.approve(address(yieldBox), _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L184

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

157               IERC20(collateralAddress).approve(
158                   address(yieldBox),
159                   collateralAmount
160:              );

234:              IERC20(assetAddress).approve(address(yieldBox), depositAmount);

339                   IERC20(bbCollateralAddress).approve(
340                       address(yieldBox),
341                       mintData.collateralDepositData.amount
342:                  );

386               IERC20(sglAssetAddress).approve(
387                   address(yieldBox),
388                   depositData.amount
389:              );

428:              IERC20(address(singularity)).approve(address(yieldBox), fraction);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L157-L160

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

75:           wrappedNative.approve(_lendingPool, type(uint256).max);

76:           rewardToken.approve(_multiSwapper, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L75

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

77:           wrappedNative.approve(_vault, type(uint256).max);

78:           IERC20(address(pool)).approve(_vault, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L77

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

58:           wrappedNative.approve(_cToken, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L58

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

105:          wrappedNative.approve(_lpGetter, type(uint256).max);

106:          lpToken.approve(_lpGetter, type(uint256).max);

107:          lpToken.approve(_booster, type(uint256).max);

108:          rewardToken.approve(_multiSwapper, type(uint256).max);

172:          rewardToken.approve(address(swapper), 0);

174:          rewardToken.approve(_swapper, type(uint256).max);

181:          wrappedNative.approve(address(lpGetter), 0);

183:          wrappedNative.approve(_lpGetter, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L105

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

79:           lpToken.approve(_lpGauge, type(uint256).max);

80:           lpToken.approve(_lpGetter, type(uint256).max);

81:           rewardToken.approve(_multiSwapper, type(uint256).max);

82:           wrappedNative.approve(_lpGetter, type(uint256).max);

143:          rewardToken.approve(address(swapper), 0);

144:          rewardToken.approve(_swapper, type(uint256).max);

152:          wrappedNative.approve(address(lpGetter), 0);

154:          wrappedNative.approve(_lpGetter, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L79

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

78:           IERC20(lpGetter.lpToken()).approve(_lpGauge, type(uint256).max);

79:           IERC20(lpGetter.lpToken()).approve(_lpGetter, type(uint256).max);

80:           rewardToken.approve(_multiSwapper, type(uint256).max);

81:           wrappedNative.approve(_lpGetter, type(uint256).max);

134:          rewardToken.approve(address(swapper), 0);

135:          rewardToken.approve(_swapper, type(uint256).max);

143:          wrappedNative.approve(address(lpGetter), 0);

145:          wrappedNative.approve(_lpGetter, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L78

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

175:              weth.approve(address(glpManager), wethAmount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L175

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

62:           IERC20(_stEth).approve(_curvePool, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L62

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

89:           stgNative.approve(_lpStaking, type(uint256).max);

90:           stgNative.approve(address(router), type(uint256).max);

94:           stgTokenReward.approve(_swapper, type(uint256).max);

151:          stgTokenReward.approve(address(swapper), 0);

153:          stgTokenReward.approve(_swapper, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L89

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

59:           wrappedNative.approve(address(vault), type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L59

[N‑31] Contract implements interface without extending the interface

Not extending the interface may lead to the wrong function signature being used, leading to unexpected behavior. If the interface is in fact being implemented, use the override keyword to indicate that fact

There are 9 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit IAPWineIBT.transfer(), IAPWineIBT.transferFrom()
24:   contract MarketERC20 is IERC20, IERC20Permit, EIP712 {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L24

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

/// @audit IAPWineIBT.symbol(), IAPWineIBT.name(), IAPWineIBT.decimals()
34:   contract SGLStorage is BoringOwnable, Market {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L34

File: tapioca-bar-audit/contracts/usd0/USDO.sol

/// @audit IAPWineIBT.mint()
24:   contract USDO is BaseUSDO, IERC3156FlashLender {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L24

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

/// @audit IAPWineIBT.burn()
32:   contract AOTAP is ERC721, ERC721Permit, BaseBoringBatchable, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L32

File: tap-token-audit/contracts/options/oTAP.sol

/// @audit IAPWineIBT.burn()
30:   contract OTAP is ERC721, ERC721Permit, BaseBoringBatchable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L30

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit IERC1155Receiver.onERC1155Received()
48:   contract TapiocaOptionLiquidityProvision is

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L48

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit IAPWineIBT.decimals()
30:   contract ARBTriCryptoOracle is ITOracle {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L30

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

/// @audit IAPWineIBT.decimals()
7:    contract GLPOracle is IOracle {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L7

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit IAPWineIBT.decimals()
23:   contract SGOracle is IOracle {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L23

[N‑32] override function arguments that are unused should have the variable name removed or commented out to avoid compiler warnings

There are 5 instances of this issue:

File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

427:          address to,

428:          uint256 amount

432:          address from,

433:          address to,

434:          uint256 amount

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L427

[N‑33] Cast is more restrictive than the type of the variable being assigned

If address foo is being used in an expression such as IERC20 token = FooToken(foo), then the more specific cast to FooToken is a waste because the only thing the compiler will check for is that FooToken extends IERC20 - it won't check any of the function signatures. Therefore, it makes more sense to do IERC20 token = IERC20(token) or better yet FooToken token = FooToken(foo). The former may allow the file in which it's used to remove the import for FooToken

There are 8 instances of this issue:

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit uint96 vs uint256
104           tapAssetId = uint96(
105               _yieldBox.registerAsset(
106                   TokenType.ERC20,
107                   address(tapToken_),
108                   emptyStrategies[address(tapToken_)],
109                   0
110               )
111:          );

/// @audit uint96 vs uint256
122           wethAssetId = uint96(
123               _yieldBox.registerAsset(
124                   TokenType.ERC20,
125                   address(wethToken_),
126                   emptyStrategies[address(wethToken_)],
127                   0
128               )
129:          );

/// @audit IERC20 vs address
292:          usdoToken = IERC20(_usdoToken);

/// @audit uint96 vs uint256
302           usdoAssetId = uint96(
303               yieldBox.registerAsset(
304                   TokenType.ERC20,
305                   _usdoToken,
306                   emptyStrategies[_usdoToken],
307                   0
308               )
309:          );

/// @audit deploy vs address
373:          _contract = deploy(mc, data, useCreate2);

/// @audit deploy vs address
406:          _contract = deploy(mc, data, useCreate2);

/// @audit clonesOfCount vs uint256
566:                  clonesOfLength = clonesOfCount(mcLocation);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L104-L111

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit uint128 vs uint256
292:          epochTAPValuation = uint128(_epochTAPValuation);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L292

[N‑34] Events that mark critical parameter changes should contain both the old and the new value

This should especially be done if the new value is not required to be different from the old value

There are 59 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit setBigBangConfig()
477:                  emit MinDebtRateUpdated(minDebtRate, _minDebtRate);

/// @audit setBigBangConfig()
483:                  emit MaxDebtRateUpdated(maxDebtRate, _maxDebtRate);

/// @audit setBigBangConfig()
488                   emit DebtRateAgainstEthUpdated(
489                       debtRateAgainstEthMarket,
490                       _debtRateAgainstEthMarket
491:                  );

/// @audit setBigBangConfig()
500                   emit LiquidationMultiplierUpdated(
501                       liquidationMultiplier,
502                       _liquidationMultiplier
503:                  );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L477

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit setBorrowOpeningFee()
144:          emit LogBorrowingFee(borrowOpeningFee, _val);

/// @audit setBorrowCap()
152:          emit LogBorrowCapUpdated(totalBorrowCap, _cap);

/// @audit setMarketConfig()
173:              emit LogBorrowingFee(borrowOpeningFee, _borrowOpeningFee);

/// @audit setMarketConfig()
179:              emit OracleUpdated();

/// @audit setMarketConfig()
184:              emit OracleDataUpdated();

/// @audit setMarketConfig()
188:              emit ConservatorUpdated(conservator, _conservator);

/// @audit setMarketConfig()
229:              emit LogBorrowCapUpdated(totalBorrowCap, _totalBorrowCap);

/// @audit updatePause()
248:          emit PausedUpdated(paused, val);

/// @audit updateExchangeRate()
346:              emit LogExchangeRate(rate);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L144

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit setSingularityConfig()
499               emit MinimumTargetUtilizationUpdated(
500                   minimumTargetUtilization,
501                   _minimumTargetUtilization
502:              );

/// @audit setSingularityConfig()
511               emit MaximumTargetUtilizationUpdated(
512                   maximumTargetUtilization,
513                   _maximumTargetUtilization
514:              );

/// @audit setSingularityConfig()
526               emit MinimumInterestPerSecondUpdated(
527                   minimumInterestPerSecond,
528                   _minimumInterestPerSecond
529:              );

/// @audit setSingularityConfig()
538               emit MaximumInterestPerSecondUpdated(
539                   maximumInterestPerSecond,
540                   _maximumInterestPerSecond
541:              );

/// @audit setSingularityConfig()
558               emit LqCollateralizationRateUpdated(
559                   lqCollateralizationRate,
560                   _lqCollateralizationRate
561:              );

/// @audit setSingularityConfig()
567               emit LiquidationMultiplierUpdated(
568                   liquidationMultiplier,
569                   _liquidationMultiplier
570:              );

/// @audit setLiquidationQueueConfig()
587:              emit BidExecutionSwapperUpdated(_bidExecutionSwapper);

/// @audit setLiquidationQueueConfig()
592:              emit UsdoSwapperUpdated(_usdoSwapper);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L499-L502

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit setBigBangEthMarketDebtRate()
258:          emit BigBangEthMarketDebtRate(_rate);

/// @audit setBigBangEthMarket()
265:          emit BigBangEthMarketSet(_market);

/// @audit updatePause()
274:          emit PausedUpdated(paused, val);

/// @audit setConservator()
283:          emit ConservatorUpdated(conservator, _conservator);

/// @audit setUsdoToken()
310:          emit UsdoTokenUpdated(_usdoToken, usdoAssetId);

/// @audit registerSingularityMasterContract()
332:          emit RegisterSingularityMasterContract(mcAddress, contractType_);

/// @audit registerBigBangMasterContract()
354:          emit RegisterBigBangMasterContract(mcAddress, contractType_);

/// @audit registerSingularity()
375:          emit RegisterSingularity(_contract, mc);

/// @audit registerBigBang()
408:          emit RegisterBigBang(_contract, mc);

/// @audit setFeeTo()
457:          emit FeeToUpdate(feeTo_);

/// @audit setSwapper()
466:          emit SwapperUpdate(address(swapper), enable);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L258

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit setMaxFlashMintable()
89:           emit MaxFlashMintUpdated(maxFlashMint, _val);

/// @audit setFlashMintFee()
98:           emit FlashMintFeeUpdated(flashMintFee, _val);

/// @audit setConservator()
107:          emit ConservatorUpdated(conservator, _conservator);

/// @audit updatePause()
117:          emit PausedUpdated(paused, val);

/// @audit setMinterStatus()
127:          emit SetMinterStatus(_for, _status);

/// @audit setBurnerStatus()
136:          emit SetBurnerStatus(_for, _status);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L89

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

/// @audit updateConnectedChain()
120           emit ConnectedChainStatusUpdated(
121               _chain,
122               connectedChains[_chain],
123               _status
124:          );

/// @audit updateBalancerState()
135:          emit BalancerStatusUpdated(_balancer, balancers[_balancer], _status);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L120-L124

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit setTapOracle()
315:          emit SetTapOracle(_tapOracle, _tapOracleData);

/// @audit setPaymentToken()
352:          emit SetPaymentToken(_paymentToken, _oracle, _oracleData);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L315

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit setTapOracle()
453:          emit SetTapOracle(_tapOracle, _tapOracleData);

/// @audit setPaymentToken()
466:          emit SetPaymentToken(_paymentToken, _oracle, _oracleData);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L453

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit setSGLPoolWEight()
269:          emit SetSGLPoolWeight(address(singularity), weight);

/// @audit registerSingularity()
292:          emit RegisterSingularity(address(singularity), assetID);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L269

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit setGovernanceChainIdentifier()
143           emit GovernanceChainIdentifierUpdated(
144               governanceChainIdentifier,
145               _identifier
146:          );

/// @audit updatePause()
154:          emit PausedUpdated(paused, val);

/// @audit setMinter()
162:          emit MinterUpdated(minter, _minter);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L143-L146

File: tap-token-audit/contracts/Vesting.sol

/// @audit registerUser()
145:          emit UserRegistered(_user, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L145

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit setPoolFee()
62:           emit PoolFee(poolFee, _newFee);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L62

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit setMultiSwapper()
130:          emit MultiSwapper(address(swapper), _swapper);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L130

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit setMultiSwapper()
171:          emit MultiSwapper(address(swapper), _swapper);

/// @audit setTricryptoLPGetter()
180:          emit LPGetterSet(address(lpGetter), _lpGetter);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L171

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit setMultiSwapper()
142:          emit MultiSwapper(address(swapper), _swapper);

/// @audit setTricryptoLPGetter()
151:          emit LPGetterSet(address(lpGetter), _lpGetter);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L142

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit setMultiSwapper()
133:          emit MultiSwapper(address(swapper), _swapper);

/// @audit setTricryptoLPGetter()
142:          emit LPGetterSet(address(lpGetter), _lpGetter);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L133

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit setMultiSwapper()
150:          emit MultiSwapper(address(swapper), _swapper);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L150

[N‑35] Constant redefined elsewhere

Consider defining in only one contract so that values cannot become out of sync when only one location is updated. A cheap way to store constants in a single location is to create an internal constant in a library. If the variable is a local cache of another contract's value, consider making the cache variable internal or private, which will require external users to query the contract with the source of truth, so that callers don't get out of sync.

There are 23 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

/// @audit seen in tapioca-bar-audit/contracts/Penrose.sol 
19:       IYieldBoxBase public immutable yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L19

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit seen in tap-token-audit/contracts/governance/twTAP.sol 
45:       TapOFT public immutable tapOFT;

/// @audit seen in tap-token-audit/contracts/governance/twTAP.sol 
95:       uint256 public constant EPOCH_DURATION = 2 days;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L45

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit seen in tap-token-audit/contracts/option-airdrop/AirdropBroker.sol 
56:       TapOFT public immutable tapOFT;

/// @audit seen in tap-token-audit/contracts/option-airdrop/AirdropBroker.sol 
78:       uint256 public immutable EPOCH_DURATION; // 7 days = 604800

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L56

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

/// @audit seen in tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol 
28:       IYieldBox public immutable yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L28

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit seen in tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol 
35:       ISwapRouter public immutable swapRouter;

/// @audit seen in tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol 
36:       IUniswapV3Factory public immutable factory;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L35

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol 
34:       IERC20 public immutable wrappedNative;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L34

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol 
34:       IERC20 public immutable wrappedNative;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L34

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol 
41:       IERC20 public immutable wrappedNative;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol 
52:       IERC20 public immutable rewardToken;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L41

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol 
40:       IERC20 public immutable lpToken;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol 
41:       IERC20 public immutable wrappedNative;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol 
47:       IERC20 public immutable rewardToken; //CRV token

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L40

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol 
40:       IERC20 public immutable wrappedNative;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol 
43:       ITricryptoLPGauge public immutable lpGauge;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol 
44:       ICurveMinter public immutable minter;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol 
46:       IERC20 public immutable rewardToken; //CRV token

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L40

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol 
36:       IERC20 public immutable wrappedNative;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L36

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol 
41:       IERC20 public immutable wrappedNative;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L41

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol 
36:       IERC20 public immutable wrappedNative;

/// @audit seen in tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol 
37:       IYearnVault public immutable vault;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L36

[N‑36] Use @inheritdoc rather than using a non-standard annotation

There are 5 instances of this issue:

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

120       /**
121        * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
122        */
123       // solhint-disable-next-line func-name-mixedcase
124:      function DOMAIN_SEPARATOR() external view override returns (bytes32) {

209       /**
210        * @dev See {IERC20Permit-permit}.
211        */
212       function permit(
213           address owner,
214           address spender,
215           uint256 value,
216           uint256 deadline,
217           uint8 v,
218           bytes32 r,
219:          bytes32 s

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L120-L124

File: tap-token-audit/contracts/governance/twTAP.sol

579       /**
580        * @dev See {IERC165-supportsInterface}.
581        */
582       function supportsInterface(
583           bytes4 interfaceId
584:      ) public view virtual override(ONFT721, ERC721) returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L579-L584

File: YieldBox/contracts/YieldBoxPermit.sol

98        /**
99         * @dev See {IERC20Permit-nonces}.
100        */
101:      function nonces(address owner) public view virtual returns (uint256) {

105       /**
106        * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
107        */
108       // solhint-disable-next-line func-name-mixedcase
109:      function DOMAIN_SEPARATOR() external view returns (bytes32) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L98-L101

[N‑37] Inconsistent spacing in comments

Some lines use // x and some use //x. The instances below point out the usages that don't follow the majority, within each file

There are 315 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

168:          liquidationMultiplier = 12000; //12%

420:              //repay as much as we can

519:          //update debt rate

521:          _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second

730:          uint256 toWithdraw = (amount - part); //acrrued

733:          //burn USDO

757:          //mint USDO

760:          //deposit borrowed amount to user

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L18

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L11

File: tapioca-bar-audit/contracts/markets/Market.sol

66:       uint256 public minLiquidatorReward = 1e3; //1%

68:       uint256 public maxLiquidatorReward = 1e4; //10%

71:       uint256 public liquidationBonusAmount = 1e4; //10%

75:       uint256 public borrowOpeningFee = 50; //0.05%

77:       uint256 public liquidationMultiplier = 12000; //12%

82:       uint256 internal EXCHANGE_RATE_PRECISION; //not costant, but can only be set in the 'init' method

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L66

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

246:                  _yieldBoxShares[from][ASSET_SIG] = 0; //some assets accrue in time

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L246

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

51:               _yieldBoxShares[from][COLLATERAL_SIG] = 0; //accrues in time

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L51

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

34:           //add collateral

43:           //borrow

46:           //withdraw

80:           //send for unwrap

133:              //repay as much as we can

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L34

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

21:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

22:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

23:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

24:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

25:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

26:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

27:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

28:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L21

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

121:          //default fees

126:          //liquidation

127:          liquidationMultiplier = 12000; //12%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L18

File: tapioca-bar-audit/contracts/Penrose.sol

16:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

17:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

18:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

19:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

20:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

21:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

22:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

23:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L16

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

201:          // Use market helper to deposit and add asset to market

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L201

File: tapioca-bar-audit/contracts/usd0/USDO.sol

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L11

File: tapiocaz-audit/contracts/Balancer.sol

155:                  1e3, //1% slippage

188:          //check if OFT is still valid

197:          //extract

200:          //send

290:              _oft, //refund

326:              _oft, //refund,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L155

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

13:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

14:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

15:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

16:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

17:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

18:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

19:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L13

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

85:           if (_decimalCache == 0) return 18; //temporary fix for LZ _sharedDecimals check

347:      //---internal-

378:      //---private---

441:      //---LZ---

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L85

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

135:              address _from, //from

174:              revert(_getRevertMsg(reason)); //forward revert because it's handled by the main executor

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L135

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

167:              revert(_getRevertMsg(reason)); //forward revert because it's handled by the main executor

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L167

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

7:     _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

8:      _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

9:       _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

10:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

11:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

12:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

13:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L7

File: tap-token-audit/contracts/governance/twTAP.sol

14:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

15:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

16:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

17:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

18:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

19:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

20:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L14

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

17:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

18:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

19:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

20:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

21:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

22:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

23:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

24:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L17

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

14:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

15:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

16:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

17:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

18:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

19:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

20:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

21:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L14

File: tap-token-audit/contracts/options/oTAP.sol

12:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

13:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

14:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

15:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

16:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

17:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

18:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

19:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L12

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

16:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

17:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

18:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

19:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

20:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

21:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

22:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

23:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L16

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

17:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

18:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

19:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

20:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

21:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

22:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

23:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

24:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L17

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

13:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

14:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

15:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

16:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

17:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

18:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

19:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

20:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

51:       //---LZ---

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L13

File: tap-token-audit/contracts/tokens/LTap.sol

28:       /// @notice Creates a new LTAP token

29:       /// @dev LTAP tokens are minted by depositing TAP

30:       /// @param _tapToken Address of the TAP token

31:       /// @param _maxLockedUntil Latest possible end of locking period

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L28

File: tap-token-audit/contracts/tokens/TapOFT.sol

10:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

11:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

12:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

13:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

14:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

15:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

16:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

17:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

137:      ///-- Owner methods --

166:      //-- View methods --

194:      ///-- Write methods --

238:      ///-- Internal methods --

245:      ///-- Private methods --

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L10

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

15:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

16:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

17:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

18:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

19:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

20:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

21:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

22:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L15

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

144:          //deposit to YieldBox

274:              //withdraw

354:                  //add collateral to BingBang

590:              //withdraw

651:              //withdraw

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L144

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

74:               // Humanity will be a Type V Kardashev Civilization before this overflows - andreas

75:               // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256

89:           // Finally, make sure the msg.value = SUM(call[0...i].value)

94:           // If the _res length is less than 68, then

95:           // the transaction failed with custom error or silently (without a revert message)

99:               // Slice the sighash.

102:          revert(abi.decode(_returnData, (string))); // All that remains is the revert string

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L74

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L11

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L11

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

17:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

18:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

19:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

20:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

21:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

22:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

23:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L17

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

38:       //AAVE

113:              result = result - (result * 50) / 10_000; //0.5%

140:          //first claim stkAave

154:          //try to claim AAVE

162:          //try to cooldown

169:              //we have an active cooldown; check if we need to cooldown again

178:          //try to stake

183:              //swap AAVE to wrappedNative

193:              uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

196:              //stake if > depositThreshold

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L18

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

39:       IBalancerPool public immutable pool; //lp token

122:          toWithdraw = toWithdraw - (toWithdraw * 50) / 10_000; //0.5%

177:          bptOut = bptOut - (bptOut * 50) / 10_000; //0.5%

250:          bptIn = bptIn + (bptIn * 250) / 10_000; //2.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L18

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L18

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

21:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

22:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

23:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

24:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

25:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

26:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

27:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

143:              result = result - (result * 50) / 10_000; //0.5%

154:          uint256 minAmount = (calcWithdraw * 50) / 10_000; //0.5%

207:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

313:              uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

336:              uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L21

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

20:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

21:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

22:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

23:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

24:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

25:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

26:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

47:       IERC20 public immutable rewardToken; //CRV token

179:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

186:                  minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L20

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

20:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

21:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

22:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

23:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

24:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

25:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

26:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

46:       IERC20 public immutable rewardToken; //CRV token

116:              result = result - (result * 50) / 10_000; //0.5%

170:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

188:          uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

201:          return assetAmount + queued; //+ compoundAmount;

232:              uint256 minAmount = calcWithdraw - (calcWithdraw * 50) / 10_000; //0.5%

249:          uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L20

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

19:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

20:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

21:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

22:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

23:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

24:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

25:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

108:          uint256 minAmount = (toWithdraw * 50) / 10_000; //0.5%

133:              stEth.submit{value: queued}(address(0)); //1:1 between eth<>stEth

150:              uint256 toWithdraw = amount - queued; //1:1 between eth<>stEth

151:              uint256 minAmount = toWithdraw - (toWithdraw * 250) / 10_000; //2.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L19

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

21:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

22:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

23:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

24:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

25:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

26:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

27:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

51:       IERC20 public stgNative; //ex: stEth

133:              result = result - (result * 50) / 10_000; //0.5%

182:                  uint256 minAmount = calcAmount - (calcAmount * 50) / 10_000; //0.5%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L21

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

16:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

17:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

18:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

19:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

20:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

21:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

22:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

147:          wrappedNative.safeTransfer(to, amount - 1); //rounding error

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L16

[N‑38] Lines are too long

Usually lines in source code are limited to 80 characters. Today's screens are much larger so it's reasonable to stretch this in some cases. The solidity style guide recommends a maximumum line length of 120 characters, so the lines below should be split when they reach that length.

There are 361 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

17:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

34:   ///     - interest rate is not fixed, but dynamic based on the main BigBang market, minDebtRate, maxDebtRate and debtRateAgainstEthMarket

35:   ///         - BigBang markets can either be main or secondary markets; the main market is set on Penrose and has a fixed rate

37:   ///             - if current debt is over _maxDebtPoint = (_ethMarketTotalDebt * debtRateAgainstEthMarket) / 1e18, the interest rate is automatically `maxDebtRate`

258:      /// @dev The bool param is not used but we added it to respect the ISingularity interface for MarketsHelper compatibility

306:      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.

655:      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L17

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

10:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L10

File: tapioca-bar-audit/contracts/markets/Market.sol

299:      /// @notice return the amount of collateral for a `user` to be solvent, min TVL and max TVL. Returns 0 if user already solvent.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L299

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

21:       /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.

373:      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L21

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

20:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

21:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

22:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

23:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

24:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

25:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

26:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

27:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

28:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

44:       Rebase public totalAsset; // elastic = yieldBox shares held by the Singularity, base = Total fractions held by asset suppliers

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L20

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

17:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

35:   ///     - adding assets to the contract, mints shares to the `to` address which can later be used in the oTap & twTap system

36:   ///     - interest rate is automatically updated based on the interest elasticity time and it's bounded by `minimumInterestPerSecond` and `maximumInterestPerSecond`

432:      /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L17

File: tapioca-bar-audit/contracts/Penrose.sol

15:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

16:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

17:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

18:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

19:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

20:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

21:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

22:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

23:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L15

File: tapioca-bar-audit/contracts/usd0/USDO.sol

10:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L10

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

12:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

13:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

14:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

15:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

16:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

17:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

18:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

19:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

20:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L12

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

8:    ///      - wrapping & unwrapping of the ERC20/the gas token can happen on multiple chains defined by the `connectedChains` mapping

85:       /// @dev Since it can be executed only on the main chain, if an address exists on the OP chain it will not allowed to wrap.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L8

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

6:    __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

7:     _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

8:      _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

9:       _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

10:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

11:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

12:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

13:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

14:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

65:       /// @dev Since it can be executed only on the main chain, if an address exists on the OP chain it will not allowed to wrap.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L6

File: tap-token-audit/contracts/governance/twTAP.sol

13:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

14:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

15:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

16:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

17:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

18:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

19:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

20:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

21:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

64:   /// @dev This contract allow the locking of TAP to twTAP. The amount of twTAP received is based on the amount of locked TAP, and the duration of the lock.

65:   ///      It uses twAML to compute the amount of twTAP received, details about the model can be found here https://docs.tapioca.xyz/tapioca/core-technologies/twaml.

66:   ///      The contract distributes a set of rewards tokens each week to the twTAP holders. The amount of rewards received is based on the amount of twTAP held.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L13

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

16:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

17:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

18:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

19:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

20:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

21:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

22:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

23:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

24:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

38:   /// @notice Forked version of TapiocaOptionBroker. More details found here https://docs.tapioca.xyz/tapioca/launch/option-airdrop#eligibility-and-details

39:   /// @dev This contract is used to manage the Tapioca Option Airdrop. It allows for users to participate in the airdrop and exercise their options.

136:      /// @param _tapAmount The amount of TAP to be exchanged. If 0 it will use the full amount of TAP eligible for the deal

407:      /// @notice Participate in phase 2 of the Airdrop. Guild members will receive pre-defined discounts and TAP, based on role.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L16

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

13:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

14:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

15:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

16:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

17:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

18:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

19:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

20:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

21:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L13

File: tap-token-audit/contracts/options/oTAP.sol

11:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

12:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

13:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

14:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

15:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

16:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

17:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

18:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

19:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L11

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

15:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

16:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

17:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

18:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

19:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

20:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

21:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

22:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

23:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

45:   /// @notice This contract handles the creation of oTAP, the oTAP options creates an expiry dates to exercise the option, and an eligible amount of TAP that can be exercised.

46:   ///         The amount of TAP that can be exercised is calculated by the TWAML algorithm, which takes into account the size of the participant as well his lock time.

48:   ///         More info about the mechanic of how to receive oTAP can be found here https://docs.tapioca.xyz/tapioca/token-economy/dso-dao-share-options

141:      /// @param _tapAmount The amount of TAP to be exchanged. If 0 it will use the full amount of TAP eligible for the deal

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L15

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

16:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

17:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

18:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

19:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

20:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

21:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

22:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

23:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

24:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

42:   ///         tOLP tokens are minted when a user locks their Singularity position and can be burned only when the position is unlocked,

62:       mapping(uint256 => IERC20) public sglAssetIDToAddress; // Singularity market YieldBox asset ID => Singularity market address

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L16

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

12:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

13:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

14:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

15:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

16:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

17:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

18:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

19:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

20:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L12

File: tap-token-audit/contracts/tokens/LTap.sol

9:    __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

10:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

11:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

12:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

13:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

14:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

15:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

16:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

17:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L9

File: tap-token-audit/contracts/tokens/TapOFT.sol

9:    __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

10:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

11:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

12:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

13:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

14:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

15:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

16:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

17:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L9

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

14:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

15:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

16:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

17:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

18:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

19:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

20:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

21:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

22:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

880:      /// @notice helper to exit from  tOB, unlock from tOLP, remove from SGL, repay on BB, remove collateral from BB and withdraw

885:      ///         - if `!removeAndRepayData.assetWithdrawData.withdraw && removeAndRepayData.repayAssetOnBB`, the repay operation is performed

887:      ///     - the helper can either stop at the remove asset from SGL step or it can continue until is removes & withdraws collateral from BB

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L14

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

257:          // if `withdrawCollateralParams.withdraw` it uses `withdrawTo` to withdraw collateral on the same chain or to another one

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L257

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

8:    __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

9:     _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

10:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

11:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

12:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

13:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

14:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

15:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

16:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L8

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

68:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

79:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

88:       /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek().

90:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

100:      /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

108:      /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L68

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

58:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

69:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

78:       /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek().

80:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

90:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

98:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L58

File: tapioca-periph-audit/contracts/oracle/Seer.sol

49:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

61:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

71:       /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek().

73:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

84:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

92:       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L49

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

10:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L10

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

10:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

11:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

12:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

13:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

14:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

15:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

16:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

17:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

18:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L10

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

16:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

17:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

18:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

19:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

20:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

21:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

22:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

23:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

24:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L16

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

17:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L17

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

17:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L17

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

17:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

18:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

19:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

20:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

21:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

22:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

23:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

24:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

25:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L17

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

20:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

21:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

22:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

23:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

24:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

25:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

26:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

27:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

28:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L20

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

19:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

20:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

21:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

22:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

23:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

24:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

25:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

26:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

27:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L19

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

19:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

20:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

21:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

22:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

23:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

24:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

25:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

26:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

27:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L19

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

18:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

19:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

20:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

21:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

22:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

23:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

24:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

25:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

26:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L18

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

20:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

21:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

22:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

23:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

24:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

25:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

26:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

27:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

28:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

31:   //TODO: decide if we need to start with ETH and wrap it into WETH; stargate allows ETH. not WETH, while others allow WETH, not ETH

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L20

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

15:   __/\\\\\\\\\\\\\\\_____/\\\\\\\\\_____/\\\\\\\\\\\\\____/\\\\\\\\\\\_______/\\\\\_____________/\\\\\\\\\_____/\\\\\\\\\____        

16:    _\///////\\\/////____/\\\\\\\\\\\\\__\/\\\/////////\\\_\/////\\\///______/\\\///\\\________/\\\////////____/\\\\\\\\\\\\\__       

17:     _______\/\\\________/\\\/////////\\\_\/\\\_______\/\\\_____\/\\\_______/\\\/__\///\\\____/\\\/____________/\\\/////////\\\_      

18:      _______\/\\\_______\/\\\_______\/\\\_\/\\\\\\\\\\\\\/______\/\\\______/\\\______\//\\\__/\\\_____________\/\\\_______\/\\\_     

19:       _______\/\\\_______\/\\\\\\\\\\\\\\\_\/\\\/////////________\/\\\_____\/\\\_______\/\\\_\/\\\_____________\/\\\\\\\\\\\\\\\_    

20:        _______\/\\\_______\/\\\/////////\\\_\/\\\_________________\/\\\_____\//\\\______/\\\__\//\\\____________\/\\\/////////\\\_   

21:         _______\/\\\_______\/\\\_______\/\\\_\/\\\_________________\/\\\______\///\\\__/\\\_____\///\\\__________\/\\\_______\/\\\_  

22:          _______\/\\\_______\/\\\_______\/\\\_\/\\\______________/\\\\\\\\\\\____\///\\\\\/________\////\\\\\\\\\_\/\\\_______\/\\\_ 

23:           _______\///________\///________\///__\///______________\///////////_______\/////_____________\/////////__\///________\///__

26:   //TODO: decide if we need to start with ETH and wrap it into WETH; stargate allows ETH. not WETH, while others allow WETH, not ETH

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L15

File: YieldBox/contracts/NativeTokenFactory.sol

55:       /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise.

56:       function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {

89:       /// @param decimals The number of decimals of the token (this is just for display purposes). Should be set to 18 in normal cases.

90:       function createToken(string calldata name, string calldata symbol, uint8 decimals, string calldata uri) public returns (uint32 tokenId) {

91:           // To keep each Token unique in the AssetRegister, we use the assetId as the tokenId. So for native assets, the tokenId is always equal to the assetId.

104:      /// @notice The `owner` can mint tokens. If a fixed supply is needed, the `owner` should mint the totalSupply and renounce ownership.

108:      /// @dev For security reasons, operators are not allowed to mint. Only the actual owner can do this. Of course the owner can be a contract.

121:      /// @notice The `owner` can mint tokens. If a fixed supply is needed, the `owner` should mint the totalSupply and renounce ownership.

125:      /// @dev If the tos array is longer than the amounts array there will be an out of bounds error. If the amounts array is longer, the extra amounts are simply ignored.

126:      /// @dev For security reasons, operators are not allowed to mint. Only the actual owner can do this. Of course the owner can be a contract.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L55

File: YieldBox/contracts/YieldBoxPermit.sol

53:           bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, assetId, _useNonce(owner), deadline));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L53

File: YieldBox/contracts/YieldBox.sol

4:    // The original BentoBox is owned by the Sushi team to set strategies for each token. Abracadabra wanted different strategies, which led to

5:    // them launching their own DegenBox. The YieldBox solves this by allowing an unlimited number of strategies for each token in a fully

127:          require(asset.tokenType != TokenType.Native && asset.tokenType != TokenType.ERC721, "YieldBox: can't deposit type");

135:              // amount may be lower than the value of share due to rounding, in that case, add 1 to amount (Always round up)

143:              // For ERC20 tokens, use the safe helper function to deal with broken ERC20 implementations. This actually calls transferFrom on the ERC20 contract.

151:                  IERC1155(asset.contractAddress).safeTransferFrom(from, address(asset.strategy), asset.tokenId, amount, "");

196:      function depositETHAsset(uint256 assetId, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

199:          require(asset.tokenType == TokenType.ERC20 && asset.contractAddress == address(wrappedNative), "YieldBox: not wrappedNative");

208:          // Strategies always receive wrappedNative (supporting both wrapped and raw native tokens adds too much complexity)

281:              // value of the share paid could be lower than the amount paid due to rounding, in that case, add a share (Always round up)

316:      function _transferBatch(address from, address to, uint256[] calldata ids, uint256[] calldata values) internal override {

336:      function transferMultiple(address from, address[] calldata tos, uint256 assetId, uint256[] calldata shares) public allowed(from, assetId) {

400:      // This functionality has been split off into a separate contract. This is only a view function, so gas usage isn't a huge issue.

489:              return depositAsset(registerAsset(TokenType.ERC1155, address(this), strategy, tokenId), from, to, amount, share);

500:      function depositETH(IStrategy strategy, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L4

File: YieldBox/contracts/YieldBoxURIBuilder.sol

90:                   abi.encodePacked("ERC1155:", uint256(uint160(asset.contractAddress)).toHexString(20), "/", asset.tokenId.toString())

107:                  : abi.encodePacked(',"totalSupply":', totalSupply.toString(), ',"fixedSupply":', owner == address(0) ? "true" : "false")

129:                              asset.tokenType == TokenType.ERC1155 ? string(abi.encodePacked(',"tokenId":', asset.tokenId.toString())) : "",

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L90

[N‑39] Variable names that consist of all capital letters should be reserved for constant/immutable variables

If the variable needs to be different based on which class it comes from, a view/pure function should be used instead (e.g. like this).

There are 6 instances of this issue:

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

45:       bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L45

File: tapioca-bar-audit/contracts/markets/Market.sol

82:       uint256 internal EXCHANGE_RATE_PRECISION; //not costant, but can only be set in the 'init' method

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L82

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

50        bytes32 internal ASSET_SIG =
51:           0x0bd4060688a1800ae986e4840aebc924bb40b5bf44de4583df2257220b54b77c; // keccak256("asset")

52        bytes32 internal COLLATERAL_SIG =
53:           0x7d1dc38e60930664f8cbf495da6556ca091d2f92d6550877750c049864b18230; // keccak256("collateral")

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L50-L51

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

77:       uint8[4] public PHASE_2_AMOUNT_PER_USER = [200, 190, 200, 190];

78:       uint8[4] public PHASE_2_DISCOUNT_PER_USER = [50, 40, 40, 33];

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L77

[N‑40] Non-library/interface files should use fixed compiler versions, not floating ones

There are 59 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L2

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L2

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L2

File: tapioca-bar-audit/contracts/Penrose.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L2

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L2

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L2

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L2

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L2

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L2

File: tapioca-bar-audit/contracts/usd0/USDO.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L2

File: tapiocaz-audit/contracts/Balancer.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L2

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L2

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L2

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L2

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L2

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L2

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L2

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L2

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L2

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L2

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L2

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L2

File: tap-token-audit/contracts/options/oTAP.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L2

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L2

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L2

File: tap-token-audit/contracts/tokens/LTap.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L2

File: tap-token-audit/contracts/tokens/TapOFT.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L2

File: tap-token-audit/contracts/Vesting.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L2

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L2

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L2

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L2

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L2

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

2:    pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L2

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

2:    pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L2

File: tapioca-periph-audit/contracts/oracle/Seer.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L2

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L2

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L2

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L2

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L2

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

2:    pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L2

File: YieldBox/contracts/NativeTokenFactory.sol

2:    pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L2

File: YieldBox/contracts/YieldBox.sol

24:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L24

File: YieldBox/contracts/YieldBoxURIBuilder.sol

2:    pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L2

[N‑41] Typos

There are 31 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit repayed
262:      /// @return amount The total amount repayed.

/// @audit Mininal
332:      /// @param minAmountOut Mininal collateral amount to receive

/// @audit Mininal
380:      /// @param minAmountOut Mininal proceeds required for the sale

/// @audit necessar
657:      /// @param swapData Swap necessar data

/// @audit acrrued
730:          uint256 toWithdraw = (amount - part); //acrrued

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L262

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit repayed
50:       /// @dev elastic = Total token amount to be repayed by borrowers, base = Total parts of the debt held by borrowers

/// @audit costant
82:       uint256 internal EXCHANGE_RATE_PRECISION; //not costant, but can only be set in the 'init' method

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L50

File: tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol

/// @audit repayed
44:       /// @return amount The total amount repayed.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L44

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

/// @audit Mininal
93:       /// @param minAmountOut Mininal proceeds required for the sale

/// @audit Mininal
143:      /// @param minAmountOut Mininal collateral amount to receive

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L93

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

/// @audit necessar
375:      /// @param swapData Swap necessar data

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L375

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

/// @audit repayed
110:      /// @notice event emitted when asset is repayed

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L110

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit repayed
295:      /// @return amount The total amount repayed.

/// @audit Mininal
318:      /// @param minAmountOut Mininal proceeds required for the sale

/// @audit Mininal
347:      /// @param minAmountOut Mininal collateral amount to receive

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L295

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit transer
183:      /// @param lzData data needed for the cross chain transer

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L183

File: tapiocaz-audit/contracts/Balancer.sol

/// @audit registeres
214:      /// @notice registeres mTapiocaOFT for rebalancing

/// @audit assings
246:      /// @notice assings more rebalanceable amount for TOFT

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L214

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit transer
124:      /// @param lzData data needed for the cross chain transer

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L124

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

/// @audit reigstered
26:       /// @notice event emitted when a connected chain is reigstered or unregistered

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L26

File: tap-token-audit/contracts/twAML.sol

/// @audit precoditions
100:          // correct result modulo 2**256. Since the precoditions guarantee

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L100

File: YieldBox/contracts/YieldBoxRebase.sol

/// @audit reseting
24:           // To prevent reseting the ratio due to withdrawal of all shares, we start with

/// @audit Calculte
31:           // Calculte the shares using te current amount to share ratio

/// @audit reseting
47:           // To prevent reseting the ratio due to withdrawal of all shares, we start with

/// @audit Calculte
54:           // Calculte the amount using te current amount to share ratio

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L24

File: YieldBox/contracts/YieldBox.sol

/// @audit repesented
117:      /// @return shareOut The deposited amount repesented in shares.

/// @audit repesented
167:      /// @return shareOut The deposited amount repesented in shares.

/// @audit repesented
195:      /// @return shareOut The deposited amount repesented in shares.

/// @audit regierestered
421:      /// @param assetId The regierestered asset id

/// @audit repesented
476:      /// @return shareOut The deposited amount repesented in shares.

/// @audit repesented
499:      /// @return shareOut The deposited amount repesented in shares.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L117

[N‑42] NatSpec @param is missing

There are 329 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit Missing: '@param data'
100       /// @notice The init function that acts as a constructor
101:      function init(bytes calldata data) external onlyOnce {

/// @audit Missing: '@param operator'
225       /// @notice allows 'operator' to act on behalf of the sender
226       /// @param status true/false
227:      function updateOperator(address operator, bool status) external {

/// @audit Missing: '@param bool'
257       /// @notice Repays a loan.
258       /// @dev The bool param is not used but we added it to respect the ISingularity interface for MarketsHelper compatibility
259       /// @param from Address to repay from.
260       /// @param to Address of the user this payment should go.
261       /// @param part The amount to repay. See `userBorrowPart`.
262       /// @return amount The total amount repayed.
263       function repay(
264           address from,
265           address to,
266           bool,
267           uint256 part
268:      ) public notPaused allowedBorrow(from, part) returns (uint256 amount) {

/// @audit Missing: '@param amount'
276       /// @notice Adds `collateral` from msg.sender to the account `to`.
277       /// @param from Account to transfer shares from.
278       /// @param to The receiver of the tokens.
279       /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
280       /// False if tokens from msg.sender in `yieldBox` should be transferred.
281       /// @param share The amount of shares to add for `to`.
282       function addCollateral(
283           address from,
284           address to,
285           bool skim,
286           uint256 amount,
287           uint256 share
288:      ) public allowedBorrow(from, share) notPaused {

/// @audit Missing: '@param address'
441       /// @notice Transfers fees to penrose
442       function refreshPenroseFees(
443           address
444:      ) external onlyOwner notPaused returns (uint256 feeShares) {

/// @audit Missing: '@param _minDebtRate'
/// @audit Missing: '@param _maxDebtRate'
/// @audit Missing: '@param _debtRateAgainstEthMarket'
/// @audit Missing: '@param _liquidationMultiplier'
464       /// @notice sets BigBang specific configuration
465       /// @dev values are updated only if > 0 or not address(0)
466       function setBigBangConfig(
467           uint256 _minDebtRate,
468           uint256 _maxDebtRate,
469           uint256 _debtRateAgainstEthMarket,
470           uint256 _liquidationMultiplier
471:      ) external onlyOwner {

/// @audit Missing: '@param _exchangeRate'
652       /// @notice Handles the liquidation of users' balances, once the users' amount of collateral is too low.
653       /// @dev Closed liquidations Only, 90% of extra shares goes to caller and 10% to protocol
654       /// @param users An array of user addresses.
655       /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.
656       /// @param swapper Contract address of the `MultiSwapper` implementation. See `setSwapper`.
657       /// @param swapData Swap necessar data
658       function _closedLiquidation(
659           address[] calldata users,
660           uint256[] calldata maxBorrowParts,
661           ISwapper swapper,
662           uint256 _exchangeRate,
663:          bytes calldata swapData

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param share'
708       /// @dev Concrete implementation of `removeCollateral`.
709       function _removeCollateral(
710           address from,
711           address to,
712:          uint256 share

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param part'
720       /// @dev Concrete implementation of `repay`.
721       function _repay(
722           address from,
723           address to,
724           uint256 part
725:      ) internal returns (uint256 amount) {

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
741       /// @dev Concrete implementation of `borrow`.
742       function _borrow(
743           address from,
744           address to,
745           uint256 amount
746:      ) internal returns (uint256 part, uint256 share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L100-L101

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit Missing: '@param from'
/// @audit Missing: '@param share'
72        // ***************** //
73        // *** MODIFIERS *** //
74        // ***************** //
75:       function _allowedLend(address from, uint share) internal {

/// @audit Missing: '@param name'
104       /**
105        * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
106        *
107        * It's a good idea to use the same `name` that is defined as the ERC20 token name.
108        */
109:      constructor(string memory name) EIP712(name, "1") {}

/// @audit Missing: '@param owner'
/// @audit Missing: '@param spender'
/// @audit Missing: '@param value'
/// @audit Missing: '@param deadline'
/// @audit Missing: '@param v'
/// @audit Missing: '@param r'
/// @audit Missing: '@param s'
209       /**
210        * @dev See {IERC20Permit-permit}.
211        */
212       function permit(
213           address owner,
214           address spender,
215           uint256 value,
216           uint256 deadline,
217           uint8 v,
218           bytes32 r,
219:          bytes32 s

/// @audit Missing: '@param owner'
240       /**
241        * @dev "Consume a nonce": return the current value and increment.
242        *
243        * _Available since v4.1._
244        */
245       function _useNonce(
246           address owner
247:      ) internal virtual returns (uint256 current) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L72-L75

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit Missing: '@param _borrowOpeningFee'
/// @audit Missing: '@param _oracle'
/// @audit Missing: '@param _oracleData'
/// @audit Missing: '@param _conservator'
/// @audit Missing: '@param _callerFee'
/// @audit Missing: '@param _protocolFee'
/// @audit Missing: '@param _liquidationBonusAmount'
/// @audit Missing: '@param _minLiquidatorReward'
/// @audit Missing: '@param _maxLiquidatorReward'
/// @audit Missing: '@param _totalBorrowCap'
/// @audit Missing: '@param _collateralizationRate'
156       /// @notice sets common market configuration
157       /// @dev values are updated only if > 0 or not address(0)
158       function setMarketConfig(
159           uint256 _borrowOpeningFee,
160           IOracle _oracle,
161           bytes calldata _oracleData,
162           address _conservator,
163           uint256 _callerFee,
164           uint256 _protocolFee,
165           uint256 _liquidationBonusAmount,
166           uint256 _minLiquidatorReward,
167           uint256 _maxLiquidatorReward,
168           uint256 _totalBorrowCap,
169           uint256 _collateralizationRate
170:      ) external onlyOwner {

/// @audit Missing: '@param borrowPart'
/// @audit Missing: '@param collateralPartInAsset'
/// @audit Missing: '@param borrowPartDecimals'
/// @audit Missing: '@param collateralPartDecimals'
/// @audit Missing: '@param ratesPrecision'
252       // ********************** //
253       // *** VIEW FUNCTIONS *** //
254       // ********************** //
255       /// @notice returns the maximum liquidatable amount for user
256       function computeClosingFactor(
257           uint256 borrowPart,
258           uint256 collateralPartInAsset,
259           uint256 borrowPartDecimals,
260           uint256 collateralPartDecimals,
261           uint256 ratesPrecision
262:      ) public view returns (uint256) {

/// @audit Missing: '@param user'
353       /// @notice computes the possible liquidator reward
354       /// @notice user the user for which a liquidation operation should be performed
355       /// @param _exchangeRate the exchange rate asset/collateral to use for internal computations
356       function computeLiquidatorReward(
357           address user,
358           uint256 _exchangeRate
359:      ) public view returns (uint256) {

/// @audit Missing: '@param user'
400       /// @notice Concrete implementation of `isSolvent`. Includes a parameter to allow caching `exchangeRate`.
401       /// @param _exchangeRate The exchange rate. Used to cache the `exchangeRate` between calls.
402       function _isSolvent(
403           address user,
404           uint256 _exchangeRate
405:      ) internal view returns (bool) {

/// @audit Missing: '@param collateralShare'
/// @audit Missing: '@param _exchangeRate'
427       /// @notice Returns the min and max LTV for user in asset price
428       function _computeMaxAndMinLTVInAsset(
429           uint256 collateralShare,
430           uint256 _exchangeRate
431:      ) internal view returns (uint256 min, uint256 max) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L156-L170

File: tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol

/// @audit Missing: '@param amount'
12        // ************************ //
13        // *** PUBLIC FUNCTIONS *** //
14        // ************************ //
15        /// @notice Adds `collateral` from msg.sender to the account `to`.
16        /// @param from Account to transfer shares from.
17        /// @param to The receiver of the tokens.
18        /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
19        /// False if tokens from msg.sender in `yieldBox` should be transferred.
20        /// @param share The amount of shares to add for `to`.
21        function addCollateral(
22            address from,
23            address to,
24            bool skim,
25            uint256 amount,
26            uint256 share
27:       ) public notPaused allowedBorrow(from, share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L12-L27

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param skim'
/// @audit Missing: '@param share'
196       /// @dev Concrete implementation of `addAsset`.
197       function _addAsset(
198           address from,
199           address to,
200           bool skim,
201           uint256 share
202:      ) internal returns (uint256 fraction) {

/// @audit Missing: '@param to'
/// @audit Missing: '@param fraction'
/// @audit Missing: '@param updateYieldBoxShares'
221       /// @dev Concrete implementation of `removeAsset`.
222       /// @param from The account to remove from. Should always be msg.sender except for `depositFeesToyieldBox()`.
223       function _removeAsset(
224           address from,
225           address to,
226           uint256 fraction,
227           bool updateYieldBoxShares
228:      ) internal returns (uint256 share) {

/// @audit Missing: '@param borrowPart'
253       /// @dev Return the equivalent of collateral borrow part in asset amount.
254       function _getAmountForBorrowPart(
255           uint256 borrowPart
256:      ) internal view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L196-L202

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param skim'
/// @audit Missing: '@param amount'
/// @audit Missing: '@param share'
12        // ************************** //
13        // *** PRIVATE FUNCTIONS *** //
14        // ************************* //
15        /// @dev Concrete implementation of `addCollateral`.
16        function _addCollateral(
17            address from,
18            address to,
19            bool skim,
20            uint256 amount,
21:           uint256 share

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param share'
40        /// @dev Concrete implementation of `removeCollateral`.
41        function _removeCollateral(
42            address from,
43            address to,
44:           uint256 share

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
57        /// @dev Concrete implementation of `borrow`.
58        function _borrow(
59            address from,
60            address to,
61            uint256 amount
62:       ) internal returns (uint256 part, uint256 share) {

/// @audit Missing: '@param from'
/// @audit Missing: '@param to'
/// @audit Missing: '@param skim'
/// @audit Missing: '@param part'
82        /// @dev Concrete implementation of `repay`.
83        function _repay(
84            address from,
85            address to,
86            bool skim,
87            uint256 part
88:       ) internal returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L12-L21

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

/// @audit Missing: '@param user'
/// @audit Missing: '@param _exchangeRate'
67        // ************************* //
68        // *** PRIVATE FUNCTIONS *** //
69        // ************************* //
70        function _computeAssetAmountToSolvency(
71            address user,
72            uint256 _exchangeRate
73:       ) private view returns (uint256) {

/// @audit Missing: '@param _exchangeRate'
370       /// @notice Handles the liquidation of users' balances, once the users' amount of collateral is too low.
371       /// @dev Closed liquidations Only, 90% of extra shares goes to caller and 10% to protocol
372       /// @param users An array of user addresses.
373       /// @param maxBorrowParts A one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user.
374       /// @param swapper Contract address of the `MultiSwapper` implementation. See `setSwapper`.
375       /// @param swapData Swap necessar data
376       function _closedLiquidation(
377           address[] calldata users,
378           uint256[] calldata maxBorrowParts,
379           ISwapper swapper,
380           uint256 _exchangeRate,
381:          bytes calldata swapData

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L67-L73

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit Missing: '@param data'
61        /// @notice The init function that acts as a constructor
62:       function init(bytes calldata data) external onlyOnce {

/// @audit Missing: '@param amount'
229       /// @notice Adds `collateral` from msg.sender to the account `to`.
230       /// @param from Account to transfer shares from.
231       /// @param to The receiver of the tokens.
232       /// @param skim True if the amount should be skimmed from the deposit balance of msg.sender.
233       /// False if tokens from msg.sender in `yieldBox` should be transferred.
234       /// @param share The amount of shares to add for `to`.
235       function addCollateral(
236           address from,
237           address to,
238           bool skim,
239           uint256 amount,
240:          uint256 share

/// @audit Missing: '@param _lqCollateralizationRate'
/// @audit Missing: '@param _liquidationMultiplier'
/// @audit Missing: '@param _minimumTargetUtilization'
/// @audit Missing: '@param _maximumTargetUtilization'
/// @audit Missing: '@param _minimumInterestPerSecond'
/// @audit Missing: '@param _maximumInterestPerSecond'
/// @audit Missing: '@param _interestElasticity'
487       /// @notice sets Singularity specific configuration
488       /// @dev values are updated only if > 0 or not address(0)
489       function setSingularityConfig(
490           uint256 _lqCollateralizationRate,
491           uint256 _liquidationMultiplier,
492           uint256 _minimumTargetUtilization,
493           uint256 _maximumTargetUtilization,
494           uint64 _minimumInterestPerSecond,
495           uint64 _maximumInterestPerSecond,
496           uint256 _interestElasticity
497:      ) external onlyOwner {

/// @audit Missing: '@param _liquidationQueue'
/// @audit Missing: '@param _bidExecutionSwapper'
/// @audit Missing: '@param _usdoSwapper'
575       /// @notice sets LQ specific confinguration
576       function setLiquidationQueueConfig(
577           ILiquidationQueue _liquidationQueue,
578           address _bidExecutionSwapper,
579           address _usdoSwapper
580:      ) external onlyOwner {

/// @audit Missing: '@param _module'
597       // ************************* //
598       // *** PRIVATE FUNCTIONS *** //
599       // ************************* //
600:      function _extractModule(Module _module) private view returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L61-L62

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit Missing: '@param _market'
261       /// @notice sets the main BigBang market
262       /// @dev needed for the variable debt computation
263:      function setBigBangEthMarket(address _market) external onlyOwner {

/// @audit Missing: '@param _contract'
378       /// @notice Registers an existing Singularity market (without deployment)
379       /// @dev can only be called by the owner
380       /// @param mc The address of the master contract which must be already registered
381       function addSingularity(
382           address mc,
383           address _contract
384:      ) external onlyOwner registeredSingularityMasterContract(mc) {

/// @audit Missing: '@param _contract'
411       /// @notice Registers an existing BigBang market (without deployment)
412       /// @dev can only be called by the owner
413       /// @param mc The address of the master contract which must be already registered
414       function addBigBang(
415           address mc,
416           address _contract
417:      ) external onlyOwner registeredBigBangMasterContract(mc) {

/// @audit Missing: '@param mc'
/// @audit Missing: '@param data'
/// @audit Missing: '@param forceSuccess'
423       /// @notice Execute an only owner function inside of a Singularity or a BigBang market
424       function executeMarketFn(
425           address[] calldata mc,
426           bytes[] memory data,
427           bool forceSuccess
428       )
429           external
430           onlyOwner
431           notPaused
432:          returns (bool[] memory success, bytes[] memory result)

/// @audit Missing: '@param _returnData'
469       // ************************* //
470       // *** PRIVATE FUNCTIONS *** //
471       // ************************* //
472       function _getRevertMsg(
473           bytes memory _returnData
474:      ) private pure returns (string memory) {

/// @audit Missing: '@param market'
/// @audit Missing: '@param swapper'
/// @audit Missing: '@param dexData'
499       /// @notice Withdraw the balance of `feeTo`, swap asset into TAP and deposit it to yieldBox of `feeTo`
500       function _depositFeesToYieldBox(
501           IMarket market,
502           ISwapper swapper,
503:          IPenrose.SwapData calldata dexData

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L261-L263

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit Missing: '@param airdropAdapterParams'
207       /// @notice inits multiHopBuyCollateral
208       /// @param from The user who sells
209       /// @param collateralAmount Extra collateral to be added
210       /// @param borrowAmount Borrowed amount that will be swapped into collateral
211       /// @param swapData Swap data used on destination chain for swapping USDO to the underlying TOFT token
212       /// @param lzData LayerZero specific data
213       /// @param externalData External contracts used for the cross chain operation
214       /// @param approvals array
215       function initMultiHopBuy(
216           address from,
217           uint256 collateralAmount,
218           uint256 borrowAmount,
219           IUSDOBase.ILeverageSwapData calldata swapData,
220           IUSDOBase.ILeverageLZData calldata lzData,
221           IUSDOBase.ILeverageExternalContractsData calldata externalData,
222           bytes calldata airdropAdapterParams,
223:          ICommonData.IApproval[] memory approvals

/// @audit Missing: '@param zroPaymentAddress'
305       /// @notice sends to YieldBox over layer and lends asset to market
306       /// @param _from sending address
307       /// @param _to receiver address
308       /// @param lzDstChainId LayerZero destination chain id
309       /// @param lendParams lend specific params
310       /// @param approvals approvals specific params
311       /// @param withdrawParams parameter to withdraw the SGL collateral
312       /// @param adapterParams adapter params of the withdrawn collateral
313       function sendAndLendOrRepay(
314           address _from,
315           address _to,
316           uint16 lzDstChainId,
317           address zroPaymentAddress,
318           IUSDOBase.ILendOrRepayParams calldata lendParams,
319           ICommonData.IApproval[] calldata approvals,
320           ICommonData.IWithdrawParams calldata withdrawParams,
321:          bytes calldata adapterParams

/// @audit Missing: '@param _module'
340       // ************************* //
341       // *** PRIVATE FUNCTIONS *** //
342       // ************************* //
343   
344:      function _extractModule(Module _module) private view returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L207-L223

File: tapioca-bar-audit/contracts/usd0/USDO.sol

/// @audit Missing: '@param _marketModule'
/// @audit Missing: '@param _optionsModule'
30        /// @notice creates a new USDO0 OFT contract
31        /// @param _lzEndpoint LayerZero endpoint
32        /// @param _yieldBox the YieldBox address
33        /// @param _owner owner address
34        /// @param _leverageModule USDOLeverageModule address
35        constructor(
36            address _lzEndpoint,
37            IYieldBoxBase _yieldBox,
38            address _owner,
39            address payable _leverageModule,
40            address payable _marketModule,
41            address payable _optionsModule
42        )
43            BaseUSDO(
44                _lzEndpoint,
45                _yieldBox,
46                _owner,
47                _leverageModule,
48                _marketModule,
49                _optionsModule
50:           )

/// @audit Missing: '@param address'
53        // ********************** //
54        // *** VIEW FUNCTIONS *** //
55        // ********************** //
56        /// @notice returns the maximum amount of tokens available for a flash mint
57:       function maxFlashLoan(address) public view override returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L30-L50

File: tapiocaz-audit/contracts/Balancer.sol

/// @audit Missing: '@param _srcOft'
/// @audit Missing: '@param _dstChainId'
133       // ************************ //
134       // *** PUBLIC FUNCTIONS *** //
135       // ************************ //
136   
137       function checker(
138           address payable _srcOft,
139           uint16 _dstChainId
140:      ) external view returns (bool canExec, bytes memory execPayload) {

/// @audit Missing: '@param _srcOft'
/// @audit Missing: '@param _dstOft'
/// @audit Missing: '@param _dstChainId'
264       // ************************* //
265       // *** PRIVATE FUNCTIONS *** //
266       // ***********************
@thebrittfactor
Copy link

Original report was truncated. Remaining contents added.

267 function _isValidOft(
268 address _srcOft,
269 address _dstOft,
270 uint16 _dstChainId
271: ) private view returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L133-L140

```solidity
File: tapiocaz-audit/contracts/TapiocaWrapper.sol

/// @audit Missing: '@param _linked'
150       /// @notice Deploy a new TOFT contract. Callable only by the owner.
151       /// @param _erc20 The ERC20 to wrap.
152       /// @param _bytecode The executable bytecode of the TOFT contract.
153       /// @param _salt Create2 salt.
154       function createTOFT(
155           address _erc20,
156           bytes calldata _bytecode,
157           bytes32 _salt,
158           bool _linked
159:      ) external onlyOwner {

/// @audit Missing: '@param _erc20'
/// @audit Missing: '@param _bytecode'
/// @audit Missing: '@param _salt'
/// @audit Missing: '@param _linked'
180       // ************************* //
181       // *** PRIVATE FUNCTIONS *** //
182       // ************************* //
183       function _createTOFT(
184           address _erc20,
185           bytes calldata _bytecode,
186           bytes32 _salt,
187           bool _linked
188:      ) private returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L150-L159

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit Missing: '@param share'
217       /// @notice sends TOFT to a specific strategy available on another layer
218       /// @param from the sender address
219       /// @param to the receiver address
220       /// @param amount the transferred amount
221       /// @param assetId the destination YieldBox asset id
222       /// @param lzDstChainId the destination LayerZero id
223       /// @param options the operation data
224       function sendToStrategy(
225           address from,
226           address to,
227           uint256 amount,
228           uint256 share,
229           uint256 assetId,
230           uint16 lzDstChainId,
231:          ICommonData.ISendOptions calldata options

/// @audit Missing: '@param share'
249       /// @notice extracts TOFT from a specific strategy available on another layer
250       /// @param from the sender address
251       /// @param amount the transferred amount
252       /// @param assetId the destination YieldBox asset id
253       /// @param lzDstChainId the destination LayerZero id
254       /// @param zroPaymentAddress LayerZero ZRO payment address
255       /// @param airdropAdapterParam the LayerZero aidrop adapter params
256       function retrieveFromStrategy(
257           address from,
258           uint256 amount,
259           uint256 share,
260           uint256 assetId,
261           uint16 lzDstChainId,
262           address zroPaymentAddress,
263:          bytes memory airdropAdapterParam

/// @audit Missing: '@param _fromAddress'
/// @audit Missing: '@param _toAddress'
/// @audit Missing: '@param _amount'
347       //---internal-
348       function _wrap(
349           address _fromAddress,
350           address _toAddress,
351:          uint256 _amount

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
378       //---private---
379:      function _safeTransferETH(address to, uint256 amount) internal {

/// @audit Missing: '@param _srcChainId'
/// @audit Missing: '@param _srcAddress'
/// @audit Missing: '@param _nonce'
/// @audit Missing: '@param _payload'
441       //---LZ---
442       function _nonblockingLzReceive(
443           uint16 _srcChainId,
444           bytes memory _srcAddress,
445           uint64 _nonce,
446:          bytes memory _payload

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L217-L231

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

/// @audit Missing: '@param _payload'
110       //---Destination calls---
111:      function multiHop(bytes memory _payload) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L110-L111

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

/// @audit Missing: '@param share'
40        /// @notice sends TOFT to a specific strategy available on another layer
41        /// @param _from the sender address
42        /// @param _to the receiver address
43        /// @param amount the transferred amount
44        /// @param assetId the destination YieldBox asset id
45        /// @param lzDstChainId the destination LayerZero id
46        /// @param options the operation data
47        function sendToStrategy(
48            address _from,
49            address _to,
50            uint256 amount,
51            uint256 share,
52            uint256 assetId,
53            uint16 lzDstChainId,
54:           ICommonData.ISendOptions calldata options

/// @audit Missing: '@param share'
82        /// @notice extracts TOFT from a specific strategy available on another layer
83        /// @param _from the sender address
84        /// @param amount the transferred amount
85        /// @param assetId the destination YieldBox asset id
86        /// @param lzDstChainId the destination LayerZero id
87        /// @param zroPaymentAddress LayerZero ZRO payment address
88        /// @param airdropAdapterParam the LayerZero aidrop adapter params
89        function retrieveFromStrategy(
90            address _from,
91            uint256 amount,
92            uint256 share,
93            uint256 assetId,
94            uint16 lzDstChainId,
95            address zroPaymentAddress,
96:           bytes memory airdropAdapterParam

/// @audit Missing: '@param _assetId'
/// @audit Missing: '@param _amount'
/// @audit Missing: '@param _share'
/// @audit Missing: '@param _from'
/// @audit Missing: '@param _to'
239       /// @notice Receive an inter-chain transaction to execute a deposit inside YieldBox.
240       function _retrieveFromYieldBox(
241           uint256 _assetId,
242           uint256 _amount,
243           uint256 _share,
244           address _from,
245:          address _to

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L40-L54

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

/// @audit Missing: '@param _leverageModule'
/// @audit Missing: '@param _strategyModule'
/// @audit Missing: '@param _marketModule'
/// @audit Missing: '@param _optionsModule'
41        /// @notice creates a new mTapiocaOFT
42        /// @param _lzEndpoint LayerZero endpoint address
43        /// @param _erc20 true the underlying ERC20 address
44        /// @param _yieldBox the YieldBox address
45        /// @param _name the TOFT name
46        /// @param _symbol the TOFT symbol
47        /// @param _decimal the TOFT decimal
48        /// @param _hostChainID the TOFT host chain LayerZero id
49        constructor(
50            address _lzEndpoint,
51            address _erc20,
52            IYieldBoxBase _yieldBox,
53            string memory _name,
54            string memory _symbol,
55            uint8 _decimal,
56            uint256 _hostChainID,
57            address payable _leverageModule,
58            address payable _strategyModule,
59            address payable _marketModule,
60            address payable _optionsModule
61        )
62            BaseTOFT(
63                _lzEndpoint,
64                _erc20,
65                _yieldBox,
66                _name,
67                _symbol,
68                _decimal,
69                _hostChainID,
70                _leverageModule,
71                _strategyModule,
72                _marketModule,
73                _optionsModule
74:           )

/// @audit Missing: '@param _fromAddress'
81        // ************************ //
82        // *** PUBLIC FUNCTIONS *** //
83        // ************************ //
84        /// @notice Wrap an ERC20 with a 1:1 ratio with a fee if existing.
85        /// @dev Since it can be executed only on the main chain, if an address exists on the OP chain it will not allowed to wrap.
86        /// @param _toAddress The address to wrap the ERC20 to.
87        /// @param _amount The amount of ERC20 to wrap.
88        function wrap(
89            address _fromAddress,
90            address _toAddress,
91            uint256 _amount
92:       ) external payable onlyHostChain {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L41-L74

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

/// @audit Missing: '@param _leverageModule'
/// @audit Missing: '@param _strategyModule'
/// @audit Missing: '@param _marketModule'
/// @audit Missing: '@param _optionsModule'
25        /// @notice creates a new TapiocaOFT
26        /// @param _lzEndpoint LayerZero endpoint address
27        /// @param _erc20 true the underlying ERC20 address
28        /// @param _yieldBox the YieldBox address
29        /// @param _name the TOFT name
30        /// @param _symbol the TOFT symbol
31        /// @param _decimal the TOFT decimal
32        /// @param _hostChainID the TOFT host chain LayerZero id
33        constructor(
34            address _lzEndpoint,
35            address _erc20,
36            IYieldBoxBase _yieldBox,
37            string memory _name,
38            string memory _symbol,
39            uint8 _decimal,
40            uint256 _hostChainID,
41            address payable _leverageModule,
42            address payable _strategyModule,
43            address payable _marketModule,
44            address payable _optionsModule
45        )
46            BaseTOFT(
47                _lzEndpoint,
48                _erc20,
49                _yieldBox,
50                _name,
51                _symbol,
52                _decimal,
53                _hostChainID,
54                _leverageModule,
55                _strategyModule,
56                _marketModule,
57                _optionsModule
58:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L25-L58

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit Missing: '@param _tapOFT'
/// @audit Missing: '@param _owner'
/// @audit Missing: '@param _layerZeroEndpoint'
/// @audit Missing: '@param _hostChainID'
/// @audit Missing: '@param _minGas'
114       /// =====-------======
115       constructor(
116           address payable _tapOFT,
117           address _owner,
118           address _layerZeroEndpoint,
119           uint256 _hostChainID,
120           uint256 _minGas
121       )
122           ONFT721("Time Weighted TAP", "twTAP", _minGas, _layerZeroEndpoint)
123:          ERC721Permit("Time Weighted TAP")

/// @audit Missing: '@param _tokenId'
154       /// @notice Return the participation of a token. Returns 0 votes for expired tokens.
155       function getParticipation(
156           uint _tokenId
157:      ) public view returns (Participation memory participant) {

/// @audit Missing: '@param _tokenId'
165       /// @notice Amount currently claimable for each reward token
166       function claimable(
167           uint256 _tokenId
168:      ) public view returns (uint256[] memory) {

/// @audit Missing: '@param token'
451       // =========
452       //   OWNER
453       // =========
454   
455:      function addRewardToken(IERC20 token) external onlyOwner returns (uint256) {

/// @audit Missing: '@param _to'
/// @audit Missing: '@param _tokenId'
466       /// @dev Mirrors the implementation of _isApprovedOrOwner, with the modification
467       /// that it is allowed if `_to` is the owner:
468       function _requireClaimPermission(
469           address _to,
470:          uint256 _tokenId

/// @audit Missing: '@param _tokenId'
/// @audit Missing: '@param _to'
482       /// @dev Claim all rewards on a position and send them to `_to`.
483:      function _claimRewards(uint256 _tokenId, address _to) internal {

/// @audit Missing: '@param _tokenId'
/// @audit Missing: '@param _to'
/// @audit Missing: '@param _rewardTokens'
498       /// @dev Claim rewards of a specific token on a position and send them to `_to`.
499       function _claimRewardsOn(
500           uint256 _tokenId,
501           address _to,
502:          IERC20[] memory _rewardTokens

/// @audit Missing: '@param _tokenId'
/// @audit Missing: '@param _to'
521       /// @dev Release the tap of a position and send it to `_to`. Remove the user from twAML.
522       function _releaseTap(
523           uint256 _tokenId,
524           address _to
525:      ) internal returns (uint256 releasedAmount) {

/// @audit Missing: '@param interfaceId'
579       /**
580        * @dev See {IERC165-supportsInterface}.
581        */
582       function supportsInterface(
583           bytes4 interfaceId
584:      ) public view virtual override(ONFT721, ERC721) returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L114-L123

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit Missing: '@param _aoTAP'
/// @audit Missing: '@param _tapOFT'
/// @audit Missing: '@param _pcnft'
/// @audit Missing: '@param _paymentTokenBeneficiary'
/// @audit Missing: '@param _owner'
97        /// =====-------======
98        constructor(
99            address _aoTAP,
100           address payable _tapOFT,
101           address _pcnft,
102           address _paymentTokenBeneficiary,
103:          address _owner

/// @audit Missing: '@param _paymentToken'
/// @audit Missing: '@param _oracle'
/// @audit Missing: '@param _oracleData'
342       /// @notice Activate or deactivate a payment token
343       /// @dev set the oracle to address(0) to deactivate, expect the same decimal precision as TAP oracle
344       function setPaymentToken(
345           ERC20 _paymentToken,
346           IOracle _oracle,
347           bytes calldata _oracleData
348:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L97-L103

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

/// @audit Missing: '@param _owner'
36        mapping(uint256 => AirdropTapOption) public options; // tokenId => Option
37        mapping(uint256 => string) public tokenURIs; // tokenId => tokenURI
38    
39        constructor(
40            address _owner
41:       ) ERC721("Airdrop Option TAP", "aoTAP") ERC721Permit("Airdrop Option TAP") {

/// @audit Missing: '@param _tokenId'
64        // =========
65        //    READ
66        // =========
67    
68        function tokenURI(
69            uint256 _tokenId
70:       ) public view override returns (string memory) {

/// @audit Missing: '@param _tokenId'
81        /// @notice Return the owner of the tokenId and the attributes of the option.
82        function attributes(
83            uint256 _tokenId
84:       ) external view returns (address, AirdropTapOption memory) {

/// @audit Missing: '@param _tokenId'
88        /// @notice Check if a token exists
89:       function exists(uint256 _tokenId) external view returns (bool) {

/// @audit Missing: '@param _tokenId'
/// @audit Missing: '@param _tokenURI'
93        // ==========
94        //    WRITE
95        // ==========
96    
97:       function setTokenURI(uint256 _tokenId, string calldata _tokenURI) external {

/// @audit Missing: '@param _amount'
105       /// @notice mints an AOTAP
106       /// @param _to address to mint to
107       /// @param _expiry timestamp
108       /// @param _discount TAP discount in basis points
109       function mint(
110           address _to,
111           uint128 _expiry,
112           uint128 _discount,
113           uint256 _amount
114:      ) external onlyBroker returns (uint256 tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L36-L41

File: tap-token-audit/contracts/options/oTAP.sol

/// @audit Missing: '@param _tokenId'
50        // =========
51        //    READ
52        // =========
53    
54        function tokenURI(
55            uint256 _tokenId
56:       ) public view override returns (string memory) {

/// @audit Missing: '@param _tokenId'
67        /// @notice Return the owner of the tokenId and the attributes of the option.
68        function attributes(
69            uint256 _tokenId
70:       ) external view returns (address, TapOption memory) {

/// @audit Missing: '@param _tokenId'
74        /// @notice Check if a token exists
75:       function exists(uint256 _tokenId) external view returns (bool) {

/// @audit Missing: '@param _tokenId'
/// @audit Missing: '@param _tokenURI'
79        // ==========
80        //    WRITE
81        // ==========
82    
83:       function setTokenURI(uint256 _tokenId, string calldata _tokenURI) external {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L50-L56

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit Missing: '@param _tOLP'
/// @audit Missing: '@param _oTAP'
/// @audit Missing: '@param _tapOFT'
/// @audit Missing: '@param _paymentTokenBeneficiary'
/// @audit Missing: '@param _epochDuration'
/// @audit Missing: '@param _owner'
80        /// =====-------======
81        constructor(
82            address _tOLP,
83            address _oTAP,
84            address payable _tapOFT,
85            address _paymentTokenBeneficiary,
86            uint256 _epochDuration,
87:           address _owner

/// @audit Missing: '@param _paymentToken'
/// @audit Missing: '@param _oracle'
/// @audit Missing: '@param _oracleData'
456       /// @notice Activate or deactivate a payment token
457       /// @dev set the oracle to address(0) to deactivate, expect the same decimal precision as TAP oracle
458       function setPaymentToken(
459           ERC20 _paymentToken,
460           IOracle _oracle,
461           bytes calldata _oracleData
462:      ) external onlyOwner {

/// @audit Missing: '@param _epochTAP'
558       /// @notice Emit TAP to the gauges equitably
559:      function _emitToGauges(uint256 _epochTAP) internal {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L80-L87

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit Missing: '@param _yieldBox'
/// @audit Missing: '@param _owner'
65        uint256 public totalSingularityPoolWeights; // Total weight of all active singularity pools
66    
67        constructor(
68            address _yieldBox,
69            address _owner
70        )
71            ERC721("TapiocaOptionLiquidityProvision", "tOLP")
72:           ERC721Permit("TapiocaOptionLiquidityProvision")

/// @audit Missing: '@param _sglAssetId'
145       /// @notice Returns the total amount of locked tokens for a given singularity market
146       function getTotalPoolDeposited(
147           uint256 _sglAssetId
148:      ) external view returns (uint256) {

/// @audit Missing: '@param tokenId'
347       /// @notice Checks if the lock position is still active
348:      function _isPositionActive(uint256 tokenId) internal view returns (bool) {

/// @audit Missing: '@param address'
/// @audit Missing: '@param uint256'
/// @audit Missing: '@param bytes'
356       /// @notice ERC1155 compliance
357       function onERC1155Received(
358           address,
359           address,
360           uint256,
361           uint256,
362           bytes calldata
363:      ) external pure returns (bytes4) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L65-L72

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

/// @audit Missing: '@param _srcChainId'
/// @audit Missing: '@param _srcAddress'
/// @audit Missing: '@param _nonce'
/// @audit Missing: '@param _payload'
51        //---LZ---
52        function _nonblockingLzReceive(
53            uint16 _srcChainId,
54            bytes memory _srcAddress,
55            uint64 _nonce,
56:           bytes memory _payload

/// @audit Missing: '@param duration'
82        /// @notice Opens a twTAP by participating in twAML.
83        /// @param to The address to add the twTAP position to.
84        /// @param amount The amount to add.
85        /// @param lzDstChainId The destination chain id.
86        /// @param zroPaymentAddress The address to send the ZRO payment to.
87        /// @param adapterParams The adapter params.
88        function lockTwTapPosition(
89            address to,
90            uint256 amount, // Amount to add
91            uint256 duration, // Duration of the position.
92            uint16 lzDstChainId,
93            address zroPaymentAddress,
94:           bytes calldata adapterParams

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L51-L56

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit Missing: '@param timestamp'
172       /// @notice Returns the current week given a timestamp
173       function timestampToWeek(
174           uint256 timestamp
175:      ) external view returns (uint256) {

/// @audit Missing: '@param timestamp'
238       ///-- Internal methods --
239       function _timestampToWeek(
240           uint256 timestamp
241:      ) internal view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L172-L175

File: tap-token-audit/contracts/twAML.sol

/// @audit Missing: '@param a'
/// @audit Missing: '@param b'
/// @audit Missing: '@param denominator'
5         // https://xn--2-umb.com/21/muldiv/
6         function muldiv(
7             uint256 a,
8             uint256 b,
9             uint256 denominator
10:       ) internal pure returns (uint256 result) {

/// @audit Missing: '@param y'
146       // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
147:      function sqrt(uint256 y) internal pure returns (uint256 z) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L5-L10

File: tap-token-audit/contracts/Vesting.sol

/// @audit Missing: '@param _owner'
64        /// @notice creates a new Vesting contract
65        /// @param _cliff cliff period
66        /// @param _duration vesting period
67:       constructor(uint256 _cliff, uint256 _duration, address _owner) {

/// @audit Missing: '@param _token'
148       /// @notice inits the contract with total amount
149       /// @dev sets the start time to block.timestamp
150       /// @param _seededAmount total vested amount
151:      function init(IERC20 _token, uint256 _seededAmount) external onlyOwner {

/// @audit Missing: '@param _total'
164       // ************************* //
165       // *** PRIVATE FUNCTIONS *** //
166       // ************************* //
167:      function _vested(uint256 _total) private view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L64-L67

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit Missing: '@param liquidationMultiplierPrecision'
/// @audit Missing: '@param exchangeRatePrecision'
84        /// @notice Calculate the collateral shares that are needed for `borrowPart`,
85        /// taking the current exchange rate into account.
86        /// @param market the Singularity or BigBang address
87        /// @param borrowPart The borrow part.
88        /// @return collateralShares The collateral shares.
89        function getCollateralSharesForBorrowPart(
90            IMarket market,
91            uint256 borrowPart,
92            uint256 liquidationMultiplierPrecision,
93            uint256 exchangeRatePrecision
94:       ) public view returns (uint256 collateralShares) {

/// @audit Missing: '@param user'
/// @audit Missing: '@param externalData'
/// @audit Missing: '@param removeAndRepayData'
880       /// @notice helper to exit from  tOB, unlock from tOLP, remove from SGL, repay on BB, remove collateral from BB and withdraw
881       /// @dev all steps are optional:
882       ///         - if `removeAndRepayData.exitData.exit` is false, the exit operation is skipped
883       ///         - if `removeAndRepayData.unlockData.unlock` is false, the unlock operation is skipped
884       ///         - if `removeAndRepayData.removeAssetFromSGL` is false, the removeAsset operation is skipped
885       ///         - if `!removeAndRepayData.assetWithdrawData.withdraw && removeAndRepayData.repayAssetOnBB`, the repay operation is performed
886       ///         - if `removeAndRepayData.removeCollateralFromBB` is false, the rmeove collateral is skipped
887       ///     - the helper can either stop at the remove asset from SGL step or it can continue until is removes & withdraws collateral from BB
888       ///         - removed asset can be withdrawn by providing `removeAndRepayData.assetWithdrawData`
889       ///     - BB collateral can be removed by providing `removeAndRepayData.collateralWithdrawData`
890       function exitPositionAndRemoveCollateral(
891           address user,
892           ICommonData.ICommonExternalContracts calldata externalData,
893:          IUSDOBase.IRemoveAndRepay calldata removeAndRepayData

/// @audit Missing: '@param who'
/// @audit Missing: '@param market'
906       // ********************** //
907       // *** PRIVATE METHODS *** //
908       // *********************** //
909       function _commonInfo(
910           address who,
911           IMarket market
912:      ) private view returns (MarketInfo memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L84-L94

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

/// @audit Missing: '@param _from'
333       // ************************ //
334       // *** INTERNAL METHODS *** //
335       // ************************ //
336:      function _checkSender(address _from) internal view {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L333-L336

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

/// @audit Missing: '@param market'
/// @audit Missing: '@param user'
/// @audit Missing: '@param collateralAmount'
/// @audit Missing: '@param borrowAmount'
/// @audit Missing: '@param extractFromSender'
/// @audit Missing: '@param deposit'
/// @audit Missing: '@param withdrawParams'
122       // *********************** //
123       // *** PRIVATE METHODS *** //
124       // *********************** //
125       function _depositAddCollateralAndBorrowFromMarket(
126           IMarket market,
127           address user,
128           uint256 collateralAmount,
129           uint256 borrowAmount,
130           bool extractFromSender,
131           bool deposit,
132:          ICommonData.IWithdrawParams calldata withdrawParams

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L122-L132

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit Missing: '@param __name'
/// @audit Missing: '@param __symbol'
/// @audit Missing: '@param pool'
/// @audit Missing: '@param btcFeed'
/// @audit Missing: '@param ethFeed'
/// @audit Missing: '@param usdtFeed'
/// @audit Missing: '@param wbtcFeed'
42        uint256 public constant DISCOUNT0 = 1_087_460_000_000_000; // 0.00108..
43    
44        constructor(
45            string memory __name,
46            string memory __symbol,
47            ICurvePool pool,
48            AggregatorV2V3Interface btcFeed,
49            AggregatorV2V3Interface ethFeed,
50            AggregatorV2V3Interface usdtFeed,
51:           AggregatorV2V3Interface wbtcFeed

/// @audit Missing: '@param bytes'
66        /// @notice Get the latest exchange rate.
67        /// For example:
68        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
69        /// @return success if no valid (recent) rate is available, return false else true.
70        /// @return rate The rate of the requested asset / pair / pool.
71        function get(
72            bytes calldata
73:       ) external virtual returns (bool success, uint256 rate) {

/// @audit Missing: '@param bytes'
77        /// @notice Check the last exchange rate without any state changes.
78        /// For example:
79        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
80        /// @return success if no valid (recent) rate is available, return false else true.
81        /// @return rate The rate of the requested asset / pair / pool.
82        function peek(
83            bytes calldata
84:       ) external view virtual returns (bool success, uint256 rate) {

/// @audit Missing: '@param bytes'
88        /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek().
89        /// For example:
90        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
91        /// @return rate The rate of the requested asset / pair / pool.
92        function peekSpot(
93            bytes calldata
94:       ) external view virtual returns (uint256 rate) {

/// @audit Missing: '@param bytes'
98        /// @notice Returns a human readable (short) name about this oracle.
99        /// For example:
100       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
101       /// @return (string) A human readable symbol name about this oracle.
102:      function symbol(bytes calldata) external view returns (string memory) {

/// @audit Missing: '@param bytes'
106       /// @notice Returns a human readable name about this oracle.
107       /// For example:
108       /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
109       /// @return (string) A human readable name about this oracle.
110:      function name(bytes calldata) external view returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L42-L51

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit Missing: '@param bytes'
56        /// @notice Get the latest exchange rate.
57        /// For example:
58        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
59        /// @return success if no valid (recent) rate is available, return false else true.
60        /// @return rate The rate of the requested asset / pair / pool.
61        function get(
62            bytes calldata
63:       ) external virtual returns (bool success, uint256 rate) {

/// @audit Missing: '@param bytes'
67        /// @notice Check the last exchange rate without any state changes.
68        /// For example:
69        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
70        /// @return success if no valid (recent) rate is available, return false else true.
71        /// @return rate The rate of the requested asset / pair / pool.
72        function peek(
73            bytes calldata
74:       ) external view virtual returns (bool success, uint256 rate) {

/// @audit Missing: '@param bytes'
78        /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek().
79        /// For example:
80        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
81        /// @return rate The rate of the requested asset / pair / pool.
82        function peekSpot(
83            bytes calldata
84:       ) external view virtual returns (uint256 rate) {

/// @audit Missing: '@param bytes'
88        /// @notice Returns a human readable (short) name about this oracle.
89        /// For example:
90        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
91        /// @return (string) A human readable symbol name about this oracle.
92:       function symbol(bytes calldata) external view returns (string memory) {

/// @audit Missing: '@param bytes'
96        /// @notice Returns a human readable name about this oracle.
97        /// For example:
98        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
99        /// @return (string) A human readable name about this oracle.
100:      function name(bytes calldata) external view returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L56-L63

File: tapioca-periph-audit/contracts/oracle/Seer.sol

/// @audit Missing: '@param bytes'
47        /// @notice Get the latest exchange rate.
48        /// For example:
49        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
50        /// @return success if no valid (recent) rate is available, return false else true.
51        /// @return rate The rate of the requested asset / pair / pool.
52        function get(
53            bytes calldata
54:       ) external virtual returns (bool success, uint256 rate) {

/// @audit Missing: '@param bytes'
59        /// @notice Check the last exchange rate without any state changes.
60        /// For example:
61        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
62        /// @return success if no valid (recent) rate is available, return false else true.
63        /// @return rate The rate of the requested asset / pair / pool.
64        function peek(
65            bytes calldata
66:       ) external view virtual returns (bool success, uint256 rate) {

/// @audit Missing: '@param bytes'
71        /// @notice Check the current spot exchange rate without any state changes. For oracles like TWAP this will be different from peek().
72        /// For example:
73        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
74        /// @return rate The rate of the requested asset / pair / pool.
75        function peekSpot(
76            bytes calldata
77:       ) external view virtual returns (uint256 rate) {

/// @audit Missing: '@param bytes'
82        /// @notice Returns a human readable (short) name about this oracle.
83        /// For example:
84        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
85        /// @return (string) A human readable symbol name about this oracle.
86:       function symbol(bytes calldata) external view returns (string memory) {

/// @audit Missing: '@param bytes'
90        /// @notice Returns a human readable name about this oracle.
91        /// For example:
92        /// (string memory collateralSymbol, string memory assetSymbol, uint256 division) = abi.decode(data, (string, string, uint256));
93        /// @return (string) A human readable name about this oracle.
94:       function name(bytes calldata) external view returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L47-L54

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit Missing: '@param user-defined'
/// @audit Missing: '@param bytes'
78        /// @notice Comutes amount in for amount out
79        function getInputAmount(
80            SwapData calldata,
81            bytes calldata
82:       ) external pure returns (uint256) {

/// @audit Missing: '@param i'
/// @audit Missing: '@param j'
/// @audit Missing: '@param amountIn'
/// @audit Missing: '@param amountOutMin'
144       /// *** PRIVATE METHODS ***
145       /// ***  ***
146       function _swapTokensForTokens(
147           int128 i,
148           int128 j,
149           uint256 amountIn,
150           uint256 amountOutMin
151:      ) private returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L78-L82

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

/// @audit Missing: '@param bytes'
56        /// @notice Computes amount out for amount in
57        /// @param swapData operation data
58        function getOutputAmount(
59            SwapData calldata swapData,
60            bytes calldata
61:       ) external view override returns (uint256 amountOut) {

/// @audit Missing: '@param swapData'
/// @audit Missing: '@param bytes'
78        /// @notice Comutes amount in for amount out
79        function getInputAmount(
80            SwapData calldata swapData,
81            bytes calldata
82:       ) external view override returns (uint256 amountIn) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L56-L61

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit Missing: '@param _newFee'
59        /// *** OWNER METHODS ***
60        /// ***  ***
61:       function setPoolFee(uint24 _newFee) external onlyOwner {

/// @audit Missing: '@param bytes'
78        /// @notice Computes amount out for amount in
79        /// @param swapData operation data
80        function getOutputAmount(
81            SwapData calldata swapData,
82            bytes calldata
83:       ) external view override returns (uint256 amountOut) {

/// @audit Missing: '@param swapData'
/// @audit Missing: '@param bytes'
107       /// @notice Comutes amount in for amount out
108       function getInputAmount(
109           SwapData calldata swapData,
110           bytes calldata
111:      ) external view override returns (uint256 amountIn) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L59-L61

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

/// @audit Missing: '@param amount'
/// @audit Missing: '@param salt'
/// @audit Missing: '@param bytecode'
/// @audit Missing: '@param contractName'
8         /**
9          * @dev Deploys a contract using `CREATE2`. The address where the contract
10         * will be deployed can be known in advance via {computeAddress}.
11         *
12         * The bytecode for a contract can be obtained from Solidity with
13         * `type(contractName).creationCode`.
14         *
15         * Requirements:
16         *
17         * - `bytecode` must not be empty.
18         * - `salt` must have not been used for `bytecode` already.
19         * - the factory must have a balance of at least `amount`.
20         * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
21         */
22        function deploy(
23            uint256 amount,
24            bytes32 salt,
25            bytes memory bytecode,
26            string memory contractName
27:       ) external payable returns (address addr) {

/// @audit Missing: '@param salt'
/// @audit Missing: '@param bytecodeHash'
52        /**
53         * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
54         * `bytecodeHash` or `salt` will result in a new destination address.
55         */
56        function computeAddress(
57            bytes32 salt,
58            bytes32 bytecodeHash
59:       ) external view returns (address) {

/// @audit Missing: '@param salt'
/// @audit Missing: '@param bytecodeHash'
/// @audit Missing: '@param deployer'
63        /**
64         * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
65         * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
66         */
67        function computeAddress(
68            bytes32 salt,
69            bytes32 bytecodeHash,
70            address deployer
71:       ) public pure returns (address addr) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L8-L27

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit Missing: '@param bytes'
134       // ************************ //
135       // *** PUBLIC FUNCTIONS *** //
136       // ************************ //
137       /// @notice
138:      function compound(bytes memory) public {

/// @audit Missing: '@param amount'
232       /// @dev deposits to AAVE or queues tokens if the 'depositThreshold' has not been met yet
233       ///      - when depositing to AAVE, aToken is minted to this contract
234:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
249       /// @dev burns aToken in exchange of Token and withdraws from AAVE LendingPool
250       function _withdraw(
251           address to,
252           uint256 amount
253:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L134-L138

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit Missing: '@param bytes'
114       // ************************ //
115       // *** PUBLIC FUNCTIONS *** //
116       // ************************ //
117:      function compound(bytes memory) public {}

/// @audit Missing: '@param amount'
136       /// @dev deposits to Balancer or queues tokens if the 'depositThreshold' has not been met yet
137       ///      - when depositing to Balancer, cToken is minted to this contract
138:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
190       /// @dev burns yToken in exchange of Token and withdraws from Yearn Vault
191       function _withdraw(
192           address to,
193           uint256 amount
194:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L114-L117

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit Missing: '@param bytes'
94        // ************************ //
95        // *** PUBLIC FUNCTIONS *** //
96        // ************************ //
97:       function compound(bytes memory) public {}

/// @audit Missing: '@param amount'
121       /// @dev deposits to Compound or queues tokens if the 'depositThreshold' has not been met yet
122       ///      - when depositing to Compound, cToken is minted to this contract
123:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
135       /// @dev burns yToken in exchange of Token and withdraws from Yearn Vault
136       function _withdraw(
137           address to,
138           uint256 amount
139:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L94-L97

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit Missing: '@param data'
186       // ************************ //
187       // *** PUBLIC FUNCTIONS *** //
188       // ************************ //
189:      function compound(bytes memory data) public {

/// @audit Missing: '@param amount'
299       /// @dev deposits to Curve Tricrypto to get the LP and stakes it into Convex
300:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
319       /// @dev unstakes from Convex and withdraws from Curve
320       function _withdraw(
321           address to,
322           uint256 amount
323:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L186-L189

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit Missing: '@param bytes'
157       // ************************ //
158       // *** PUBLIC FUNCTIONS *** //
159       // ************************ //
160:      function compound(bytes memory) public {

/// @audit Missing: '@param amount'
217       /// @dev deposits to Curve Tricrypto or queues tokens if the 'depositThreshold' has not been met yet
218:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
228       /// @dev withdraws from Curve Tricrypto
229       function _withdraw(
230           address to,
231           uint256 amount
232:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L157-L160

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit Missing: '@param bytes'
148       // ************************ //
149       // *** PUBLIC FUNCTIONS *** //
150       // ************************ //
151:      function compound(bytes memory) public {

/// @audit Missing: '@param amount'
204       /// @dev deposits to Curve Tricrypto or queues tokens if the 'depositThreshold' has not been met yet
205:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
215       /// @dev withdraws from Curve Tricrypto
216       function _withdraw(
217           address to,
218           uint256 amount
219:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L148-L151

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit Missing: '@param int256'
/// @audit Missing: '@param data'
85        // (For the GMX-ETH pool)
86        function uniswapV3SwapCallback(
87            int256 /* amount0Delta */,
88            int256 /* amount1Delta */,
89:           bytes calldata data

/// @audit Missing: '@param vester'
/// @audit Missing: '@param available'
/// @audit Missing: '@param tokenAvailable'
180       /// @dev Underreports if not all vesting claims have been made.
181       function _getVestableAmount(
182           IGmxVester vester,
183           uint256 available,
184           uint256 tokenAvailable
185:      ) private view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L85-L89

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit Missing: '@param bytes'
98        // ************************ //
99        // *** PUBLIC FUNCTIONS *** //
100       // ************************ //
101:      function compound(bytes memory) public {}

/// @audit Missing: '@param amount'
127       /// @dev deposits to Lido or queues tokens if the 'depositThreshold' has not been met yet
128:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
140       /// @dev swaps StEth with Eth
141       function _withdraw(
142           address to,
143           uint256 amount
144:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L98-L101

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit Missing: '@param bytes'
156       // ************************ //
157       // *** PUBLIC FUNCTIONS *** //
158       // ************************ //
159:      function compound(bytes memory) public {

/// @audit Missing: '@param amount'
221       /// @dev deposits to Stargate or queues tokens if the 'depositThreshold' has not been met yet
222       ///      - when depositing to Stargate, aToken is minted to this contract
223:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
240       /// @dev burns stgToken in exchange of Native and withdraws from Stargate Staking & Router
241       function _withdraw(
242           address to,
243           uint256 amount
244:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L156-L159

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit Missing: '@param bytes'
95        // ************************ //
96        // *** PUBLIC FUNCTIONS *** //
97        // ************************ //
98:       function compound(bytes memory) public {}

/// @audit Missing: '@param amount'
119       /// @dev deposits to Yearn or queues tokens if the 'depositThreshold' has not been met yet
120       ///      - when depositing to Yearn, yToken is minted to this contract
121:      function _deposited(uint256 amount) internal override nonReentrant {

/// @audit Missing: '@param to'
/// @audit Missing: '@param amount'
131       /// @dev burns yToken in exchange of Token and withdraws from Yearn Vault
132       function _withdraw(
133           address to,
134           uint256 amount
135:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L95-L98

File: YieldBox/contracts/NativeTokenFactory.sol

/// @audit Missing: '@param uri'
85        /// @notice Create a new native token. This will be an ERC1155 token. If later it's needed as an ERC20 token it can
86        /// be wrapped into an ERC20 token. Native support for ERC1155 tokens is growing though.
87        /// @param name The name of the token.
88        /// @param symbol The symbol of the token.
89        /// @param decimals The number of decimals of the token (this is just for display purposes). Should be set to 18 in normal cases.
90:       function createToken(string calldata name, string calldata symbol, uint8 decimals, string calldata uri) public returns (uint32 tokenId) {

/// @audit Missing: '@param from'
113       /// @notice Burns tokens. Only the holder of tokens can burn them or an approved operator.
114       /// @param tokenId The token to be burned.
115       /// @param amount The amount of tokens to burn.
116:      function burn(uint256 tokenId, address from, uint256 amount) public allowed(from, tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L85-L90

File: YieldBox/contracts/YieldBoxPermit.sol

/// @audit Missing: '@param name'
35        /**
36         * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
37         *
38         * It's a good idea to use the same `name` that is defined as the ERC721 token name.
39         */
40:       constructor(string memory name) EIP712(name, "1") {}

/// @audit Missing: '@param owner'
98        /**
99         * @dev See {IERC20Permit-nonces}.
100        */
101:      function nonces(address owner) public view virtual returns (uint256) {

/// @audit Missing: '@param owner'
113       /**
114        * @dev "Consume a nonce": return the current value and increment.
115        *
116        */
117:      function _useNonce(address owner) internal virtual returns (uint256 current) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L35-L40

File: YieldBox/contracts/YieldBoxRebase.sol

/// @audit Missing: '@param amount'
/// @audit Missing: '@param totalShares_'
/// @audit Missing: '@param totalAmount'
/// @audit Missing: '@param roundUp'
17        /// @notice Calculates the base value in relationship to `elastic` and `total`.
18        function _toShares(
19            uint256 amount,
20            uint256 totalShares_,
21            uint256 totalAmount,
22            bool roundUp
23:       ) internal pure returns (uint256 share) {

/// @audit Missing: '@param share'
/// @audit Missing: '@param totalShares_'
/// @audit Missing: '@param totalAmount'
/// @audit Missing: '@param roundUp'
40        /// @notice Calculates the elastic value in relationship to `base` and `total`.
41        function _toAmount(
42            uint256 share,
43            uint256 totalShares_,
44            uint256 totalAmount,
45            bool roundUp
46:       ) internal pure returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L17-L23

File: YieldBox/contracts/YieldBox.sol

/// @audit Missing: '@param asset'
100       /// @dev Returns the total balance of `token` the strategy contract holds,
101       /// plus the total amount this contract thinks the strategy holds.
102:      function _tokenBalanceOf(Asset storage asset) internal view returns (uint256 amount) {

/// @audit Missing: '@param assetId'
400       // This functionality has been split off into a separate contract. This is only a view function, so gas usage isn't a huge issue.
401       // This keeps the YieldBox contract smaller, so it can be optimized more.
402:      function uri(uint256 assetId) external view override returns (string memory) {

/// @audit Missing: '@param to'
495       /// @notice Helper function to register & deposit ETH
496       /// @param strategy Asset's strategy address.
497       /// @param amount amount to deposit.
498       /// @return amountOut The amount deposited.
499       /// @return shareOut The deposited amount repesented in shares.
500:      function depositETH(IStrategy strategy, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L100-L102

[N‑43] NatSpec @return argument is missing

There are 168 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit Missing: '@return'
173       // ********************** //
174       /// @notice returns total market debt
175:      function getTotalDebt() external view returns (uint256) {

/// @audit Missing: '@return'
179       /// @notice returns the current debt rate
180:      function getDebtRate() public view returns (uint256) {

/// @audit Missing: '@return'
207       /// @param calls An array encoded call data.
208       /// @param revertOnFail If True then reverts after a failed call and stops doing further calls.
209       function execute(
210           bytes[] calldata calls,
211           bool revertOnFail
212:      ) external returns (bool[] memory successes, string[] memory results) {

/// @audit Missing: '@return'
441       /// @notice Transfers fees to penrose
442       function refreshPenroseFees(
443           address
444:      ) external onlyOwner notPaused returns (uint256 feeShares) {

/// @audit Missing: '@return'
720       /// @dev Concrete implementation of `repay`.
721       function _repay(
722           address from,
723           address to,
724           uint256 part
725:      ) internal returns (uint256 amount) {

/// @audit Missing: '@return'
741       /// @dev Concrete implementation of `borrow`.
742       function _borrow(
743           address from,
744           address to,
745           uint256 amount
746:      ) internal returns (uint256 part, uint256 share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L173-L175

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit Missing: '@return'
112       // *** VIEW FUNCTIONS *** //
113       // ********************** //
114:      function totalSupply() public view virtual override returns (uint256) {}

/// @audit Missing: '@return'
122        */
123       // solhint-disable-next-line func-name-mixedcase
124:      function DOMAIN_SEPARATOR() external view override returns (bytes32) {

/// @audit Missing: '@return'
240       /**
241        * @dev "Consume a nonce": return the current value and increment.
242        *
243        * _Available since v4.1._
244        */
245       function _useNonce(
246           address owner
247:      ) internal virtual returns (uint256 current) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L112-L114

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit Missing: '@return'
252       // ********************** //
253       // *** VIEW FUNCTIONS *** //
254       // ********************** //
255       /// @notice returns the maximum liquidatable amount for user
256       function computeClosingFactor(
257           uint256 borrowPart,
258           uint256 collateralPartInAsset,
259           uint256 borrowPartDecimals,
260           uint256 collateralPartDecimals,
261           uint256 ratesPrecision
262:      ) public view returns (uint256) {

/// @audit Missing: '@return'
353       /// @notice computes the possible liquidator reward
354       /// @notice user the user for which a liquidation operation should be performed
355       /// @param _exchangeRate the exchange rate asset/collateral to use for internal computations
356       function computeLiquidatorReward(
357           address user,
358           uint256 _exchangeRate
359:      ) public view returns (uint256) {

/// @audit Missing: '@return'
400       /// @notice Concrete implementation of `isSolvent`. Includes a parameter to allow caching `exchangeRate`.
401       /// @param _exchangeRate The exchange rate. Used to cache the `exchangeRate` between calls.
402       function _isSolvent(
403           address user,
404           uint256 _exchangeRate
405:      ) internal view returns (bool) {

/// @audit Missing: '@return'
427       /// @notice Returns the min and max LTV for user in asset price
428       function _computeMaxAndMinLTVInAsset(
429           uint256 collateralShare,
430           uint256 _exchangeRate
431:      ) internal view returns (uint256 min, uint256 max) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L252-L262

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit Missing: '@return'
33        // *** PRIVATE FUNCTIONS *** //
34        // ************************* //
35        function _getInterestRate()
36            internal
37            view
38            returns (
39                ISingularity.AccrueInfo memory _accrueInfo,
40                Rebase memory _totalBorrow,
41                Rebase memory _totalAsset,
42                uint256 extraAmount,
43                uint256 feeFraction,
44                uint256 utilization,
45:               bool logStartingInterest

/// @audit Missing: '@return'
196       /// @dev Concrete implementation of `addAsset`.
197       function _addAsset(
198           address from,
199           address to,
200           bool skim,
201           uint256 share
202:      ) internal returns (uint256 fraction) {

/// @audit Missing: '@return'
221       /// @dev Concrete implementation of `removeAsset`.
222       /// @param from The account to remove from. Should always be msg.sender except for `depositFeesToyieldBox()`.
223       function _removeAsset(
224           address from,
225           address to,
226           uint256 fraction,
227           bool updateYieldBoxShares
228:      ) internal returns (uint256 share) {

/// @audit Missing: '@return'
253       /// @dev Return the equivalent of collateral borrow part in asset amount.
254       function _getAmountForBorrowPart(
255           uint256 borrowPart
256:      ) internal view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L33-L45

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

/// @audit Missing: '@return'
57        /// @dev Concrete implementation of `borrow`.
58        function _borrow(
59            address from,
60            address to,
61            uint256 amount
62:       ) internal returns (uint256 part, uint256 share) {

/// @audit Missing: '@return'
82        /// @dev Concrete implementation of `repay`.
83        function _repay(
84            address from,
85            address to,
86            bool skim,
87            uint256 part
88:       ) internal returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L57-L62

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

/// @audit Missing: '@return'
67        // ************************* //
68        // *** PRIVATE FUNCTIONS *** //
69        // ************************* //
70        function _computeAssetAmountToSolvency(
71            address user,
72            uint256 _exchangeRate
73:       ) private view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L67-L73

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

/// @audit Missing: '@return'
152       // ********************** //
153       /// @notice returns market's ERC20 symbol
154:      function symbol() public view returns (string memory) {

/// @audit Missing: '@return'
168       /// @notice returns market's ERC20 name
169:      function name() external view returns (string memory) {

/// @audit Missing: '@return'
183       /// @notice returns market's ERC20 decimals
184:      function decimals() external view returns (uint8) {

/// @audit Missing: '@return'
189       /// @dev totalSupply for ERC20 compatibility
190       ///      BalanceOf[user] represent a fraction
191:      function totalSupply() public view override returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L152-L154

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit Missing: '@return'
475       /// @dev can only be called by the owner
476       /// @param feeTo fees receiver
477       function refreshPenroseFees(
478           address feeTo
479:      ) external onlyOwner notPaused returns (uint256 feeShares) {

/// @audit Missing: '@return'
597       // ************************* //
598       // *** PRIVATE FUNCTIONS *** //
599       // ************************* //
600:      function _extractModule(Module _module) private view returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L475-L479

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit Missing: '@return'
213       /// @notice Get the length of `singularityMasterContracts`
214:      function singularityMasterContractLength() public view returns (uint256) {

/// @audit Missing: '@return'
218       /// @notice Get the length of `bigbangMasterContracts`
219:      function bigBangMasterContractLength() public view returns (uint256) {

/// @audit Missing: '@return'
360       /// @param data The init data of the Singularity
361       /// @param useCreate2 Whether to use create2 or not
362       function registerSingularity(
363           address mc,
364           bytes calldata data,
365           bool useCreate2
366       )
367           external
368           payable
369           onlyOwner
370           registeredSingularityMasterContract(mc)
371:          returns (address _contract)

/// @audit Missing: '@return'
393       /// @param data The init data of the BigBang contract
394       /// @param useCreate2 Whether to use create2 or not
395       function registerBigBang(
396           address mc,
397           bytes calldata data,
398           bool useCreate2
399       )
400           external
401           payable
402           onlyOwner
403           registeredBigBangMasterContract(mc)
404:          returns (address _contract)

/// @audit Missing: '@return'
423       /// @notice Execute an only owner function inside of a Singularity or a BigBang market
424       function executeMarketFn(
425           address[] calldata mc,
426           bytes[] memory data,
427           bool forceSuccess
428       )
429           external
430           onlyOwner
431           notPaused
432:          returns (bool[] memory success, bytes[] memory result)

/// @audit Missing: '@return'
469       // ************************* //
470       // *** PRIVATE FUNCTIONS *** //
471       // ************************* //
472       function _getRevertMsg(
473           bytes memory _returnData
474:      ) private pure returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L213-L214

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit Missing: '@return'
141       // ************************ //
142       /// @notice returns token's decimals
143:      function decimals() public pure override returns (uint8) {

/// @audit Missing: '@return'
340       // ************************* //
341       // *** PRIVATE FUNCTIONS *** //
342       // ************************* //
343   
344:      function _extractModule(Module _module) private view returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L141-L143

File: tapioca-bar-audit/contracts/usd0/USDO.sol

/// @audit Missing: '@return'
53        // ********************** //
54        // *** VIEW FUNCTIONS *** //
55        // ********************** //
56        /// @notice returns the maximum amount of tokens available for a flash mint
57:       function maxFlashLoan(address) public view override returns (uint256) {

/// @audit Missing: '@return'
62        /// @param token USDO address
63        /// @param amount the amount for which fee is computed
64        function flashFee(
65            address token,
66            uint256 amount
67:       ) public view override returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L53-L57

File: tapiocaz-audit/contracts/Balancer.sol

/// @audit Missing: '@return'
133       // ************************ //
134       // *** PUBLIC FUNCTIONS *** //
135       // ************************ //
136   
137       function checker(
138           address payable _srcOft,
139           uint16 _dstChainId
140:      ) external view returns (bool canExec, bytes memory execPayload) {

/// @audit Missing: '@return'
264       // ************************* //
265       // *** PRIVATE FUNCTIONS *** //
266       // ************************* //
267       function _isValidOft(
268           address _srcOft,
269           address _dstOft,
270           uint16 _dstChainId
271:      ) private view returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L133-L140

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

/// @audit Missing: '@return'
73        // ********************** //
74        /// @notice Return the number of TOFT contracts deployed on the current chain.
75:       function tapiocaOFTLength() external view returns (uint256) {

/// @audit Missing: '@return'
79        /// @notice Return the number of harvestable TOFT contracts deployed on the current chain.
80:       function harvestableTapiocaOFTsLength() external view returns (uint256) {

/// @audit Missing: '@return'
84        /// @notice Return the latest TOFT contract deployed on the current chain.
85:       function lastTOFT() external view returns (ITapiocaOFT) {

/// @audit Missing: '@return'
180       // ************************* //
181       // *** PRIVATE FUNCTIONS *** //
182       // ************************* //
183       function _createTOFT(
184           address _erc20,
185           bytes calldata _bytecode,
186           bytes32 _salt,
187           bool _linked
188:      ) private returns (address) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L73-L75

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit Missing: '@return'
82        // ********************** //
83        /// @notice decimal number of the ERC20
84:       function decimals() public view override returns (uint8) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L82-L84

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit Missing: '@return'
147       //    READ
148       // ==========
149   
150:      function currentWeek() public view returns (uint256) {

/// @audit Missing: '@return'
154       /// @notice Return the participation of a token. Returns 0 votes for expired tokens.
155       function getParticipation(
156           uint _tokenId
157:      ) public view returns (Participation memory participant) {

/// @audit Missing: '@return'
165       /// @notice Amount currently claimable for each reward token
166       function claimable(
167           uint256 _tokenId
168:      ) public view returns (uint256[] memory) {

/// @audit Missing: '@return'
250       /// @param _amount The amount of TAP to participate with
251       /// @param _duration The duration of the lock
252       function participate(
253           address _participant,
254           uint256 _amount,
255           uint256 _duration
256:      ) external returns (uint256 tokenId) {

/// @audit Missing: '@return'
385       /// @notice Exit a twAML participation and send the withdrawn TAP to tapOFT to send it to another chain.
386       /// @param _tokenId The tokenId of the twTAP position
387       function exitPositionAndSendTap(
388           uint256 _tokenId
389:      ) external returns (uint256) {

/// @audit Missing: '@return'
451       // =========
452       //   OWNER
453       // =========
454   
455:      function addRewardToken(IERC20 token) external onlyOwner returns (uint256) {

/// @audit Missing: '@return'
521       /// @dev Release the tap of a position and send it to `_to`. Remove the user from twAML.
522       function _releaseTap(
523           uint256 _tokenId,
524           address _to
525:      ) internal returns (uint256 releasedAmount) {

/// @audit Missing: '@return'
570       /// @dev Returns the chain ID of the current network
571:      function _getChainId() internal view virtual returns (uint256) {

/// @audit Missing: '@return'
579       /**
580        * @dev See {IERC165-supportsInterface}.
581        */
582       function supportsInterface(
583           bytes4 interfaceId
584:      ) public view virtual override(ONFT721, ERC721) returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L147-L150

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit Missing: '@return'
197       /// @notice Participate in the airdrop
198       /// @param _data The data to be used for the participation, varies by phases
199       function participate(
200           bytes calldata _data
201:      ) external returns (uint256 aoTAPTokenID) {

/// @audit Missing: '@return'
389       /// @notice Participate in phase 1 of the Airdrop. LBP users are given aoTAP pro-rata.
390:      function _participatePhase1() internal returns (uint256 oTAPTokenID) {

/// @audit Missing: '@return'
408       /// @param _data The calldata. Needs to be the address of the user.
409       /// _data = (uint256 role, bytes32[] _merkleProof). Refer to {phase2MerkleRoots} for role.
410       function _participatePhase2(
411           bytes calldata _data
412:      ) internal returns (uint256 oTAPTokenID) {

/// @audit Missing: '@return'
440       /// @param _data The calldata. Needs to be the address of the user.
441       /// _data = (uint256 _tokenID)
442       function _participatePhase3(
443           bytes calldata _data
444:      ) internal returns (uint256 oTAPTokenID) {

/// @audit Missing: '@return'
464       /// @notice Participate in phase 4 of the Airdrop. twTAP and Cassava guild's role are given TAP pro-rata.
465:      function _participatePhase4() internal returns (uint256 oTAPTokenID) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L197-L201

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

/// @audit Missing: '@return'
64        // =========
65        //    READ
66        // =========
67    
68        function tokenURI(
69            uint256 _tokenId
70:       ) public view override returns (string memory) {

/// @audit Missing: '@return'
81        /// @notice Return the owner of the tokenId and the attributes of the option.
82        function attributes(
83            uint256 _tokenId
84:       ) external view returns (address, AirdropTapOption memory) {

/// @audit Missing: '@return'
88        /// @notice Check if a token exists
89:       function exists(uint256 _tokenId) external view returns (bool) {

/// @audit Missing: '@return'
105       /// @notice mints an AOTAP
106       /// @param _to address to mint to
107       /// @param _expiry timestamp
108       /// @param _discount TAP discount in basis points
109       function mint(
110           address _to,
111           uint128 _expiry,
112           uint128 _discount,
113           uint256 _amount
114:      ) external onlyBroker returns (uint256 tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L64-L70

File: tap-token-audit/contracts/options/oTAP.sol

/// @audit Missing: '@return'
50        // =========
51        //    READ
52        // =========
53    
54        function tokenURI(
55            uint256 _tokenId
56:       ) public view override returns (string memory) {

/// @audit Missing: '@return'
67        /// @notice Return the owner of the tokenId and the attributes of the option.
68        function attributes(
69            uint256 _tokenId
70:       ) external view returns (address, TapOption memory) {

/// @audit Missing: '@return'
74        /// @notice Check if a token exists
75:       function exists(uint256 _tokenId) external view returns (bool) {

/// @audit Missing: '@return'
94        /// @param _discount TAP discount in basis points
95        /// @param _tOLP tOLP token ID
96        function mint(
97            address _to,
98            uint128 _expiry,
99            uint128 _discount,
100           uint256 _tOLP
101:      ) external onlyBroker returns (uint256 tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L50-L56

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit Missing: '@return'
210       /// @notice Participate in twAMl voting and mint an oTAP position
211       /// @param _tOLPTokenID The tokenId of the tOLP position
212       function participate(
213           uint256 _tOLPTokenID
214:      ) external returns (uint256 oTAPTokenID) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L210-L214

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit Missing: '@return'
110       /// @notice Returns the lock position of a given tOLP NFT and if it's active
111       /// @param _tokenId tOLP NFT ID
112       function getLock(
113           uint256 _tokenId
114:      ) external view returns (bool, LockPosition memory) {

/// @audit Missing: '@return'
120       /// @notice Returns the active singularity YieldBox ID markets
121:      function getSingularities() external view returns (uint256[] memory) {

/// @audit Missing: '@return'
125       /// @notice Returns the active singularity pool data
126       function getSingularityPools()
127           external
128           view
129:          returns (SingularityPool[] memory)

/// @audit Missing: '@return'
145       /// @notice Returns the total amount of locked tokens for a given singularity market
146       function getTotalPoolDeposited(
147           uint256 _sglAssetId
148:      ) external view returns (uint256) {

/// @audit Missing: '@return'
205       /// @param _singularity Singularity market address
206       /// @param _to Address to send the tokens to
207       function unlock(
208           uint256 _tokenId,
209           IERC20 _singularity,
210           address _to
211:      ) external returns (uint256 sharesOut) {

/// @audit Missing: '@return'
335       /// @notice Compute the total pool weight of all active singularity markets
336:      function _computeSGLPoolWeights() internal view returns (uint256) {

/// @audit Missing: '@return'
347       /// @notice Checks if the lock position is still active
348:      function _isPositionActive(uint256 tokenId) internal view returns (bool) {

/// @audit Missing: '@return'
356       /// @notice ERC1155 compliance
357       function onERC1155Received(
358           address,
359           address,
360           uint256,
361           uint256,
362           bytes calldata
363:      ) external pure returns (bytes4) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L110-L114

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit Missing: '@return'
166       //-- View methods --
167       /// @notice returns token's decimals
168:      function decimals() public pure override returns (uint8) {

/// @audit Missing: '@return'
172       /// @notice Returns the current week given a timestamp
173       function timestampToWeek(
174           uint256 timestamp
175:      ) external view returns (uint256) {

/// @audit Missing: '@return'
184       /// @notice Returns the current week
185:      function getCurrentWeek() external view returns (uint256) {

/// @audit Missing: '@return'
189       /// @notice Returns the current week emission
190:      function getCurrentWeekEmission() external view returns (uint256) {

/// @audit Missing: '@return'
238       ///-- Internal methods --
239       function _timestampToWeek(
240           uint256 timestamp
241:      ) internal view returns (uint256) {

/// @audit Missing: '@return'
246       /// @notice Return the current chain ID.
247       /// @dev Useful for testing.
248:      function _getChainId() private view returns (uint256) {

/// @audit Missing: '@return'
252       /// @notice returns the available emissions for a given supply
253:      function _computeEmission() internal view returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L166-L168

File: tap-token-audit/contracts/twAML.sol

/// @audit Missing: '@return'
5         // https://xn--2-umb.com/21/muldiv/
6         function muldiv(
7             uint256 a,
8             uint256 b,
9             uint256 denominator
10:       ) internal pure returns (uint256 result) {

/// @audit Missing: '@return'
113       /// @param _totalWeight The total weight of the twAML system
114       /// @param _minWeightFactor The minimum weight factor in BPS
115       function computeMinWeight(
116           uint256 _totalWeight,
117           uint256 _minWeightFactor
118:      ) internal pure returns (uint256) {

/// @audit Missing: '@return'
146       // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
147:      function sqrt(uint256 y) internal pure returns (uint256 z) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L5-L10

File: tap-token-audit/contracts/Vesting.sol

/// @audit Missing: '@return'
77        // ********************** //
78        /// @notice returns total claimable
79:       function claimable() external view returns (uint256) {

/// @audit Missing: '@return'
83        /// @notice returns total claimable for user
84        /// @param _user the user address
85:       function claimable(address _user) public view returns (uint256) {

/// @audit Missing: '@return'
89        /// @notice returns total vested amount
90:       function vested() external view returns (uint256) {

/// @audit Missing: '@return'
94        /// @notice returns total vested amount for user
95        /// @param _user the user address
96:       function vested(address _user) external view returns (uint256) {

/// @audit Missing: '@return'
100       /// @notice returns total claimed
101:      function totalClaimed() external view returns (uint256) {

/// @audit Missing: '@return'
164       // ************************* //
165       // *** PRIVATE FUNCTIONS *** //
166       // ************************* //
167:      function _vested(uint256 _total) private view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L77-L79

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit Missing: '@return'
53        /// @param who user to return for
54        /// @param markets the list of Singularity markets to query for
55        function singularityMarketInfo(
56            address who,
57            ISingularity[] calldata markets
58:       ) external view returns (SingularityInfo[] memory) {

/// @audit Missing: '@return'
63        /// @param who user to return for
64        /// @param markets the list of BigBang markets to query for
65        function bigBangMarketInfo(
66            address who,
67            IBigBang[] calldata markets
68:       ) external view returns (BigBangInfo[] memory) {

/// @audit Missing: '@return'
192       /// @notice Batch multiple calls together
193       /// @param calls The list of actions to perform
194       function burst(
195           Call[] calldata calls
196:      ) external payable returns (Result[] memory returnData) {

/// @audit Missing: '@return'
906       // ********************** //
907       // *** PRIVATE METHODS *** //
908       // *********************** //
909       function _commonInfo(
910           address who,
911           IMarket market
912:      ) private view returns (MarketInfo memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L53-L58

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit Missing: '@return'
45        /// ***  ***
46        /// @notice returns default bytes swap data
47        function getDefaultDexOptions()
48            public
49            pure
50            override
51:           returns (bytes memory)

/// @audit Missing: '@return'
57        /// @param swapData operation data
58        /// @param dexOptions AMM data
59        function getOutputAmount(
60            SwapData calldata swapData,
61            bytes calldata dexOptions
62:       ) external view override returns (uint256 amountOut) {

/// @audit Missing: '@return'
78        /// @notice Comutes amount in for amount out
79        function getInputAmount(
80            SwapData calldata,
81            bytes calldata
82:       ) external pure returns (uint256) {

/// @audit Missing: '@return'
92        /// @param to receiver address
93        /// @param data AMM data
94        function swap(
95            SwapData calldata swapData,
96            uint256 amountOutMin,
97            address to,
98            bytes memory data
99:       ) external override returns (uint256 amountOut, uint256 shareOut) {

/// @audit Missing: '@return'
144       /// *** PRIVATE METHODS ***
145       /// ***  ***
146       function _swapTokensForTokens(
147           int128 i,
148           int128 j,
149           uint256 amountIn,
150           uint256 amountOutMin
151:      ) private returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L45-L51

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

/// @audit Missing: '@return'
45        /// ***  ***
46        /// @notice returns default bytes swap data
47        function getDefaultDexOptions()
48            public
49            view
50            override
51:           returns (bytes memory)

/// @audit Missing: '@return'
56        /// @notice Computes amount out for amount in
57        /// @param swapData operation data
58        function getOutputAmount(
59            SwapData calldata swapData,
60            bytes calldata
61:       ) external view override returns (uint256 amountOut) {

/// @audit Missing: '@return'
78        /// @notice Comutes amount in for amount out
79        function getInputAmount(
80            SwapData calldata swapData,
81            bytes calldata
82:       ) external view override returns (uint256 amountIn) {

/// @audit Missing: '@return'
105       /// @param to receiver address
106       /// @param data AMM data
107       function swap(
108           SwapData calldata swapData,
109           uint256 amountOutMin,
110           address to,
111           bytes memory data
112       )
113           external
114           override
115           nonReentrant
116:          returns (uint256 amountOut, uint256 shareOut)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L45-L51

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit Missing: '@return'
67        /// ***  ***
68        /// @notice returns default bytes swap data
69        function getDefaultDexOptions()
70            public
71            view
72            override
73:           returns (bytes memory)

/// @audit Missing: '@return'
78        /// @notice Computes amount out for amount in
79        /// @param swapData operation data
80        function getOutputAmount(
81            SwapData calldata swapData,
82            bytes calldata
83:       ) external view override returns (uint256 amountOut) {

/// @audit Missing: '@return'
107       /// @notice Comutes amount in for amount out
108       function getInputAmount(
109           SwapData calldata swapData,
110           bytes calldata
111:      ) external view override returns (uint256 amountIn) {

/// @audit Missing: '@return'
140       /// @param to receiver address
141       /// @param data AMM data
142       function swap(
143           SwapData calldata swapData,
144           uint256 amountOutMin,
145           address to,
146           bytes memory data
147:      ) external override returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L67-L73

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

/// @audit Missing: '@return'
8         /**
9          * @dev Deploys a contract using `CREATE2`. The address where the contract
10         * will be deployed can be known in advance via {computeAddress}.
11         *
12         * The bytecode for a contract can be obtained from Solidity with
13         * `type(contractName).creationCode`.
14         *
15         * Requirements:
16         *
17         * - `bytecode` must not be empty.
18         * - `salt` must have not been used for `bytecode` already.
19         * - the factory must have a balance of at least `amount`.
20         * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
21         */
22        function deploy(
23            uint256 amount,
24            bytes32 salt,
25            bytes memory bytecode,
26            string memory contractName
27:       ) external payable returns (address addr) {

/// @audit Missing: '@return'
52        /**
53         * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
54         * `bytecodeHash` or `salt` will result in a new destination address.
55         */
56        function computeAddress(
57            bytes32 salt,
58            bytes32 bytecodeHash
59:       ) external view returns (address) {

/// @audit Missing: '@return'
63        /**
64         * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
65         * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
66         */
67        function computeAddress(
68            bytes32 salt,
69            bytes32 bytecodeHash,
70            address deployer
71:       ) public pure returns (address addr) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L8-L27

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit Missing: '@return'
81        // ********************** //
82        /// @notice Returns the name of this strategy
83:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
87        /// @notice Returns the description of this strategy
88        function description()
89            external
90            pure
91            override
92:           returns (string memory description_)

/// @audit Missing: '@return'
97        /// @notice returns compounded amounts in wrappedNative
98:       function compoundAmount() public view returns (uint256 result) {

/// @audit Missing: '@return'
208       /// @notice withdraws everythig from the strategy
209:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
223       // ************************* //
224       /// @dev queries 'getUserAccountData' from AAVE and gets the total collateral
225:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L81-L83

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit Missing: '@return'
83        // ********************** //
84        /// @notice Returns the name of this strategy
85:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
89        /// @notice Returns the description of this strategy
90        function description()
91            external
92            pure
93            override
94:           returns (string memory description_)

/// @audit Missing: '@return'
99        /// @notice returns compounded amounts in wrappedNative
100:      function compoundAmount() external pure returns (uint256 result) {

/// @audit Missing: '@return'
119       /// @notice withdraws everythig from the strategy
120:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
128       // *** PRIVATE FUNCTIONS *** //
129       // ************************* //
130:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L83-L85

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit Missing: '@return'
63        // ********************** //
64        /// @notice Returns the name of this strategy
65:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
69        /// @notice Returns the description of this strategy
70        function description()
71            external
72            pure
73            override
74:           returns (string memory description_)

/// @audit Missing: '@return'
79        /// @notice returns compounded amounts in wrappedNative
80:       function compoundAmount() public pure returns (uint256 result) {

/// @audit Missing: '@return'
99        /// @notice withdraws everythig from the strategy
100:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
111       // *** PRIVATE FUNCTIONS *** //
112       // ************************* //
113:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L63-L65

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit Missing: '@return'
113       // ********************** //
114       /// @notice Returns the name of this strategy
115:      function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
119       /// @notice Returns the description of this strategy
120       function description()
121           external
122           pure
123           override
124:          returns (string memory description_)

/// @audit Missing: '@return'
129       /// @notice returns compounded amounts in wrappedNative
130:      function compoundAmount() public view returns (uint256 result) {

/// @audit Missing: '@return'
147       /// @notice withdraws everythig from the strategy
148:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
289       // ************************* //
290       /// @dev queries total staked
291:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L113-L115

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit Missing: '@return'
87        // ********************** //
88        /// @notice Returns the name of this strategy
89:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
93        /// @notice Returns the description of this strategy
94        function description()
95            external
96            pure
97            override
98:           returns (string memory description_)

/// @audit Missing: '@return'
103       /// @notice returns compounded amounts in wrappedNative
104:      function compoundAmount() public view returns (uint256 result) {

/// @audit Missing: '@return'
198       /// @notice withdraws everythig from the strategy
199:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
208       // ************************* //
209       /// @dev queries Curve-Tricrypto Liquidity Pool
210:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L87-L89

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit Missing: '@return'
86        // ********************** //
87        /// @notice Returns the name of this strategy
88:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
92        /// @notice Returns the description of this strategy
93        function description()
94            external
95            pure
96            override
97:           returns (string memory description_)

/// @audit Missing: '@return'
102       /// @notice returns compounded amounts in wrappedNative
103:      function compoundAmount() public returns (uint256 result) {

/// @audit Missing: '@return'
181       /// @notice withdraws everythig from the strategy
182:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
194       // ************************* //
195       /// @dev queries Curve-Tricrypto Liquidity Pool
196:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L86-L88

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit Missing: '@return'
180       /// @dev Underreports if not all vesting claims have been made.
181       function _getVestableAmount(
182           IGmxVester vester,
183           uint256 available,
184           uint256 tokenAvailable
185:      ) private view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L180-L185

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit Missing: '@return'
67        // ********************** //
68        /// @notice Returns the name of this strategy
69:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
73        /// @notice Returns the description of this strategy
74        function description()
75            external
76            pure
77            override
78:           returns (string memory description_)

/// @audit Missing: '@return'
83        /// @notice returns compounded amounts in wrappedNative
84:       function compoundAmount() public pure returns (uint256 result) {

/// @audit Missing: '@return'
103       /// @notice withdraws everythig from the strategy
104:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
116       // ************************* //
117       /// @dev queries Lido and Curve Eth/STEth pools
118:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L67-L69

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit Missing: '@return'
99        // ********************** //
100       /// @notice Returns the name of this strategy
101:      function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
105       /// @notice Returns the description of this strategy
106       function description()
107           external
108           pure
109           override
110:          returns (string memory description_)

/// @audit Missing: '@return'
115       /// @notice returns compounded amounts in wrappedNative
116:      function compoundAmount() public view returns (uint256 result) {

/// @audit Missing: '@return'
192       /// @notice withdraws everythig from the strategy
193:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
212       // ************************* //
213       /// @dev queries 'getUserAccountData' from Stargate and gets the total collateral
214:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L99-L101

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit Missing: '@return'
64        // ********************** //
65        /// @notice Returns the name of this strategy
66:       function name() external pure override returns (string memory name_) {

/// @audit Missing: '@return'
70        /// @notice Returns the description of this strategy
71        function description()
72            external
73            pure
74            override
75:           returns (string memory description_)

/// @audit Missing: '@return'
80        /// @notice returns compounded amounts in wrappedNative
81:       function compoundAmount() public pure returns (uint256 result) {

/// @audit Missing: '@return'
100       /// @notice withdraws everythig from the strategy
101:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit Missing: '@return'
109       // *** PRIVATE FUNCTIONS *** //
110       // ************************* //
111:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L64-L66

File: YieldBox/contracts/NativeTokenFactory.sol

/// @audit Missing: '@return'
85        /// @notice Create a new native token. This will be an ERC1155 token. If later it's needed as an ERC20 token it can
86        /// be wrapped into an ERC20 token. Native support for ERC1155 tokens is growing though.
87        /// @param name The name of the token.
88        /// @param symbol The symbol of the token.
89        /// @param decimals The number of decimals of the token (this is just for display purposes). Should be set to 18 in normal cases.
90:       function createToken(string calldata name, string calldata symbol, uint8 decimals, string calldata uri) public returns (uint32 tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L85-L90

File: YieldBox/contracts/YieldBoxPermit.sol

/// @audit Missing: '@return'
98        /**
99         * @dev See {IERC20Permit-nonces}.
100        */
101:      function nonces(address owner) public view virtual returns (uint256) {

/// @audit Missing: '@return'
107        */
108       // solhint-disable-next-line func-name-mixedcase
109:      function DOMAIN_SEPARATOR() external view returns (bytes32) {

/// @audit Missing: '@return'
113       /**
114        * @dev "Consume a nonce": return the current value and increment.
115        *
116        */
117:      function _useNonce(address owner) internal virtual returns (uint256 current) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L98-L101

File: YieldBox/contracts/YieldBoxRebase.sol

/// @audit Missing: '@return'
17        /// @notice Calculates the base value in relationship to `elastic` and `total`.
18        function _toShares(
19            uint256 amount,
20            uint256 totalShares_,
21            uint256 totalAmount,
22            bool roundUp
23:       ) internal pure returns (uint256 share) {

/// @audit Missing: '@return'
40        /// @notice Calculates the elastic value in relationship to `base` and `total`.
41        function _toAmount(
42            uint256 share,
43            uint256 totalShares_,
44            uint256 totalAmount,
45            bool roundUp
46:       ) internal pure returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L17-L23

File: YieldBox/contracts/YieldBox.sol

/// @audit Missing: '@return'
100       /// @dev Returns the total balance of `token` the strategy contract holds,
101       /// plus the total amount this contract thinks the strategy holds.
102:      function _tokenBalanceOf(Asset storage asset) internal view returns (uint256 amount) {

/// @audit Missing: '@return'
221       /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.
222       /// @param share Like above, but `share` takes precedence over `amount`.
223       function withdraw(
224           uint256 assetId,
225           address from,
226           address to,
227           uint256 amount,
228           uint256 share
229:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

/// @audit Missing: '@return'
245       /// @param from which user to pull the tokens.
246       /// @param to which user to push the tokens.
247       function _withdrawNFT(
248           Asset storage asset,
249           uint256 assetId,
250           address from,
251           address to
252:      ) internal returns (uint256 amountOut, uint256 shareOut) {

/// @audit Missing: '@return'
268       /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.
269       /// @param share Like above, but `share` takes precedence over `amount`.
270       function _withdrawFungible(
271           Asset storage asset,
272           uint256 assetId,
273           address from,
274           address to,
275           uint256 amount,
276           uint256 share
277:      ) internal returns (uint256 amountOut, uint256 shareOut) {

/// @audit Missing: '@return'
400       // This functionality has been split off into a separate contract. This is only a view function, so gas usage isn't a huge issue.
401       // This keeps the YieldBox contract smaller, so it can be optimized more.
402:      function uri(uint256 assetId) external view override returns (string memory) {

/// @audit Missing: '@return'
456       /// @param user The `user` to get the amount for.
457       /// @param assetId The id of the asset.
458:      function amountOf(address user, uint256 assetId) external view returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L100-L102

[N‑44] Avoid the use of sensitive terms

Use alternative variants, e.g. allowlist/denylist instead of whitelist/blacklist

There are 60 instances of this issue:

File: tapioca-bar-audit/contracts/Penrose.sol

56:       IPenrose.MasterContract[] public singularityMasterContracts;

58:       IPenrose.MasterContract[] public bigbangMasterContracts;

61        mapping(address => bool) public isSingularityMasterContractRegistered;
62        // Used to check if a BigBang master contract is registered
63        mapping(address => bool) public isBigBangMasterContractRegistered;
64        // Used to check if a SGL/BB is a real market
65:       mapping(address => bool) public isMarketRegistered;

63:       mapping(address => bool) public isBigBangMasterContractRegistered;

545:          uint256 _masterContractLength = array.length;

56:       IPenrose.MasterContract[] public singularityMasterContracts;

58:       IPenrose.MasterContract[] public bigbangMasterContracts;

61:       mapping(address => bool) public isSingularityMasterContractRegistered;

63:       mapping(address => bool) public isBigBangMasterContractRegistered;

140       event RegisterSingularityMasterContract(
141           address location,
142           IPenrose.ContractType risk
143:      );

145       event RegisterBigBangMasterContract(
146           address location,
147           IPenrose.ContractType risk
148:      );

175:              isSingularityMasterContractRegistered[mc] == true,

183:              isBigBangMasterContractRegistered[mc] == true,

204:          markets = _getMasterContractLength(singularityMasterContracts);

210:          markets = _getMasterContractLength(bigbangMasterContracts);

214:      function singularityMasterContractLength() public view returns (uint256) {

215:          return singularityMasterContracts.length;

219:      function bigBangMasterContractLength() public view returns (uint256) {

220:          return bigbangMasterContracts.length;

317       function registerSingularityMasterContract(
318           address mcAddress,
319           IPenrose.ContractType contractType_
320:      ) external onlyOwner {

322:              isSingularityMasterContractRegistered[mcAddress] == false,

329:          singularityMasterContracts.push(mc);

330:          isSingularityMasterContractRegistered[mcAddress] = true;

332:          emit RegisterSingularityMasterContract(mcAddress, contractType_);

339       function registerBigBangMasterContract(
340           address mcAddress,
341           IPenrose.ContractType contractType_
342:      ) external onlyOwner {

344:              isBigBangMasterContractRegistered[mcAddress] == false,

351:          bigbangMasterContracts.push(mc);

352:          isBigBangMasterContractRegistered[mcAddress] = true;

354:          emit RegisterBigBangMasterContract(mcAddress, contractType_);

439:                  isSingularityMasterContractRegistered[

441:                  ] || isBigBangMasterContractRegistered[masterContractOf[mc[i]]],

542       function _getMasterContractLength(
543           IPenrose.MasterContract[] memory array
544:      ) public view returns (address[] memory markets) {

545:          uint256 _masterContractLength = array.length;

550:              for (uint256 i = 0; i < _masterContractLength; ) {

564:              for (uint256 i = 0; i < _masterContractLength; ) {

55:       /// @notice Singularity master contracts

57:       /// @notice BigBang master contracts

60:       // Used to check if a Singularity master contract is registered

62:       // Used to check if a BigBang master contract is registered

70:       /// @notice whitelisted swappers

139:      /// @notice event emitted when Singularity master contract is registered

144:      /// @notice event emitted when BigBang master contract is registered

213:      /// @notice Get the length of `singularityMasterContracts`

218:      /// @notice Get the length of `bigbangMasterContracts`

226:      /// @notice Loop through the master contracts and call `_depositFeesToYieldBox()` to each one of their clones.

227:      /// @dev `swappers_` can have one element that'll be used for all clones. Or one swapper per MasterContract.

313:      /// @notice Register a Singularity master contract

335:      /// @notice Register a BigBang master contract

359:      /// @param mc The address of the master contract which must be already registered

380:      /// @param mc The address of the master contract which must be already registered

392:      /// @param mc The address of the master contract which must be already registered

413:      /// @param mc The address of the master contract which must be already registered

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L56

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

113:      /// @notice updates a connected chain whitelist status

115:      /// @param _status the new whitelist status

128:      /// @notice updates a Balancer whitelist status

130:      /// @param _status the new whitelist status

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L113

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

222:      /// @param _paymentToken Address of the payment token to use, must be whitelisted

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L222

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

349:      /// @param _paymentToken Address of the payment token to use, must be whitelisted

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L349

[N‑45] Function ordering does not follow the Solidity style guide

According to the Solidity style guide, functions should be laid out in the following order :constructor(), receive(), fallback(), external, public, internal, private, but the cases below do not follow this pattern

There are 81 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit getDebtRate() came earlier
209       function execute(
210           bytes[] calldata calls,
211           bool revertOnFail
212:      ) external returns (bool[] memory successes, string[] memory results) {

/// @audit removeCollateral() came earlier
309       function liquidate(
310           address[] calldata users,
311           uint256[] calldata maxBorrowParts,
312           ISwapper swapper,
313           bytes calldata collateralToAssetSwapData
314:      ) external notPaused {

/// @audit transferFrom() came earlier
442       function refreshPenroseFees(
443           address
444:      ) external onlyOwner notPaused returns (uint256 feeShares) {

/// @audit _closedLiquidation() came earlier
691       function _addTokens(
692           address from,
693           uint256 _tokenId,
694           uint256 share,
695           uint256 total,
696:          bool skim

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L209-L212

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit _allowedBorrow() came earlier
109:      constructor(string memory name) EIP712(name, "1") {}

/// @audit nonces() came earlier
124:      function DOMAIN_SEPARATOR() external view override returns (bytes32) {

/// @audit approveBorrow() came earlier
212       function permit(
213           address owner,
214           address spender,
215           uint256 value,
216           uint256 deadline,
217           uint8 v,
218           bytes32 r,
219:          bytes32 s

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L109

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit accrue() came earlier
21        function getInterestDetails()
22            external
23            view
24            returns (
25                ISingularity.AccrueInfo memory _accrueInfo,
26:               uint256 utilization

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L21-L26

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

/// @audit symbol() came earlier
169:      function name() external view returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L169

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit repay() came earlier
322       function sellCollateral(
323           address from,
324           uint256 share,
325           uint256 minAmountOut,
326           ISwapper swapper,
327           bytes calldata dexData
328:      ) external returns (uint256 amountOut) {

/// @audit withdrawFeesEarned() came earlier
477       function refreshPenroseFees(
478           address feeTo
479:      ) external onlyOwner notPaused returns (uint256 feeShares) {

/// @audit _executeViewModule() came earlier
644:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L322-L328

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit withdrawAllMarketFees() came earlier
256:      function setBigBangEthMarketDebtRate(uint256 _rate) external onlyOwner {

/// @audit _depositFeesToYieldBox() came earlier
542       function _getMasterContractLength(
543           IPenrose.MasterContract[] memory array
544:      ) public view returns (address[] memory markets) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L256

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit decimals() came earlier
158       function triggerSendFrom(
159           uint16 lzDstChainId,
160           bytes calldata airdropAdapterParams,
161           address zroPaymentAddress,
162           uint256 amount,
163           ISendFrom.LzCallParams calldata sendFromData,
164:          ICommonData.IApproval[] calldata approvals

/// @audit _executeOnDestination() came earlier
399       function _nonblockingLzReceive(
400           uint16 _srcChainId,
401           bytes memory _srcAddress,
402           uint64 _nonce,
403:          bytes memory _payload

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L158-L164

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

/// @audit receive() came earlier
70        constructor(
71            address _lzEndpoint,
72            IYieldBoxBase _yieldBox
73:       ) OFTV2("USDO", "USDO", 8, _lzEndpoint) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L70-L73

File: tapioca-bar-audit/contracts/usd0/USDO.sol

/// @audit flashFee() came earlier
81        function flashLoan(
82            IERC3156FlashBorrower receiver,
83            address token,
84            uint256 amount,
85            bytes calldata data
86:       ) external override notPaused returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L81-L86

File: tapiocaz-audit/contracts/Balancer.sol

/// @audit _computeMinAmount() came earlier
342:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L342

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit decimals() came earlier
99        function triggerSendFrom(
100           uint16 lzDstChainId,
101           bytes calldata airdropAdapterParams,
102           address zroPaymentAddress,
103           uint256 amount,
104           ISendFrom.LzCallParams calldata sendFromData,
105:          ICommonData.IApproval[] calldata approvals

/// @audit _executeOnDestination() came earlier
442       function _nonblockingLzReceive(
443           uint16 _srcChainId,
444           bytes memory _srcAddress,
445           uint64 _nonce,
446:          bytes memory _payload

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L99-L105

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

/// @audit receive() came earlier
45        constructor(
46            address _lzEndpoint,
47            address _erc20,
48            IYieldBoxBase _yieldBox,
49            string memory _name,
50            string memory _symbol,
51            uint8 _decimal,
52            uint256 _hostChainID
53        )
54            OFTV2(
55                string(abi.encodePacked("TapiocaOFT-", _name)),
56                string(abi.encodePacked("t", _symbol)),
57                _decimal / 2,
58                _lzEndpoint
59:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L45-L59

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit claimable() came earlier
252       function participate(
253           address _participant,
254           uint256 _amount,
255           uint256 _duration
256:      ) external returns (uint256 tokenId) {

/// @audit advanceWeek() came earlier
429       function distributeReward(
430           uint256 _rewardTokenId,
431:          uint256 _amount

/// @audit _getChainId() came earlier
582       function supportsInterface(
583           bytes4 interfaceId
584:      ) public view virtual override(ONFT721, ERC721) returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L252-L256

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

/// @audit tokenURI() came earlier
74        function isApprovedOrOwner(
75            address _spender,
76            uint256 _tokenId
77:       ) external view returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L74-L77

File: tap-token-audit/contracts/options/oTAP.sol

/// @audit tokenURI() came earlier
60        function isApprovedOrOwner(
61            address _spender,
62            uint256 _tokenId
63:       ) external view returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L60-L63

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit _isPositionActive() came earlier
357       function onERC1155Received(
358           address,
359           address,
360           uint256,
361           uint256,
362           bytes calldata
363:      ) external pure returns (bytes4) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L357-L363

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

/// @audit _nonblockingLzReceive() came earlier
88        function lockTwTapPosition(
89            address to,
90            uint256 amount, // Amount to add
91            uint256 duration, // Duration of the position.
92            uint16 lzDstChainId,
93            address zroPaymentAddress,
94:           bytes calldata adapterParams

/// @audit _lockTwTapPosition() came earlier
163       function claimRewards(
164           address to,
165           uint256 tokenID,
166           address[] memory rewardTokens,
167           uint16 lzDstChainId,
168           address zroPaymentAddress,
169           bytes calldata adapterParams,
170:          IRewardClaimSendFromParams[] calldata rewardClaimSendParams

/// @audit _claimRewards() came earlier
258       function unlockTwTapPosition(
259           address to,
260           uint256 tokenID,
261           uint16 lzDstChainId,
262           address zroPaymentAddress,
263           bytes calldata adapterParams,
264:          LzCallParams calldata twTapSendBackAdapterParams

/// @audit _unlockTwTapPosition() came earlier
326:      function setTwTap(address _twTap) external onlyOwner {

/// @audit setTwTap() came earlier
330:      receive() external payable virtual {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L88-L94

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit decimals() came earlier
173       function timestampToWeek(
174           uint256 timestamp
175:      ) external view returns (uint256) {

/// @audit _getChainId() came earlier
253:      function _computeEmission() internal view returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L173-L175

File: tap-token-audit/contracts/Vesting.sol

/// @audit claimable() came earlier
90:       function vested() external view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L90

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit getFractionForAmount() came earlier
194       function burst(
195           Call[] calldata calls
196:      ) external payable returns (Result[] memory returnData) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L194-L196

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

/// @audit _checkSender() came earlier
340:      receive() external payable virtual {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L340

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit A() came earlier
44        constructor(
45            string memory __name,
46            string memory __symbol,
47            ICurvePool pool,
48            AggregatorV2V3Interface btcFeed,
49            AggregatorV2V3Interface ethFeed,
50            AggregatorV2V3Interface usdtFeed,
51:           AggregatorV2V3Interface wbtcFeed

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L44-L51

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

/// @audit _get() came earlier
24        function get(
25            bytes calldata
26:       ) public view override returns (bool success, uint256 rate) {

/// @audit peek() came earlier
40        function peekSpot(
41            bytes calldata data
42:       ) external view override returns (uint256 rate) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L24-L26

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit token() came earlier
30        constructor(
31            string memory __name,
32            string memory __symbol,
33            IStargatePool pool,
34:           AggregatorV2V3Interface _underlying

/// @audit _get() came earlier
61        function get(
62            bytes calldata
63:       ) external virtual returns (bool success, uint256 rate) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L30-L34

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit getDefaultDexOptions() came earlier
59        function getOutputAmount(
60            SwapData calldata swapData,
61            bytes calldata dexOptions
62:       ) external view override returns (uint256 amountOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L59-L62

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

/// @audit getDefaultDexOptions() came earlier
58        function getOutputAmount(
59            SwapData calldata swapData,
60            bytes calldata
61:       ) external view override returns (uint256 amountOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L58-L61

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit getDefaultDexOptions() came earlier
80        function getOutputAmount(
81            SwapData calldata swapData,
82            bytes calldata
83:       ) external view override returns (uint256 amountOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L80-L83

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit compoundAmount() came earlier
122:      function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
209:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L122

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit compound() came earlier
120:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit _vaultDeposit() came earlier
191       function _withdraw(
192           address to,
193           uint256 amount
194:      ) internal override nonReentrant {

/// @audit _vaultWithdraw() came earlier
271:      function updateCache() public returns (uint256) {

/// @audit updateCache() came earlier
301:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L120

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit compoundAmount() came earlier
89:       function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
100:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit _withdraw() came earlier
164:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L89

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit compoundAmount() came earlier
148:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit _executeClaim() came earlier
291:      function _currentBalance() internal view override returns (uint256 amount) {

/// @audit _addLiquidityAndStake() came earlier
320       function _withdraw(
321           address to,
322           uint256 amount
323:      ) internal override nonReentrant {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L148

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit compoundAmount() came earlier
134:      function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
199:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L134

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit compoundAmount() came earlier
125:      function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
182:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L125

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit harvestGmx() came earlier
113:      function setFeeRecipient(address recipient) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L113

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit compoundAmount() came earlier
93:       function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
104:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit _withdraw() came earlier
169:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L93

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit compoundAmount() came earlier
142:      function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
193:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

/// @audit _stake() came earlier
241       function _withdraw(
242           address to,
243           uint256 amount
244:      ) internal override nonReentrant {

/// @audit _withdraw() came earlier
271:      receive() external payable {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L142

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit compoundAmount() came earlier
90:       function setDepositThreshold(uint256 amount) external onlyOwner {

/// @audit compound() came earlier
101:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L90

File: YieldBox/contracts/YieldBoxPermit.sol

/// @audit _setApprovalForAsset() came earlier
72        function permitAll(
73            address owner,
74            address spender,
75            uint256 deadline,
76            uint8 v,
77            bytes32 r,
78:           bytes32 s

/// @audit _setApprovalForAll() came earlier
101:      function nonces(address owner) public view virtual returns (uint256) {

/// @audit nonces() came earlier
109:      function DOMAIN_SEPARATOR() external view returns (bytes32) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L72-L78

File: YieldBox/contracts/YieldBox.sol

/// @audit _tokenBalanceOf() came earlier
118       function depositAsset(
119           uint256 assetId,
120           address from,
121           address to,
122           uint256 amount,
123           uint256 share
124:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

/// @audit _withdrawFungible() came earlier
303:      function transfer(address from, address to, uint256 assetId, uint256 share) public allowed(from, assetId) {

/// @audit _transferBatch() came earlier
336:      function transferMultiple(address from, address[] calldata tos, uint256 assetId, uint256[] calldata shares) public allowed(from, assetId) {

/// @audit transferMultiple() came earlier
358:      function setApprovalForAll(address operator, bool approved) external override {

/// @audit _setApprovalForAll() came earlier
380:      function setApprovalForAsset(address operator, uint256 assetId, bool approved) external override {

/// @audit _setApprovalForAsset() came earlier
402:      function uri(uint256 assetId) external view override returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L118-L124

[N‑46] Contract does not follow the Solidity style guide's suggested layout ordering

The style guide says that, within a contract, the ordering should be 1) Type declarations, 2) State variables, 3) Events, 4) Modifiers, and 5) Functions, but the contract(s) below do not follow this ordering

There are 15 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit function _allowedBorrow came earlier
94        modifier allowedLend(address from, uint share) virtual {
95            _allowedLend(from, share);
96            _;
97:       }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L94-L97

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit modifier solvent came earlier
129:      bool internal initialized;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L129

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

/// @audit event UsdoSwapperUpdated came earlier
143:      uint256 internal constant FULL_UTILIZATION = 1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L143

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit function constructor came earlier
138:      event ProtocolWithdrawal(IMarket[] markets, uint256 timestamp);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L138

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit function constructor came earlier
134       event Participate(
135           address indexed participant,
136           uint256 tapAmount,
137           uint256 multiplier
138:      );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L134-L138

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit function constructor came earlier
115:      event Participate(uint256 indexed epoch, uint256 aoTAPTokenID);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L115

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

/// @audit function constructor came earlier
45        modifier onlyBroker() {
46            require(msg.sender == broker, "AOTAP: only onlyBroker");
47            _;
48:       }

/// @audit modifier onlyBroker came earlier
53        event Mint(
54            address indexed to,
55            uint256 indexed tokenId,
56            AirdropTapOption option
57:       );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L45-L48

File: tap-token-audit/contracts/options/oTAP.sol

/// @audit function constructor came earlier
39        modifier onlyBroker() {
40            require(msg.sender == broker, "OTAP: only onlyBroker");
41            _;
42:       }

/// @audit modifier onlyBroker came earlier
47:       event Mint(address indexed to, uint256 indexed tokenId, TapOption option);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L39-L42

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit function constructor came earlier
100       event Participate(
101           uint256 indexed epoch,
102           uint256 indexed sglAssetID,
103           uint256 totalDeposited,
104           LockPosition lock,
105           uint256 discount
106:      );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L100-L106

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit function constructor came earlier
81        event Mint(
82            address indexed to,
83            uint128 indexed sglAssetID,
84            LockPosition lockPosition
85:       );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L81-L85

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit function A came earlier
31:       string public _name;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L31

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit function token came earlier
24:       string public _name;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L24

File: YieldBox/contracts/YieldBox.sol

/// @audit event Withdraw came earlier
88:       IWrappedNative public immutable wrappedNative;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L88

[N‑47] Control structures do not follow the Solidity Style Guide

See the control structures section of the Solidity Style Guide

There are 5 instances of this issue:

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

188               if (
189:                  balanceAfter - balanceBefore >= optionsData.paymentTokenAmount

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L188-L189

File: tapiocaz-audit/contracts/Balancer.sol

189           if (
190:              !_isValidOft(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L189-L190

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

203               if (
204:                  balanceAfter - balanceBefore >= optionsData.paymentTokenAmount

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L203-L204

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

314                   } else if (
315:                      _singularities[i] == sglAssetID && i < sglLastIndex

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L314-L315

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

611           if (
612:              !removeAndRepayData.assetWithdrawData.withdraw &&

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L611-L612

[N‑48] Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

While it doesn't save any gas because the compiler knows that developers often make this mistake, it's still best to use the right tool for the task at hand. There is a difference between constant variables and immutable variables, and they should each be used in their appropriate contexts. constants should be used for literal values written into the code, and immutable variables should be used for expressions, or values calculated in, or passed into the constructor.

There are 5 instances of this issue:

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

29        bytes32 private constant _PERMIT_TYPEHASH =
30            keccak256(
31                "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
32:           );

33        bytes32 private constant _PERMIT_TYPEHASH_BORROW =
34            keccak256(
35                "PermitBorrow(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
36:           );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L29-L32

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

38        bytes32 internal constant FLASH_MINT_CALLBACK_SUCCESS =
39:           keccak256("ERC3156FlashBorrower.onFlashLoan");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L38-L39

File: YieldBox/contracts/YieldBoxPermit.sol

27        bytes32 private constant _PERMIT_TYPEHASH =
28:           keccak256("Permit(address owner,address spender,uint256 assetId,uint256 nonce,uint256 deadline)");

31        bytes32 private constant _PERMIT_ALL_TYPEHASH =
32:           keccak256("PermitAll(address owner,address spender,uint256 nonce,uint256 deadline)");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L27-L28

[N‑49] Numeric values having to do with time should use time units for readability

There are units for seconds, minutes, hours, days, and weeks, and since they're defined, they should be used

There are 14 instances of this issue:

File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit 90000
148:          callerFee = 90000; // 90%

/// @audit 75000
149           protocolFee = 10000; // 10%
150:          collateralizationRate = 75000; // 75%

/// @audit 12000
167           borrowOpeningFee = 50; // 0.05%
168:          liquidationMultiplier = 12000; //12%

/// @audit 31536000
519           //update debt rate
520           uint256 annumDebtRate = getDebtRate();
521:          _accrueInfo.debtRate = uint64(annumDebtRate / 31536000); //per second

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L148

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit 12000
76        /// @notice liquidation multiplier used to compute liquidator rewards
77:       uint256 public liquidationMultiplier = 12000; //12%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L76-L77

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit 951293760
112:          minimumInterestPerSecond = 951293760; // approx 3% APR

/// @audit 7200e36
113           maximumInterestPerSecond = 2536783360; // approx 8% APR
114:          interestElasticity = 7200e36; // Half or double in 28800 seconds (1 hours) if linear

/// @audit 12000
126           //liquidation
127:          liquidationMultiplier = 12000; //12%

/// @audit 75000
126           //liquidation
127           liquidationMultiplier = 12000; //12%
128   
129:          collateralizationRate = 75000;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L112

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit 604800
48        /// @notice seconds in a week
49:       uint256 public constant WEEK = 604800;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L48-L49

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

/// @audit 300
317:      uint16 internal constant TOFT_WRAP = 300;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L317

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

/// @audit 3000
38:       uint24 public poolFee = 3000;

/// @audit 60
97:           (int24 tick, ) = OracleLibrary.consult(pool, 60);

/// @audit 60
126:          (int24 tick, ) = OracleLibrary.consult(pool, 60);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L38

[N‑50] Consider using delete rather than assigning zero/false to clear values

The delete keyword more closely matches the semantics of what is being done, and draws more attention to the changing of state, which may lead to a more thorough audit of its associated logic

There are 19 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

246:                  _yieldBoxShares[from][ASSET_SIG] = 0; //some assets accrue in time

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L246

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

51:               _yieldBoxShares[from][COLLATERAL_SIG] = 0; //accrues in time

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L51

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

467:          accrueInfo.feesEarnedFraction = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L467

File: tap-token-audit/contracts/governance/twTAP.sol

160:              participant.multiplier = 0;

293:                      pool.cumulative = 0;

547:                      pool.cumulative = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L160

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

395:          phase1Users[msg.sender] = 0;

470:          phase4Users[msg.sender] = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L395

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

256:                      pool.cumulative = 0;

318:                      pool.cumulative = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L256

File: tap-token-audit/contracts/Vesting.sol

138:          data.claimed = 0;

139:          data.revoked = false;

140:          data.latestClaimTimestamp = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L138

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

161:                  maxAmountsIn[i] = 0;

168:          joinPoolRequest.fromInternalBalance = false;

230:                  minAmountsOut[i] = 0;

237:          exitRequest.toInternalBalance = false;

281:              minAmountsOut[i] = 0;

287:          exitRequest.toInternalBalance = false;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L161

[N‑51] Contracts should have full test coverage

While 100% code coverage does not guarantee that there are no bugs, it often will catch easy-to-find bugs, and will ensure that there are fewer regressions when the code invariably has to be modified. Furthermore, in order to get full coverage, code authors will often have to re-organize their code so that it is more modular, so that each component can be tested separately, which reduces interdependencies between modules and layers, and makes for code that is easier to reason about and audit.

There are 6 instances of this issue:

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

File: Various Files

[N‑52] Large or complicated code bases should implement invariant tests

Large code bases, or code with lots of inline-assembly, complicated math, or complicated interactions between multiple contracts, should implement invariant fuzzing tests. Invariant fuzzers such as Echidna require the test writer to come up with invariants which should not be violated under any circumstances, and the fuzzer tests various inputs and function calls to ensure that the invariants always hold. Even code with 100% code coverage can still have bugs due to the order of the operations a user performs, and invariant fuzzers, with properly and extensively-written invariants, can close this testing gap significantly.

There are 6 instances of this issue:

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

File: Various Files

[N‑53] Enable IR-based code generation

By using --via-ir or {"viaIR": true}, the compiler is able to use more advanced multi-function optimizations, for extra gas savings.

There are 6 instances of this issue:

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

File: Various Files

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

File: Various Files

[N‑54] private functions not called by the contract should be removed

All dead code should be removed

There is one instance of this issue:

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

631       function _executeViewModule(
632           Module _module,
633           bytes memory _data
634:      ) private view returns (bytes memory returnData) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L631-L634

[N‑55] internal functions not called by the contract should be removed

All unused code should be removed

There is one instance of this issue:

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

254       function _getAmountForBorrowPart(
255           uint256 borrowPart
256:      ) internal view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L254-L256

[N‑56] Unused error definition

Note that there may be cases where an error superficially appears to be used, but this is only because there are multiple definitions of the error in different files. In such cases, the error definition should be moved into a separate file. The instances below are the unused definitions.

There is one instance of this issue:

File: contracts/TapiocaWrapper.sol

61:      error TapiocaWrapper__MngmtFeeTooHigh();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L61-L61

[N‑57] Contract names should use CamelCase

According to the Solidity style guide function names should be in CamelCase and should match their file names.

There is one instance of this issue:

File: contracts/tOFT/mTapiocaOFT.sol

9:   contract mTapiocaOFT is BaseTOFT {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L9-L9

[N‑58] Cast to bytes or bytes32 for clearer semantic meaning

Using a cast on a single argument, rather than abi.encodePacked() makes the intended operation more clear, leading to less reviewer confusion.

There are 2 instances of this issue:

File: contracts/Balancer.sol

291:             abi.encodePacked(connectedOFTs[_oft][_dstChainId].dstOft),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L291-L291

File: contracts/option-airdrop/AirdropBroker.sol

418:         bytes32 leaf = keccak256(abi.encodePacked(msg.sender));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L418-L418

[N‑59] Custom error has no error details

Consider adding parameters to the error to indicate which user or values caused the failure

There are 23 instances of this issue:

File: contracts/Balancer.sol

95:      error RouterNotValid();

97:      error ExceedsBalance();

99:      error DestinationNotValid();

101:     error SlippageNotValid();

103:     error FeeAmountNotSet();

104:     error PoolInfoRequired();

105:     error RebalanceAmountNotSet();

106:     error DestinationOftNotValid();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L95-L95

File: contracts/TapiocaWrapper.sol

59:      error TapiocaWrapper__FailedDeploy();

61:      error TapiocaWrapper__MngmtFeeTooHigh();

65:      error TapiocaWrapper__NoTOFTDeployed();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L59-L59

File: contracts/Vesting.sol

46:      error NotStarted();

47:      error NothingToClaim();

48:      error Initialized();

49:      error AddressNotValid();

50:      error AmountNotValid();

51:      error AlreadyRegistered();

52:      error NoTokens();

53:      error NotEnough();

54:      error BalanceTooLow();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L46-L46

File: contracts/Swapper/BaseSwapper.sol

16:      error AddressNotValid();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L16-L16

File: contracts/Swapper/CurveSwapper.sol

33:      error Undefined();

34:      error NotImplemented();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L33-L33

[N‑60] Variable names don't follow the Solidity style guide

For constant variable names, each word should use all capital letters, with underscores separating each word (CONSTANT_CASE)

There are 4 instances of this issue:

File: contracts/tokens/TapOFT.sol

45:      uint256 constant decay_rate = 8800000000000000; // 0.88%

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L45-L45

File: contracts/glp/GlpStrategy.sol

26:      string public constant override name = "sGLP";

27       string public constant override description =
28:          "Holds staked GLP tokens and compounds the rewards";

43       IUniswapV3Pool private constant gmxWethPool =
44:          IUniswapV3Pool(0x80A9ae39310abf666A87C743d6ebBD0E8C42158E);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L26-L26

[N‑61] Contracts containing only utility functions should be made into libraries

There are 2 instances of this issue:

File: contracts/twAML.sol

4    abstract contract FullMath {
5:       // https://xn--2-umb.com/21/muldiv/

111  abstract contract TWAML is FullMath {
112      /// @notice Compute the minimum weight to participate in the twAML voting mechanism
113      /// @param _totalWeight The total weight of the twAML system
114:     /// @param _minWeightFactor The minimum weight factor in BPS

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L4-L5

[N‑62] Unused struct definition

Note that there may be cases where a struct superficially appears to be used, but this is only because there are multiple definitions of the struct in different files. In such cases, the struct definition should be moved into a separate file. The instances below are the unused definitions.

There are 8 instances of this issue:

File: contracts/option-airdrop/AirdropBroker.sol

32   struct Phase2Info {
33       uint8[4] amountsPerUsers;
34       uint8[4] discountsPerUsers;
35:  }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L32-L35

File: contracts/Magnetar/MagnetarV2Storage.sol

116      struct WrapNativeData {
117          address to;
118:     }

120      struct TOFTSendAndBorrowData {
121          address from;
122          address to;
123          uint16 lzDstChainId;
124          bytes airdropAdapterParams;
125          ITapiocaOFT.IBorrowParams borrowParams;
126          ICommonData.IWithdrawParams withdrawParams;
127          ICommonData.ISendOptions options;
128          ICommonData.IApproval[] approvals;
129:     }

131      struct TOFTSendAndLendData {
132          address from;
133          address to;
134          uint16 lzDstChainId;
135          IUSDOBase.ILendOrRepayParams lendParams;
136          ICommonData.ISendOptions options;
137          ICommonData.IApproval[] approvals;
138:     }

150      struct TOFTRetrieveFromStrategyData {
151          address from;
152          uint256 amount;
153          uint256 share;
154          uint256 assetId;
155          uint16 lzDstChainId;
156          address zroPaymentAddress;
157          bytes airdropAdapterParam;
158:     }

196      struct HelperRemoveAssetData {
197          address market;
198          address user;
199          uint256 fraction;
200:     }

212      struct HelperBorrowData {
213          address market;
214          address user;
215          uint256 collateralAmount;
216          uint256 borrowAmount;
217          bool extractFromSender;
218          bool deposit;
219          bool withdraw;
220          bytes withdrawData;
221:     }

270      struct HelperMultiHopSell {
271          address from;
272          uint256 share;
273          IUSDOBase.ILeverageSwapData swapData;
274          IUSDOBase.ILeverageLZData lzData;
275          IUSDOBase.ILeverageExternalContractsData externalData;
276          bytes airdropAdapterParams;
277          ICommonData.IApproval[] approvals;
278:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L116-L118

[N‑63] if-statement can be converted to a ternary

The code can be made more compact while also increasing readability by converting the following if-statements to ternaries (e.g. foo += (x > y) ? a : b)

There are 6 instances of this issue:

File: contracts/governance/twTAP.sol

290                  if (pool.cumulative > pool.averageMagnitude) {
291                      pool.cumulative -= pool.averageMagnitude;
292                  } else {
293                      pool.cumulative = 0;
294:                 }

543              if (position.divergenceForce) {
544                  if (pool.cumulative > position.averageMagnitude) {
545                      pool.cumulative -= position.averageMagnitude;
546                  } else {
547                      pool.cumulative = 0;
548                  }
549              } else {
550                  pool.cumulative += position.averageMagnitude;
551:             }

544                  if (pool.cumulative > position.averageMagnitude) {
545                      pool.cumulative -= position.averageMagnitude;
546                  } else {
547                      pool.cumulative = 0;
548:                 }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L290-L294

File: contracts/options/TapiocaOptionBroker.sol

253                  if (pool.cumulative > pool.averageMagnitude) {
254                      pool.cumulative -= pool.averageMagnitude;
255                  } else {
256                      pool.cumulative = 0;
257:                 }

314              if (participation.divergenceForce) {
315                  if (pool.cumulative > pool.averageMagnitude) {
316                      pool.cumulative -= pool.averageMagnitude;
317                  } else {
318                      pool.cumulative = 0;
319                  }
320              } else {
321                  pool.cumulative += pool.averageMagnitude;
322:             }

315                  if (pool.cumulative > pool.averageMagnitude) {
316                      pool.cumulative -= pool.averageMagnitude;
317                  } else {
318                      pool.cumulative = 0;
319:                 }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L253-L257

[N‑64] Adding a return statement when the function defines a named return variable, is redundant

Once the return variable has been assigned (or has its default value), there is no need to explicitly return it at the end of the function, since it's returned automatically.

There are 3 instances of this issue:

File: tap-token-audit/contracts/governance/twTAP.sol

162:          return participant;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L162

File: tap-token-audit/contracts/twAML.sol

36:               return result;

105:          return result;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L36

[N‑65] 2**<n> - 1 should be re-written as type(uint<n>).max

Earlier versions of solidity can use uint<n>(-1) instead. Expressions not including the - 1 can often be re-written to accomodate the change (e.g. by using a > rather than a >=, which will also save some gas)

There is one instance of this issue:

File: tap-token-audit/contracts/governance/twTAP.sol

95:       uint256 constant DIST_PRECISION = 2 ** 128;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L95

[N‑66] require()/revert() statements should have descriptive reason strings

There are 2 instances of this issue:

File: tap-token-audit/contracts/twAML.sol

12:           require(denominator > 0);

44:           require(prod1 < denominator);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L12

[N‑67] Non-assembly method available

assembly{ id := chainid() } => uint256 id = block.chainid, assembly { size := extcodesize() } => uint256 size = address().code.length, assembly { hash := extcodehash() } => bytes32 hash = address().codehash
There are some automated tools that will flag a project as having higher complexity if there is inline-assembly, so it's best to avoid using it where it's not necessary

There are 2 instances of this issue:

File: tap-token-audit/contracts/governance/twTAP.sol

574:              chainId := chainid()

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L574

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

41:               addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L41

[N‑68] Missing event and or timelock for critical parameter change

Events help non-contract tools to track changes, and events prevent users from being surprised by changes

There are 5 instances of this issue:

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

318       function setPhase2MerkleRoots(
319           bytes32[4] calldata _merkleRoots
320       ) external onlyOwner {
321           phase2MerkleRoots = _merkleRoots;
322:      }

357       function setPaymentTokenBeneficiary(
358           address _paymentTokenBeneficiary
359       ) external onlyOwner {
360           paymentTokenBeneficiary = _paymentTokenBeneficiary;
361:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L318-L322

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

471       function setPaymentTokenBeneficiary(
472           address _paymentTokenBeneficiary
473       ) external onlyOwner {
474           paymentTokenBeneficiary = _paymentTokenBeneficiary;
475:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L471-L475

File: tap-token-audit/contracts/tokens/LTap.sol

53        function setLockedUntil(uint256 _lockedUntil) external onlyOwner {
54            require(_lockedUntil <= maxLockedUntil, "Too late");
55            lockedUntil = _lockedUntil;
56:       }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L53-L56

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

113       function setFeeRecipient(address recipient) external onlyOwner {
114           feeRecipient = recipient;
115:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L113-L115

[N‑69] Constructor visibility is ignored

Remove the public if using solidity at or above 0.7.0

There is one instance of this issue:

File: tap-token-audit/contracts/tokens/TapOFT.sol

107       constructor(
108           address _lzEndpoint,
109           address _contributors,
110           address _earlySupporters,
111           address _supporters,
112           address _lbp,
113           address _dao,
114           address _airdrop,
115           uint256 _governanceChainId,
116           address _conservator
117:      ) BaseTapOFT("TapOFT", "TAP", 8, _lzEndpoint) ERC20Permit("TapOFT") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L107-L117

[N‑70] Visibility should be set explicitly rather than defaulting to internal

There are 10 instances of this issue:

File: tap-token-audit/contracts/governance/twTAP.sol

81:       uint256 constant MIN_WEIGHT_FACTOR = 10; // In BPS, 0.1%

82:       uint256 constant dMAX = 100 * 1e4; // 10% - 100% voting power multiplier

83:       uint256 constant dMIN = 10 * 1e4;

95:       uint256 constant DIST_PRECISION = 2 ** 128;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L81

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

75:       uint256 constant MIN_WEIGHT_FACTOR = 10; // In BPS, 0.1%

76:       uint256 constant dMAX = 50 * 1e4; // 5% - 50% discount

77:       uint256 constant dMIN = 5 * 1e4;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L75

File: tap-token-audit/contracts/tokens/LTap.sol

24:       IERC20 tapToken;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L24

File: tap-token-audit/contracts/tokens/TapOFT.sol

45:       uint256 constant decay_rate = 8800000000000000; // 0.88%

46:       uint256 constant DECAY_RATE_DECIMAL = 1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L45

[N‑71] Memory-safe annotation preferred over comment variant

The memory-safe annotation (assembly ("memory-safe") { ... }), available starting in Solidity version 0.8.13 is preferred over the comment variant, which will be removed in a future breaking release. The comment variant is only meant for externalized library code that needs to work in earlier versions (e.g. SafeTransferLib needs to be able to be used in many different versions).

There are 2 instances of this issue:

File: contracts/TapiocaDeployer/TapiocaDeployer.sol

39           /// @solidity memory-safe-assembly
40           assembly {
41               addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
42:          }

72           /// @solidity memory-safe-assembly
73           assembly {
74               let ptr := mload(0x40) // Get free memory pointer
75   
76               // |                   | ↓ ptr ...  ↓ ptr + 0x0B (start) ...  ↓ ptr + 0x20 ...  ↓ ptr + 0x40 ...   |
77               // |-------------------|---------------------------------------------------------------------------|
78               // | bytecodeHash      |                                                        CCCCCCCCCCCCC...CC |
79               // | salt              |                                      BBBBBBBBBBBBB...BB                   |
80               // | deployer          | 000000...0000AAAAAAAAAAAAAAAAAAA...AA                                     |
81               // | 0xFF              |            FF                                                             |
82               // |-------------------|---------------------------------------------------------------------------|
83               // | memory            | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
84               // | keccak(start, 85) |            ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
85   
86               mstore(add(ptr, 0x40), bytecodeHash)
87               mstore(add(ptr, 0x20), salt)
88               mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
89               let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
90               mstore8(start, 0xff)
91               addr := keccak256(start, 85)
92:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L39-L42

[N‑72] Interfaces should be defined in separate files from their usage

The interfaces below should be defined in separate files, so that it's easier for future projects to import them, and to avoid duplication later on if they need to be used elsewhere in the project

There are 2 instances of this issue:

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

10   interface ICurvePool {
11       function coins(uint256 i) external view returns (address);
12   
13       function get_dy(
14           int128 i,
15           int128 j,
16           uint256 dx
17       ) external view returns (uint256);
18   
19       function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external;
20   
21       function get_virtual_price() external view returns (uint256);
22   
23       function gamma() external view returns (uint256);
24   
25       function A() external view returns (uint256);
26:  }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L10-L26

File: contracts/oracle/implementations/SGOracle.sol

7    interface IStargatePool {
8        function deltaCredit() external view returns (uint256);
9    
10       function totalLiquidity() external view returns (uint256);
11   
12       function totalSupply() external view returns (uint256);
13   
14       function decimals() external view returns (uint256);
15   
16       function localDecimals() external view returns (uint256);
17   
18       function token() external view returns (address);
19:  }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L7-L19

[N‑73] Duplicate import statements

There is one instance of this issue:

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

16:   import "../interfaces/ITapiocaOptionsBroker.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L16

[N‑74] Using >/>= without specifying an upper bound is unsafe

There will be breaking changes in future versions of solidity, and at that point your code will no longer be compatable. While you may have the specific version to use in a configuration file, others that include your source files may not.

There is one instance of this issue:

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

2:    pragma solidity >=0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L2

[N‑75] File is missing NatSpec

There are 4 instances of this issue:

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

File: YieldBox/contracts/BoringMath.sol

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol

File: YieldBox/contracts/YieldBoxURIBuilder.sol

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol

[N‑76] addresss shouldn't be hard-coded

It is often better to declare addresses as immutable, and assign them via constructor arguments. This allows the code to remain the same across deployments on different networks, and avoids recompilation when addresses need to change.

There is one instance of this issue:

File: contracts/glp/GlpStrategy.sol

44:          IUniswapV3Pool(0x80A9ae39310abf666A87C743d6ebBD0E8C42158E);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L44-L44

[N‑77] pragma experimental ABIEncoderV2 is deprecated

Use pragma abicoder v2 instead

There are 3 instances of this issue:

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

3:    pragma experimental ABIEncoderV2;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L3

File: YieldBox/contracts/YieldBoxRebase.sol

4:    pragma experimental ABIEncoderV2;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L4

File: YieldBox/contracts/YieldBox.sol

25:   pragma experimental ABIEncoderV2;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L25

[N‑78] Use scientific notation (e.g. 1e18) rather than exponentiation (e.g. 10**18)

While the compiler knows to optimize away the exponentiation, it's still better coding practice to use idioms that do not require compiler optimization, if they exist

There are 2 instances of this issue:

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

116:          uint256 invested = (shares * pricePerShare) / (10 ** 18);

146:              uint256 toWithdraw = (((amount - queued) * (10 ** 18)) /

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L116

[N‑79] else-block not required

One level of nesting can be removed by not having an else block when the if-block returns, and if (foo) { return 1; } else { return 2; } becomes if (foo) { return 1; } return 2;

There are 3 instances of this issue:

File: contracts/YieldBox.sol

487          if (tokenType == TokenType.Native) {
488              // If native token, register it as an ERC1155 asset (as that's what it is)
489              return depositAsset(registerAsset(TokenType.ERC1155, address(this), strategy, tokenId), from, to, amount, share);
490          } else {
491              return depositAsset(registerAsset(tokenType, contractAddress, strategy, tokenId), from, to, amount, share);
492:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L487-L492

File: contracts/YieldBoxURIBuilder.sol

30               } else if (asset.tokenType == TokenType.ERC1155) {
31                   return
32                       string(
33                           abi.encodePacked(
34                               string(
35                                   abi.encodePacked(
36                                       "ERC1155:",
37                                       uint256(uint160(asset.contractAddress)).toHexString(20),
38                                       "/",
39                                       asset.tokenId.toString()
40                                   )
41                               ),
42                               " (",
43                               asset.strategy.name(),
44                               ")"
45                           )
46                       );
47               } else {
48                   return string(abi.encodePacked(nativeName, " (", asset.strategy.name(), ")"));
49:              }

60               } else if (asset.tokenType == TokenType.ERC1155) {
61                   return string(abi.encodePacked("ERC1155", " (", asset.strategy.name(), ")"));
62               } else {
63                   return string(abi.encodePacked(nativeSymbol, " (", asset.strategy.name(), ")"));
64:              }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L30-L49

[N‑80] Use a more recent version of solidity

Use a solidity version of at least 0.8.12 to get string.concat() to be used instead of abi.encodePacked(<str>,<str>)

There is one instance of this issue:

File: YieldBox/contracts/YieldBoxURIBuilder.sol

2:    pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L2

[N‑81] Use a more recent version of solidity

Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions

There are 3 instances of this issue:

File: YieldBox/contracts/NativeTokenFactory.sol

2:    pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L2

File: YieldBox/contracts/YieldBoxPermit.sol

3:    pragma solidity ^0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L3

File: YieldBox/contracts/YieldBox.sol

24:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L24

[N‑82] Strings should use double quotes rather than single quotes

See the Solidity Style Guide

There are 7 instances of this issue:

File: YieldBox/contracts/YieldBoxURIBuilder.sol

106:                  ? abi.encodePacked(',"tokenAddress":"', uint256(uint160(asset.contractAddress)).toHexString(20), '"')

107:                  : abi.encodePacked(',"totalSupply":', totalSupply.toString(), ',"fixedSupply":', owner == address(0) ? "true" : "false")

117                               details.name,
118:                              '","symbol":"',

119                               details.symbol,
120:                              '"',

122                               asset.tokenType == TokenType.ERC1155 ? "" : details.decimals.toString(),
123:                              ',"properties":{"strategy":"',

124                               uint256(uint160(address(asset.strategy))).toHexString(20),
125:                              '","tokenType":"',

126                               details.tokenType,
127:                              '"',

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L106

Gas Optimizations

[G‑01] Reduce gas usage by moving to Solidity 0.8.19 or later

See this link for the full details

There are 68 instances of this issue:

see instances
File: contracts/Penrose.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L2-L2

File: contracts/markets/Market.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L2-L2

File: contracts/markets/MarketERC20.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L2-L2

File: contracts/markets/bigBang/BigBang.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L2-L2

File: contracts/markets/singularity/SGLBorrow.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L2-L2

File: contracts/markets/singularity/SGLCollateral.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L2-L2

File: contracts/markets/singularity/SGLCommon.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L2-L2

File: contracts/markets/singularity/SGLLendingCommon.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L2-L2

File: contracts/markets/singularity/SGLLeverage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L2-L2

File: contracts/markets/singularity/SGLLiquidation.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L2-L2

File: contracts/markets/singularity/SGLStorage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L2-L2

File: contracts/markets/singularity/Singularity.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L2-L2

File: contracts/usd0/BaseUSDO.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L2-L2

File: contracts/usd0/BaseUSDOStorage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L2-L2

File: contracts/usd0/USDO.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L2-L2

File: contracts/usd0/modules/USDOLeverageModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L2-L2

File: contracts/usd0/modules/USDOMarketModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L2-L2

File: contracts/usd0/modules/USDOOptionsModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L2-L2

File: contracts/Balancer.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L2-L2

File: contracts/TapiocaWrapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L2-L2

File: contracts/tOFT/BaseTOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L2-L2

File: contracts/tOFT/BaseTOFTStorage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L2-L2

File: contracts/tOFT/TapiocaOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L2-L2

File: contracts/tOFT/mTapiocaOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L2-L2

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L2-L2

File: contracts/Vesting.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L2-L2

File: contracts/governance/twTAP.sol

2:   pragma solidity 0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L2-L2

File: contracts/option-airdrop/AirdropBroker.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L2-L2

File: contracts/option-airdrop/aoTAP.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L2-L2

File: contracts/options/TapiocaOptionBroker.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L2-L2

File: contracts/options/TapiocaOptionLiquidityProvision.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L2-L2

File: contracts/options/oTAP.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L2-L2

File: contracts/tokens/BaseTapOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L2-L2

File: contracts/tokens/LTap.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L2-L2

File: contracts/tokens/TapOFT.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L2-L2

File: contracts/twAML.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L2-L2

File: contracts/Magnetar/MagnetarV2.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L2-L2

File: contracts/Magnetar/MagnetarV2Storage.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L2-L2

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L2-L2

File: contracts/Multicall/Multicall3.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L2-L2

File: contracts/Swapper/BaseSwapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L2-L2

File: contracts/Swapper/CurveSwapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L2-L2

File: contracts/Swapper/UniswapV2Swapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L2-L2

File: contracts/Swapper/UniswapV3Swapper.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L2-L2

File: contracts/TapiocaDeployer/TapiocaDeployer.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L2-L2

File: contracts/oracle/Seer.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L2-L2

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L2-L2

File: contracts/oracle/implementations/GLPOracle.sol

2:   pragma solidity >=0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L2-L2

File: contracts/oracle/implementations/SGOracle.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L2-L2

File: contracts/aave/AaveStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L2-L2

File: contracts/balancer/BalancerStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L2-L2

File: contracts/compound/CompoundStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L2-L2

File: contracts/convex/ConvexTricryptoStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L2-L2

File: contracts/curve/TricryptoLPStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L2-L2

File: contracts/curve/TricryptoNativeStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L2-L2

File: contracts/glp/GlpStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L2-L2

File: contracts/lido/LidoEthStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L2-L2

File: contracts/stargate/StargateStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L2-L2

File: contracts/yearn/YearnStrategy.sol

2:   pragma solidity ^0.8.18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L2-L2

File: contracts/BoringMath.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L2-L2

File: contracts/NativeTokenFactory.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L2-L2

File: contracts/YieldBox.sol

24:  pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L24-L24

File: contracts/YieldBoxPermit.sol

3:   pragma solidity ^0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L3-L3

File: contracts/YieldBoxRebase.sol

3:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L3-L3

File: contracts/YieldBoxURIBuilder.sol

2:   pragma solidity ^0.8.9;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L2-L2

[G‑02] Using bools for storage incurs overhead

    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27
Use uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas) for the extra SLOAD, and to avoid Gsset (20000 gas) when changing from false to true, after having been true in the past

There are 17 instances of this issue:

see instances
File: contracts/Penrose.sol

39:      bool public paused;

61:      mapping(address => bool) public isSingularityMasterContractRegistered;

63:      mapping(address => bool) public isBigBangMasterContractRegistered;

65:      mapping(address => bool) public isMarketRegistered;

71:      mapping(ISwapper => bool) public swappers;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L39-L39

File: contracts/markets/Market.sol

35:      bool public paused;

129:     bool internal initialized;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L35-L35

File: contracts/markets/bigBang/BigBang.sol

46:      mapping(address => mapping(address => bool)) public operators;

52:      bool private _isEthMarket;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L46-L46

File: contracts/usd0/BaseUSDOStorage.sol

25:      mapping(uint256 => mapping(address => bool)) public allowedMinter;

28:      mapping(uint256 => mapping(address => bool)) public allowedBurner;

30:      bool public paused;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L25-L25

File: contracts/tOFT/mTapiocaOFT.sol

17:      mapping(uint256 => bool) public connectedChains;

21:      mapping(address => bool) public balancers;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L17-L17

File: contracts/option-airdrop/AirdropBroker.sol

61:      mapping(address => mapping(uint256 => bool)) public userParticipation; // user address => phase => participated

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L61-L61

File: contracts/tokens/TapOFT.sol

70:      bool public paused;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L70-L70

File: contracts/Magnetar/MagnetarV2Storage.sol

29:      mapping(address => mapping(address => bool)) public isApprovedForAll;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L29-L29

[G‑03] Avoid updating storage when the value hasn't changed

If the old value is equal to the new value, not re-storing the value will avoid a Gsreset (2900 gas), potentially at the expense of a Gcoldsload (2100 gas) or a Gwarmaccess (100 gas)

There are 26 instances of this issue:

see instances
File: contracts/Penrose.sol

256      function setBigBangEthMarketDebtRate(uint256 _rate) external onlyOwner {
257          bigBangEthDebtRate = _rate;
258          emit BigBangEthMarketDebtRate(_rate);
259:     }

263      function setBigBangEthMarket(address _market) external onlyOwner {
264          bigBangEthMarket = _market;
265          emit BigBangEthMarketSet(_market);
266:     }

455      function setFeeTo(address feeTo_) external onlyOwner {
456          feeTo = feeTo_;
457          emit FeeToUpdate(feeTo_);
458:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L256-L259

File: contracts/markets/Market.sol

142      function setBorrowOpeningFee(uint256 _val) external onlyOwner {
143          require(_val <= FEE_PRECISION, "Market: not valid");
144          emit LogBorrowingFee(borrowOpeningFee, _val);
145          borrowOpeningFee = _val;
146:     }

151      function setBorrowCap(uint256 _cap) external notPaused onlyOwner {
152          emit LogBorrowCapUpdated(totalBorrowCap, _cap);
153          totalBorrowCap = _cap;
154:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L142-L146

File: contracts/markets/singularity/Singularity.sol

489      function setSingularityConfig(
490          uint256 _lqCollateralizationRate,
491          uint256 _liquidationMultiplier,
492          uint256 _minimumTargetUtilization,
493          uint256 _maximumTargetUtilization,
494          uint64 _minimumInterestPerSecond,
495          uint64 _maximumInterestPerSecond,
496          uint256 _interestElasticity
497      ) external onlyOwner {
498          if (_minimumTargetUtilization > 0) {
499              emit MinimumTargetUtilizationUpdated(
500                  minimumTargetUtilization,
501                  _minimumTargetUtilization
502              );
503              minimumTargetUtilization = _minimumTargetUtilization;
504          }
505  
506          if (_maximumTargetUtilization > 0) {
507              require(
508                  _maximumTargetUtilization < FULL_UTILIZATION,
509                  "SGL: not valid"
510              );
511              emit MaximumTargetUtilizationUpdated(
512                  maximumTargetUtilization,
513                  _maximumTargetUtilization
514              );
515              maximumTargetUtilization = _maximumTargetUtilization;
516              fullUtilizationMinusMax =
517                  FULL_UTILIZATION -
518                  maximumTargetUtilization;
519          }
520  
521          if (_minimumInterestPerSecond > 0) {
522              require(
523                  _minimumInterestPerSecond < maximumInterestPerSecond,
524                  "SGL: not valid"
525              );
526              emit MinimumInterestPerSecondUpdated(
527                  minimumInterestPerSecond,
528                  _minimumInterestPerSecond
529              );
530              minimumInterestPerSecond = _minimumInterestPerSecond;
531          }
532  
533          if (_maximumInterestPerSecond > 0) {
534              require(
535                  _maximumInterestPerSecond > minimumInterestPerSecond,
536                  "SGL: not valid"
537              );
538              emit MaximumInterestPerSecondUpdated(
539                  maximumInterestPerSecond,
540                  _maximumInterestPerSecond
541              );
542              maximumInterestPerSecond = _maximumInterestPerSecond;
543          }
544  
545          if (_interestElasticity > 0) {
546              emit InterestElasticityUpdated(
547                  interestElasticity,
548                  _interestElasticity
549              );
550              interestElasticity = _interestElasticity;
551          }
552  
553          if (_lqCollateralizationRate > 0) {
554              require(
555                  _lqCollateralizationRate <= FEE_PRECISION,
556                  "SGL: not valid"
557              );
558              emit LqCollateralizationRateUpdated(
559                  lqCollateralizationRate,
560                  _lqCollateralizationRate
561              );
562              lqCollateralizationRate = _lqCollateralizationRate;
563          }
564  
565          if (_liquidationMultiplier > 0) {
566              require(_liquidationMultiplier < FEE_PRECISION, "SGL: not valid");
567              emit LiquidationMultiplierUpdated(
568                  liquidationMultiplier,
569                  _liquidationMultiplier
570              );
571              liquidationMultiplier = _liquidationMultiplier;
572          }
573:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L489-L573

File: contracts/usd0/BaseUSDO.sol

88       function setMaxFlashMintable(uint256 _val) external onlyOwner {
89           emit MaxFlashMintUpdated(maxFlashMint, _val);
90           maxFlashMint = _val;
91:      }

96       function setFlashMintFee(uint256 _val) external onlyOwner {
97           require(_val < FLASH_MINT_FEE_PRECISION, "USDO: fee too big");
98           emit FlashMintFeeUpdated(flashMintFee, _val);
99           flashMintFee = _val;
100:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L88-L91

File: contracts/option-airdrop/AirdropBroker.sol

308      function setTapOracle(
309          IOracle _tapOracle,
310          bytes calldata _tapOracleData
311      ) external onlyOwner {
312          tapOracle = _tapOracle;
313          tapOracleData = _tapOracleData;
314  
315          emit SetTapOracle(_tapOracle, _tapOracleData);
316:     }

318      function setPhase2MerkleRoots(
319          bytes32[4] calldata _merkleRoots
320      ) external onlyOwner {
321          phase2MerkleRoots = _merkleRoots;
322:     }

357      function setPaymentTokenBeneficiary(
358          address _paymentTokenBeneficiary
359      ) external onlyOwner {
360          paymentTokenBeneficiary = _paymentTokenBeneficiary;
361:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L308-L316

File: contracts/options/TapiocaOptionBroker.sol

446      function setTapOracle(
447          IOracle _tapOracle,
448          bytes calldata _tapOracleData
449      ) external onlyOwner {
450          tapOracle = _tapOracle;
451          tapOracleData = _tapOracleData;
452  
453          emit SetTapOracle(_tapOracle, _tapOracleData);
454:     }

471      function setPaymentTokenBeneficiary(
472          address _paymentTokenBeneficiary
473      ) external onlyOwner {
474          paymentTokenBeneficiary = _paymentTokenBeneficiary;
475:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L446-L454

File: contracts/tokens/LTap.sol

53       function setLockedUntil(uint256 _lockedUntil) external onlyOwner {
54           require(_lockedUntil <= maxLockedUntil, "Too late");
55           lockedUntil = _lockedUntil;
56:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L53-L56

File: contracts/tokens/TapOFT.sol

140      function setGovernanceChainIdentifier(
141          uint256 _identifier
142      ) external onlyOwner {
143          emit GovernanceChainIdentifierUpdated(
144              governanceChainIdentifier,
145              _identifier
146          );
147          governanceChainIdentifier = _identifier;
148:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L140-L148

File: contracts/Swapper/UniswapV3Swapper.sol

61       function setPoolFee(uint24 _newFee) external onlyOwner {
62           emit PoolFee(poolFee, _newFee);
63           poolFee = _newFee;
64:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L61-L64

File: contracts/aave/AaveStrategy.sol

122      function setDepositThreshold(uint256 amount) external onlyOwner {
123          emit DepositThreshold(depositThreshold, amount);
124          depositThreshold = amount;
125:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L122-L125

File: contracts/balancer/BalancerStrategy.sol

109      function setDepositThreshold(uint256 amount) external onlyOwner {
110          emit DepositThreshold(depositThreshold, amount);
111          depositThreshold = amount;
112:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L109-L112

File: contracts/compound/CompoundStrategy.sol

89       function setDepositThreshold(uint256 amount) external onlyOwner {
90           emit DepositThreshold(depositThreshold, amount);
91           depositThreshold = amount;
92:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L89-L92

File: contracts/convex/ConvexTricryptoStrategy.sol

163      function setDepositThreshold(uint256 amount) external onlyOwner {
164          emit DepositThreshold(depositThreshold, amount);
165          depositThreshold = amount;
166:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L163-L166

File: contracts/curve/TricryptoLPStrategy.sol

134      function setDepositThreshold(uint256 amount) external onlyOwner {
135          emit DepositThreshold(depositThreshold, amount);
136          depositThreshold = amount;
137:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L134-L137

File: contracts/curve/TricryptoNativeStrategy.sol

125      function setDepositThreshold(uint256 amount) external onlyOwner {
126          emit DepositThreshold(depositThreshold, amount);
127          depositThreshold = amount;
128:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L125-L128

File: contracts/glp/GlpStrategy.sol

113      function setFeeRecipient(address recipient) external onlyOwner {
114          feeRecipient = recipient;
115:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L113-L115

File: contracts/lido/LidoEthStrategy.sol

93       function setDepositThreshold(uint256 amount) external onlyOwner {
94           emit DepositThreshold(depositThreshold, amount);
95           depositThreshold = amount;
96:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L93-L96

File: contracts/stargate/StargateStrategy.sol

142      function setDepositThreshold(uint256 amount) external onlyOwner {
143          emit DepositThreshold(depositThreshold, amount);
144          depositThreshold = amount;
145:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L142-L145

File: contracts/yearn/YearnStrategy.sol

90       function setDepositThreshold(uint256 amount) external onlyOwner {
91           emit DepositThreshold(depositThreshold, amount);
92           depositThreshold = amount;
93:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L90-L93

[G‑04] unchecked {} can be used on the division of two uints in order to save gas

The division cannot overflow, since both the numerator and the denominator are non-negative

There are 76 instances of this issue:

see instances
File: contracts/markets/Market.sol

265:             borrowPartScaled = borrowPart / (10 ** (borrowPartDecimals - 18));

274                  collateralPartInAsset /
275:                 (10 ** (collateralPartDecimals - 18));

283          uint256 liquidationStartsAt = (collateralPartInAssetScaled *
284:             collateralizationRate) / (10 ** ratesPrecision);

288              ((collateralizationRate * collateralPartInAssetScaled) /
289:                 (10 ** ratesPrecision));

291              (collateralizationRate *
292                  ((10 ** ratesPrecision) + liquidationMultiplier)) /
293:             (10 ** ratesPrecision)) * (10 ** (18 - ratesPrecision));

295:         uint256 x = (numerator * 1e18) / denominator;

390              yieldBox.toAmount(
391                  collateralId,
392                  (userCollateralShare[user] *
393                      (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
394                      collateralizationRate),
395                  false
396              ) /
397:             _exchangeRate;

393:                     (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

418:                     (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

438:         max = (collateralAmount * EXCHANGE_RATE_PRECISION) / _exchangeRate;

439:         min = (max * collateralizationRate) / FEE_PRECISION;

453          uint256 rewardPercentage = ((borrowed - startTVLInAsset) *
454:             FEE_PRECISION) / (maxTVLInAsset - startTVLInAsset);

477:         return (shareRatio * userCollateralShare[user]) / (10 ** assetDecimals);

489:         uint256 _quotient = ((_numerator / denominator) + 5) / 10;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L265-L265

File: contracts/markets/bigBang/BigBang.sol

192          uint256 debtPercentage = ((_currentDebt - debtStartPoint) *
193:             DEBT_PRECISION) / (_maxDebtPoint - debtStartPoint);

194          uint256 debt = ((maxDebtRate - minDebtRate) * debtPercentage) /
195:             DEBT_PRECISION +

645:         feeShare = (extraShare * protocolFee) / FEE_PRECISION; // x% of profit goes to fee.

646:         callerShare = (extraShare * callerReward) / FEE_PRECISION; //  y%  of profit goes to caller.

747:         uint256 feeAmount = (amount * borrowOpeningFee) / FEE_PRECISION; // A flat % fee is charged for any borrow

781          uint256 collateralPartInAsset = (yieldBox.toAmount(
782              collateralId,
783              userCollateralShare[user],
784              false
785:         ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;

809              (borrowAmount * liquidationMultiplier) /
810:             FEE_PRECISION;

813:             (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L192-L193

File: contracts/markets/singularity/SGLCommon.sol

63               : (uint256(_totalBorrow.elastic) * UTILIZATION_PRECISION) /
64:                  fullAssetAmount;

106:         uint256 feeAmount = (extraAmount * protocolFee) / FEE_PRECISION; // % of interest paid goes to fee

107:         feeFraction = (feeAmount * _totalAsset.base) / fullAssetAmount;

125              uint256 overFactor = ((utilization - maximumTargetUtilization) *
126:                 FACTOR_PRECISION) / fullUtilizationMinusMax;

129              uint256 newInterestPerSecond = (uint256(
130                  _accrueInfo.interestPerSecond
131:             ) * scale) / interestElasticity;

113              uint256 underFactor = ((minimumTargetUtilization - utilization) *
114:                 FACTOR_PRECISION) / minimumTargetUtilization;

118                  (uint256(_accrueInfo.interestPerSecond) * interestElasticity) /
119:                     scale

209:             : (share * _totalAsset.base) / allShare;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L63-L64

File: contracts/markets/singularity/SGLLendingCommon.sol

63:          uint256 feeAmount = (amount * borrowOpeningFee) / FEE_PRECISION; // A flat % fee is charged for any borrow

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L63-L63

File: contracts/markets/singularity/SGLLiquidation.sol

81           uint256 collateralAmountInAsset = yieldBox.toAmount(
82               collateralId,
83               (collateralShare *
84                   (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *
85                   lqCollateralizationRate),
86               false
87:          ) / _exchangeRate;

84:                  (EXCHANGE_RATE_PRECISION / FEE_PRECISION) *

126                      (borrowAmount * liquidationMultiplier) /
127:                     FEE_PRECISION;

130:                     (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

182:         uint256 callerShare = (extraShare * callerFee) / FEE_PRECISION; // 1% goes to caller

216          uint256 collateralPartInAsset = (yieldBox.toAmount(
217              collateralId,
218              userCollateralShare[user],
219              false
220:         ) * EXCHANGE_RATE_PRECISION) / _exchangeRate;

236                  (availableBorrowPart * liquidationBonusAmount) /
237:                 FEE_PRECISION;

253              (borrowAmount * liquidationMultiplier) /
254:             FEE_PRECISION;

257:             (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

278:         feeShare = (extraShare * protocolFee) / FEE_PRECISION; // x% of profit goes to fee.

279:         callerShare = (extraShare * callerReward) / FEE_PRECISION; //  y%  of profit goes to caller.

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L81-L87

File: contracts/usd0/USDO.sol

69:          return (amount * flashMintFee) / FLASH_MINT_FEE_PRECISION;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L69-L69

File: contracts/Balancer.sol

339:         return _amount - ((_amount * _slippage) / SLIPPAGE_PRECISION);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L339-L339

File: contracts/Vesting.sol

172:         return (total * (block.timestamp - start)) / duration;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L172-L172

File: contracts/governance/twTAP.sol

151:         return (block.timestamp - creation) / EPOCH_DURATION;

236:             result[i] = ((votes * net) / DIST_PRECISION) - claimed[_tokenId][i];

280                  (pool.averageMagnitude + magnitude) /
281:                 pool.totalParticipants; // compute new average magnitude

323:         uint256 w1 = (expiry - creation) / EPOCH_DURATION;

446              (_amount * DIST_PRECISION) /
447:             uint256(totals.netActiveVotes);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L151-L151

File: contracts/option-airdrop/AirdropBroker.sol

530:         uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

535:         paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L530-L530

File: contracts/options/TapiocaOptionBroker.sol

245                  (pool.averageMagnitude + magnitude) /
246:                 pool.totalParticipants; // compute new average magnitude

551:         uint256 rawPaymentAmount = _otcAmountInUSD / _paymentTokenValuation;

555:         paymentAmount = paymentAmount / (10 ** (18 - _paymentTokenDecimals));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L245-L246

File: contracts/tokens/TapOFT.sol

242:         return ((timestamp - emissionsStartTime) / WEEK) + 1; // Starts at week 1

254:         result = (dso_supply * decay_rate) / DECAY_RATE_DECIMAL;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L242-L242

File: contracts/twAML.sol

141:         uint256 target = (_magnitude * _dMax) / _cumulative;

153:                 x = (y / x + x) / 2;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L141-L141

File: contracts/Magnetar/MagnetarV2.sol

105                  (borrowAmount *
106                      market.liquidationMultiplier() *
107                      market.exchangeRate()) /
108:                     (liquidationMultiplierPrecision * exchangeRatePrecision),

186:         fraction = allShare == 0 ? share : (share * totalAssetBase) / allShare;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L105-L108

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

135:         uint256 _g = (TRI_CRYPTO.gamma() * 1 ether) / GAMMA0;

136:         uint256 _a = (TRI_CRYPTO.A() * 1 ether) / A0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L135-L135

File: contracts/oracle/implementations/SGOracle.sol

50           uint256 lpPrice = (SG_POOL.totalLiquidity() *
51:              uint256(UNDERLYING.latestAnswer())) / SG_POOL.totalSupply();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L50-L51

File: contracts/balancer/BalancerStrategy.sol

202              uint256 toWithdraw = (((amount - queued) * (10 ** decimals)) /
203:                 pricePerShare);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L202-L203

File: contracts/compound/CompoundStrategy.sol

146              uint256 toWithdraw = (((amount - queued) * (10 ** 18)) /
147:                 pricePerShare);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L146-L147

File: contracts/glp/GlpStrategy.sol

207          uint256 minTokenReserve = ((vestingNow + vestable) * avgTokenStake) /
208:             totalVestable;

244                  (totalVestable * tokenAvailable) /
245:                 avgTokenStake -

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L207-L208

File: contracts/yearn/YearnStrategy.sol

114:         uint256 invested = (shares * pricePerShare) / (10 ** vault.decimals());

142              uint256 toWithdraw = (((amount - queued) *
143:                 (10 ** vault.decimals())) / pricePerShare);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L114-L114

File: contracts/BoringMath.sol

26:          result = (value * mul) / div;

27:          if (roundUp && (result * div) / mul < value) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L26-L26

File: contracts/YieldBoxRebase.sol

32:          share = (amount * totalShares_) / totalAmount;

35:          if (roundUp && (share * totalAmount) / totalShares_ < amount) {

55:          amount = (share * totalAmount) / totalShares_;

58:          if (roundUp && (amount * totalShares_) / totalAmount < share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L32-L32

[G‑05] Remove or replace unused state variables

Saves a storage slot. If the variable is assigned a non-zero value, saves Gsset (20000 gas). If it's assigned a zero value, saves Gsreset (2900 gas). If the variable remains unassigned, there is no gas savings unless the variable is public, in which case the compiler-generated non-payable getter deployment cost is saved. If the state variable is overriding an interface's public function, mark the variable as constant or immutable so that it does not use a storage slot

There are 3 instances of this issue:

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

45:       bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L45

File: tap-token-audit/contracts/governance/twTAP.sol

112:      string private baseURI;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L112

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

41:       address[] public rewardTokens;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L41

[G‑06] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, where appropriate

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot. Finally, if both fields are accessed in the same function, can save ~42 gas per access due to not having to recalculate the key's keccak256 hash (Gkeccak256 - 30 gas) and that calculation's associated stack operations.

There are 10 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

48        mapping(address => uint256) public override balanceOf;
49        /// @notice owner > spender > allowance mapping.
50        mapping(address => mapping(address => uint256)) public override allowance;
51        /// @notice owner > spender > allowance mapping.
52        mapping(address => mapping(address => uint256)) public allowanceBorrow;
53        /// @notice owner > nonce mapping. Used in `permit`.
54:       mapping(address => uint256) private _nonces;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L48-L54

File: tapioca-bar-audit/contracts/markets/Market.sol

57        mapping(address => uint256) public userBorrowPart;
58        /// @notice collateral share per user
59:       mapping(address => uint256) public userCollateralShare;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L57-L59

File: tapioca-bar-audit/contracts/Penrose.sol

61        mapping(address => bool) public isSingularityMasterContractRegistered;
62        // Used to check if a BigBang master contract is registered
63        mapping(address => bool) public isBigBangMasterContractRegistered;
64        // Used to check if a SGL/BB is a real market
65:       mapping(address => bool) public isMarketRegistered;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L61-L65

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

25        mapping(uint256 => mapping(address => bool)) public allowedMinter;
26        /// @notice addresses allowed to burn USDO
27        /// @dev chainId>address>status
28:       mapping(uint256 => mapping(address => bool)) public allowedBurner;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L25-L28

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

57        mapping(uint256 => mapping(uint256 => uint256)) public aoTAPCalls; // oTAPTokenID => epoch => amountExercised
58    
59        /// @notice Record of participation in phase 2 airdrop
60        /// Only applicable for phase 2. To get subphases on phase 2 we do userParticipation[_user][20+roles]
61        mapping(address => mapping(uint256 => bool)) public userParticipation; // user address => phase => participated
62    
63        /// =====-------======
64        ///      Phase 1
65        /// =====-------======
66    
67        /// @notice user address => eligible TAP amount, 0 means no eligibility
68:       mapping(address => uint256) public phase1Users;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L57-L68

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

36        mapping(uint256 => AirdropTapOption) public options; // tokenId => Option
37:       mapping(uint256 => string) public tokenURIs; // tokenId => tokenURI

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L36-L37

File: tap-token-audit/contracts/options/oTAP.sol

34        mapping(uint256 => TapOption) public options; // tokenId => Option
35:       mapping(uint256 => string) public tokenURIs; // tokenId => tokenURI

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L34-L35

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

64        mapping(uint256 => Participation) public participants; // tOLPTokenID => Participation
65        mapping(uint256 => mapping(uint256 => uint256)) public oTAPCalls; // oTAPTokenID => epoch => amountExercised
66    
67:       mapping(uint256 => mapping(uint256 => uint256)) public singularityGauges; // epoch => sglAssetId => availableTAP

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L64-L67

File: tap-token-audit/contracts/tokens/TapOFT.sol

57        mapping(uint256 => uint256) public emissionForWeek;
58    
59        /// @notice returns the amount minted for a specific week
60        /// @dev week is computed using (timestamp - emissionStartTime) / WEEK
61:       mapping(uint256 => uint256) public mintedInWeek;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L57-L61

File: YieldBox/contracts/NativeTokenFactory.sol

24        mapping(uint256 => NativeToken) public nativeTokens;
25        mapping(uint256 => address) public owner;
26:       mapping(uint256 => address) public pendingOwner;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L24-L26

[G‑07] State variables only set in the constructor should be declared immutable

Avoids a Gsset (20000 gas) in the constructor, and replaces the first access in each transaction (Gcoldsload - 2100 gas) and each access thereafter (Gwarmacces - 100 gas) with a PUSH32 (3 gas).

While strings are not value types, and therefore cannot be immutable/constant if not hard-coded outside of the constructor, the same behavior can be achieved by making the current contract abstract with virtual functions for the string accessors, and having a child contract override the functions with the hard-coded implementation-specific values.

There are 27 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit leverageModule (constructor)
75:           leverageModule = USDOLeverageModule(_leverageModule);

/// @audit marketModule (constructor)
76:           marketModule = USDOMarketModule(_marketModule);

/// @audit optionsModule (constructor)
77:           optionsModule = USDOOptionsModule(_optionsModule);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L75

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit leverageModule (constructor)
74:           leverageModule = BaseTOFTLeverageModule(_leverageModule);

/// @audit strategyModule (constructor)
75:           strategyModule = BaseTOFTStrategyModule(_strategyModule);

/// @audit marketModule (constructor)
76:           marketModule = BaseTOFTMarketModule(_marketModule);

/// @audit optionsModule (constructor)
77:           optionsModule = BaseTOFTOptionsModule(_optionsModule);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L74

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit creation (constructor)
127:          creation = block.timestamp;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L127

File: tap-token-audit/contracts/tokens/LTap.sol

/// @audit tapToken (constructor)
36:           tapToken = _tapToken;

/// @audit maxLockedUntil (constructor)
38:           maxLockedUntil = _maxLockedUntil;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L36

File: tap-token-audit/contracts/Vesting.sol

/// @audit cliff (constructor)
70:           cliff = _cliff;

/// @audit duration (constructor)
71:           duration = _duration;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L70

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit marketModule (constructor)
46:           marketModule = MagnetarMarketModule(_marketModule);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L46

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit _name (constructor)
53:           _name = __name;

/// @audit _symbol (constructor)
54:           _symbol = __symbol;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L53

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit _name (constructor)
36:           _name = __name;

/// @audit _symbol (constructor)
37:           _symbol = __symbol;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L36

File: tapioca-periph-audit/contracts/oracle/Seer.sol

/// @audit _name (constructor)
42:           _name = __name;

/// @audit _symbol (constructor)
43:           _symbol = __symbol;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L42

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit curvePool (constructor)
40:           curvePool = _curvePool;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L40

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit poolId (constructor)
70:           poolId = _poolId;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L70

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit curveStEthPool (constructor)
60:           curveStEthPool = ICurveEthStEthPool(_curvePool);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L60

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit stgEthPool (constructor)
79:           stgEthPool = _stgEthPool;

/// @audit lpStakingPid (constructor)
83:           lpStakingPid = _stakingPid;

/// @audit lpRouterPid (constructor)
86:           lpRouterPid = addLiquidityRouter.poolId();

/// @audit stgNative (constructor)
88:           stgNative = IERC20(_lpToken);

/// @audit stgTokenReward (constructor)
92:           stgTokenReward = IERC20(lpStaking.stargate());

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L79

@thebrittfactor
Copy link

[G‑08] State variables can be packed into fewer storage slots

If variables occupying the same slot are both written the same function or by the constructor, avoids a separate Gsset (20000 gas). Reads of the variables can also be cheaper

There are 6 instances of this issue:

File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit Variable ordering with 7 slots instead of the current 8:
///           mapping(32):operators, uint256(32):totalFees, uint256(32):maxDebtRate, uint256(32):minDebtRate, uint256(32):debtRateAgainstEthMarket, uint256(32):debtStartPoint, user-defined(20):accrueInfo, bool(1):_isEthMarket
46:       mapping(address => mapping(address => bool)) public operators;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L46

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit Variable ordering with 24 slots instead of the current 25:
///           uint256(32):collateralId, uint256(32):assetId, bytes(32):oracleData, uint256(32):exchangeRate, uint256(32):totalCollateralShare, uint256(32):totalBorrowCap, mapping(32):userBorrowPart, mapping(32):userCollateralShare, uint256(32):callerFee, uint256(32):protocolFee, uint256(32):minLiquidatorReward, uint256(32):maxLiquidatorReward, uint256(32):liquidationBonusAmount, uint256(32):collateralizationRate, uint256(32):borrowOpeningFee, uint256(32):liquidationMultiplier, uint256(32):EXCHANGE_RATE_PRECISION, user-defined(20):yieldBox, bool(1):paused, bool(1):initialized, user-defined(20):penrose, user-defined(20):collateral, user-defined(20):asset, address(20):conservator, user-defined(20):oracle, user-defined(20):totalBorrow
21:       YieldBox public yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L21

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

/// @audit Variable ordering with 11 slots instead of the current 13:
///           mapping(32):_yieldBoxShares, bytes32(32):ASSET_SIG, bytes32(32):COLLATERAL_SIG, uint256(32):lqCollateralizationRate, uint256(32):minimumTargetUtilization, uint256(32):maximumTargetUtilization, uint256(32):fullUtilizationMinusMax, uint256(32):interestElasticity, user-defined(20):accrueInfo, uint64(8):minimumInterestPerSecond, user-defined(20):totalAsset, uint64(8):maximumInterestPerSecond, user-defined(20):liquidationQueue, uint64(8):startingInterestPerSecond
42:       ISingularity.AccrueInfo public accrueInfo;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L42

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

/// @audit Variable ordering with 5 slots instead of the current 6:
///           mapping(32):allowedMinter, mapping(32):allowedBurner, uint256(32):flashMintFee, uint256(32):maxFlashMint, address(20):conservator, bool(1):paused
22:       address public conservator;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L22

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

/// @audit Variable ordering with 3 slots instead of the current 4:
///           uint256(32):hostChainID, user-defined(20):yieldBox, uint8(1):_decimalCache, address(20):erc20
26:       IYieldBoxBase public yieldBox;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L26

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit Variable ordering with 5 slots instead of the current 6:
///           uint256(32):dso_supply, mapping(32):emissionForWeek, mapping(32):mintedInWeek, uint256(32):governanceChainIdentifier, address(20):minter, bool(1):paused
42:       uint256 public dso_supply = 53_313_405 * 1e18;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L42

[G‑09] Using storage instead of memory for structs/arrays saves gas

When fetching data from a storage location, assigning the data to a memory variable causes all fields of the struct/array to be read from storage, which incurs a Gcoldsload (2100 gas) for each field of the struct/array. If the fields are read from the new memory variable, they incur an additional MLOAD rather than a cheap stack read. Instead of declearing the variable with the memory keyword, declaring the variable with the storage keyword and caching any fields that need to be re-read in stack variables, will be much cheaper, only incuring the Gcoldsload for the fields actually read. The only time it makes sense to read the whole struct/array into a memory variable, is if the full struct/array is being returned by the function, is being passed to a function that requires memory, or if the array/struct is being read from another memory array/struct

There are 18 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

513:          IBigBang.AccrueInfo memory _accrueInfo = accrueInfo;

525:          Rebase memory _totalBorrow = totalBorrow;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L513

File: tapioca-bar-audit/contracts/markets/Market.sol

316:          Rebase memory _totalBorrow = totalBorrow;

412:          Rebase memory _totalBorrow = totalBorrow;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L316

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

203:          Rebase memory _totalAsset = totalAsset;

232:          Rebase memory _totalAsset = totalAsset;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L203

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

74:           Rebase memory _totalAsset = totalAsset;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L74

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

79:           Rebase memory _totalBorrow = totalBorrow;

105:          Rebase memory _totalBorrow = totalBorrow;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L79

File: tap-token-audit/contracts/governance/twTAP.sol

263:          TWAMLPool memory pool = twAML;

536:              TWAMLPool memory pool = twAML;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L263

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

222:          TWAMLPool memory pool = twAML[lock.sglAssetID];

308:          Participation memory participation = participants[oTAPPosition.tOLP];

312:              TWAMLPool memory pool = twAML[lock.sglAssetID];

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L222

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

131:          uint256[] memory _singularities = singularities;

304:              uint256[] memory _singularities = singularities;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L131

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

48:               Result memory result = returnData[i];

71:               Result memory result = returnData[i];

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L48

[G‑10] State variables should be cached in stack variables rather than re-reading them from storage

The instances below point to the second+ access of a state variable within a function. Caching of a state variable replaces each Gwarmaccess (100 gas) with a much cheaper stack read. Other less obvious fixes/optimizations include having local memory caches of state variable structs, or having local caches of state variable contracts/addresses.

There are 156 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit totalFees on line 446
447:          feeShares = yieldBox.toShare(assetId, totalFees, false);

/// @audit totalFees on line 447
449:          if (totalFees > 0) {

/// @audit totalFees on line 449
450:              asset.approve(address(yieldBox), totalFees);

/// @audit totalFees on line 450
456:                  totalFees,

/// @audit _isEthMarket on line 156
157:          if (!_isEthMarket) {

/// @audit _isEthMarket on line 472
474:          if (!_isEthMarket) {

/// @audit maxDebtRate on line 190
194:          uint256 debt = ((maxDebtRate - minDebtRate) * debtPercentage) /

/// @audit maxDebtRate on line 194
/// @audit maxDebtRate on line 198
198:          if (debt > maxDebtRate) return maxDebtRate;

/// @audit maxDebtRate on line 476
483:                  emit MaxDebtRateUpdated(maxDebtRate, _maxDebtRate);

/// @audit minDebtRate on line 182
194:          uint256 debt = ((maxDebtRate - minDebtRate) * debtPercentage) /

/// @audit minDebtRate on line 194
196:              minDebtRate;

/// @audit minDebtRate on line 478
482:                  require(_maxDebtRate > minDebtRate, "BigBang: not valid");

/// @audit debtStartPoint on line 192
193:              DEBT_PRECISION) / (_maxDebtPoint - debtStartPoint);

/// @audit yieldBox on line 347
349:              yieldBox.transfer(from, address(swapper), assetId, supplyShare);

/// @audit yieldBox on line 447
450:              asset.approve(address(yieldBox), totalFees);

/// @audit yieldBox on line 450
452:              yieldBox.depositAsset(

/// @audit yieldBox on line 551
557:          emit LogAddCollateral(skim ? address(yieldBox) : from, to, share);

/// @audit yieldBox on line 590
596:          yieldBox.transfer(

/// @audit yieldBox on line 596
608:          uint256 balanceBefore = yieldBox.balanceOf(address(this), assetId);

/// @audit yieldBox on line 608
619:          uint256 balanceAfter = yieldBox.balanceOf(address(this), assetId);

/// @audit yieldBox on line 648
649:          yieldBox.transfer(address(this), msg.sender, assetId, callerShare);

/// @audit yieldBox on line 700
704:              yieldBox.transfer(from, address(this), _tokenId, share);

/// @audit yieldBox on line 761
762:          yieldBox.depositAsset(assetId, address(this), to, amount, 0);

/// @audit yieldBox on line 762
764:          share = yieldBox.toShare(assetId, amount, false);

/// @audit yieldBox on line 781
811:          collateralShare = yieldBox.toShare(

/// @audit penrose on line 127
129:          owner = address(penrose);

/// @audit penrose on line 129
131:          address _asset = penrose.usdoToken();

/// @audit penrose on line 131
141:          assetId = penrose.usdoAssetId();

/// @audit penrose on line 141
156:          _isEthMarket = collateralId == penrose.wethAssetId();

/// @audit penrose on line 181
184:          uint256 _ethMarketTotalDebt = BigBang(penrose.bigBangEthMarket())

/// @audit collateralId on line 143
156:          _isEthMarket = collateralId == penrose.wethAssetId();

/// @audit collateralId on line 551
556:          _addTokens(from, collateralId, share, oldTotalCollateralShare, skim);

/// @audit collateralId on line 599
611:              collateralId,

/// @audit collateralId on line 782
812:              collateralId,

/// @audit asset on line 445
450:              asset.approve(address(yieldBox), totalFees);

/// @audit asset on line 758
761:          asset.approve(address(yieldBox), amount);

/// @audit assetId on line 347
349:              yieldBox.transfer(from, address(swapper), assetId, supplyShare);

/// @audit assetId on line 349
356:              assetId,

/// @audit assetId on line 397
416:          uint256 shareOwed = yieldBox.toShare(assetId, amountOwed, true);

/// @audit assetId on line 447
453:                  assetId,

/// @audit assetId on line 590
608:          uint256 balanceBefore = yieldBox.balanceOf(address(this), assetId);

/// @audit assetId on line 608
612:              assetId,

/// @audit assetId on line 612
619:          uint256 balanceAfter = yieldBox.balanceOf(address(this), assetId);

/// @audit assetId on line 648
649:          yieldBox.transfer(address(this), msg.sender, assetId, callerShare);

/// @audit assetId on line 762
764:          share = yieldBox.toShare(assetId, amount, false);

/// @audit totalBorrow on line 182
186:          uint256 _currentDebt = totalBorrow.elastic;

/// @audit totalBorrow on line 415
421:              uint256 partOut = totalBorrow.toBase(amountOut, false);

/// @audit totalBorrow on line 726
726:          (totalBorrow, amount) = totalBorrow.sub(part, true);

/// @audit totalBorrow on line 749
749:          (totalBorrow, part) = totalBorrow.add(amount + feeAmount, true);

/// @audit totalBorrow on line 749
751:              totalBorrowCap == 0 || totalBorrow.elastic <= totalBorrowCap,

/// @audit totalBorrow on line 807
822:          totalBorrow.elastic -= uint128(borrowAmount);

/// @audit totalBorrow on line 822
823:          totalBorrow.base -= uint128(borrowPart);

/// @audit totalBorrowCap on line 751
751:              totalBorrowCap == 0 || totalBorrow.elastic <= totalBorrowCap,

/// @audit EXCHANGE_RATE_PRECISION on line 785
813:              (amountWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L447

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit paused on line 247
248:          emit PausedUpdated(paused, val);

/// @audit exchangeRate on line 345
349:              rate = exchangeRate;

/// @audit minLiquidatorReward on line 216
222:                  _maxLiquidatorReward > minLiquidatorReward,

/// @audit minLiquidatorReward on line 451
456:          int256 diff = int256(minLiquidatorReward) - int256(maxLiquidatorReward);

/// @audit maxLiquidatorReward on line 456
459:              int256(maxLiquidatorReward);

/// @audit collateralizationRate on line 284
288:              ((collateralizationRate * collateralPartInAssetScaled) /

/// @audit collateralizationRate on line 288
291:              (collateralizationRate *

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L248

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit totalAsset on line 50
72:                   totalAsset,

/// @audit totalAsset on line 72
90:                   totalAsset,

/// @audit totalAsset on line 229
232:          Rebase memory _totalAsset = totalAsset;

/// @audit ASSET_SIG on line 245
246:                  _yieldBoxShares[from][ASSET_SIG] = 0; //some assets accrue in time

/// @audit ASSET_SIG on line 246
248:                  _yieldBoxShares[from][ASSET_SIG] -= share;

/// @audit minimumTargetUtilization on line 112
113:              uint256 underFactor = ((minimumTargetUtilization - utilization) *

/// @audit minimumTargetUtilization on line 113
114:                  FACTOR_PRECISION) / minimumTargetUtilization;

/// @audit maximumTargetUtilization on line 124
125:              uint256 overFactor = ((utilization - maximumTargetUtilization) *

/// @audit minimumInterestPerSecond on line 121
122:                  _accrueInfo.interestPerSecond = minimumInterestPerSecond; // 0.25% APR minimum

/// @audit maximumInterestPerSecond on line 132
133:                  newInterestPerSecond = maximumInterestPerSecond; // 1000% APR maximum

/// @audit interestElasticity on line 115
118:                  (uint256(_accrueInfo.interestPerSecond) * interestElasticity) /

/// @audit interestElasticity on line 118
127:              uint256 scale = interestElasticity +

/// @audit interestElasticity on line 127
131:              ) * scale) / interestElasticity;

/// @audit startingInterestPerSecond on line 83
84:                   _accrueInfo.interestPerSecond = startingInterestPerSecond;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L72

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit paused on line 273
274:          emit PausedUpdated(paused, val);

/// @audit usdoAssetId on line 302
310:          emit UsdoTokenUpdated(_usdoToken, usdoAssetId);

/// @audit feeTo on line 508
532:                  feeTo,

/// @audit feeTo on line 532
536:              yieldBox.transfer(address(this), feeTo, assetId, feeShares);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L274

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit paused on line 116
117:          emit PausedUpdated(paused, val);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L117

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

/// @audit tapiocaOFTs on line 86
/// @audit tapiocaOFTs on line 89
89:           return tapiocaOFTs[tapiocaOFTs.length - 1];

/// @audit harvestableTapiocaOFTs on line 98
99:               harvestableTapiocaOFTs[i].harvestFees();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L89

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit erc20 on line 371
374:              IERC20(erc20).safeTransfer(_toAddress, _amount);

/// @audit _decimalCache on line 85
86:           return _decimalCache;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L374

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

/// @audit erc20 on line 215
217:              .buildSwapData(erc20, swapData.tokenOut, amount, 0, false, false);

/// @audit erc20 on line 272
275:              IERC20(erc20).safeTransfer(_toAddress, _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L217

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

/// @audit yieldBox on line 182
184:          _erc20.approve(address(yieldBox), _amount);

/// @audit yieldBox on line 184
185:          yieldBox.depositAsset(_assetId, _from, _to, _amount, _share);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L184

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit rewardTokens on line 456
457:          rewardTokens.push(token);

/// @audit lastProcessedWeek on line 434
437:          WeekTotals storage totals = weekTotals[lastProcessedWeek];

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L457

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit paymentTokenBeneficiary on line 369
378:                      paymentTokenBeneficiary,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L378

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit paymentTokenBeneficiary on line 483
492:                      paymentTokenBeneficiary,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L492

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit singularities on line 304
313:                      singularities.pop();

/// @audit singularities on line 321
322:                      singularities.pop();

/// @audit singularities on line 338
340:              total += activeSingularities[sglAssetIDToAddress[singularities[i]]]

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L313

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

/// @audit twTap on line 135
138:          try twTap.participate(to, amount, duration) {} catch Error(

/// @audit twTap on line 222
225:          try twTap.claimAndSendRewards(tokenID, rewardTokens) {

/// @audit twTap on line 307
310:          try twTap.exitPositionAndSendTap(tokenID) returns (uint256 _amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L138

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit governanceChainIdentifier on line 119
120:          if (_getChainId() == governanceChainIdentifier) {

/// @audit paused on line 153
154:          emit PausedUpdated(paused, val);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L120

File: tap-token-audit/contracts/Vesting.sol

/// @audit start on line 168
170:          if (block.timestamp < start + cliff) return 0;

/// @audit start on line 170
171:          if (block.timestamp >= start + duration) return total;

/// @audit start on line 171
/// @audit duration on line 171
172:          return (total * (block.timestamp - start)) / duration;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L170

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit curvePool on line 102
103:          address tokenOut = curvePool.coins(tokenIndexes[1]);

/// @audit curvePool on line 152
153:          address tokenOut = curvePool.coins(uint256(uint128(j)));

/// @audit curvePool on line 153
155:          uint256 outputAmount = curvePool.get_dy(i, j, amountIn);

/// @audit curvePool on line 155
160:          _safeApprove(tokenIn, address(curvePool), amountIn);

/// @audit curvePool on line 160
161:          curvePool.exchange(i, j, amountIn, amountOutMin);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L103

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit swapper on line 104
112:              result = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 184
192:              uint256 calcAmount = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 192
194:              swapper.swap(swapData, minAmount, address(this), "");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L112

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit poolId on line 152
172:              poolId,

/// @audit poolId on line 172
181:          vault.joinPool(poolId, address(this), address(this), joinPoolRequest);

/// @audit poolId on line 222
245:              poolId,

/// @audit poolId on line 245
257:          vault.exitPool(poolId, address(this), payable(this), exitRequest);

/// @audit poolId on line 274
291:              poolId,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L172

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit swapper on line 134
142:              result = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 171
172:          rewardToken.approve(address(swapper), 0);

/// @audit swapper on line 197
198:                  ISwapper.SwapData memory swapData = swapper.buildSwapData(

/// @audit swapper on line 198
206:                  uint256 calcAmount = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 206
208:                  swapper.swap(swapData, minAmount, address(this), "");

/// @audit lpGetter on line 153
155:          result = lpGetter.removeLiquidityWeth(lpBalance, minAmount);

/// @audit lpGetter on line 180
181:          wrappedNative.approve(address(lpGetter), 0);

/// @audit lpGetter on line 311
314:              uint256 lpAmount = lpGetter.addLiquidityWeth(amount, minAmount);

/// @audit lpGetter on line 335
337:              lpGetter.removeLiquidityWeth(lpBalance, minAmount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L142

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit swapper on line 116
124:              result = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 142
143:          rewardToken.approve(address(swapper), 0);

/// @audit swapper on line 170
178:                  uint256 calcAmount = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 178
180:                  swapper.swap(swapData, minAmount, address(this), "");

/// @audit lpGetter on line 73
76:           lpToken = IERC20(lpGetter.lpToken());

/// @audit lpGetter on line 151
152:          wrappedNative.approve(address(lpGetter), 0);

/// @audit lpGetter on line 185
187:                  uint256 lpAmount = lpGetter.addLiquidityWeth(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L124

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit swapper on line 107
115:              result = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 133
134:          rewardToken.approve(address(swapper), 0);

/// @audit swapper on line 161
169:                  uint256 calcAmount = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 169
171:                  swapper.swap(swapData, minAmount, address(this), "");

/// @audit lpGetter on line 75
78:           IERC20(lpGetter.lpToken()).approve(_lpGauge, type(uint256).max);

/// @audit lpGetter on line 78
79:           IERC20(lpGetter.lpToken()).approve(_lpGetter, type(uint256).max);

/// @audit lpGetter on line 142
143:          wrappedNative.approve(address(lpGetter), 0);

/// @audit lpGetter on line 187
189:          result = lpGetter.removeLiquidityWeth(lpBalance, minAmount);

/// @audit lpGetter on line 231
233:              lpGetter.removeLiquidityWeth(lpBalance, minAmount);

/// @audit lpGetter on line 248
250:          uint256 lpAmount = lpGetter.addLiquidityWeth(amount, minAmount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L115

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit swapper on line 123
131:              result = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 150
151:          stgTokenReward.approve(address(swapper), 0);

/// @audit swapper on line 173
181:                  uint256 calcAmount = swapper.getOutputAmount(swapData, "");

/// @audit swapper on line 181
184:                  swapper.swap(swapData, minAmount, address(this), "");

/// @audit lpStakingPid on line 197
200:          lpStaking.withdraw(lpStakingPid, toWithdraw);

/// @audit stgNative on line 88
89:           stgNative.approve(_lpStaking, type(uint256).max);

/// @audit stgNative on line 89
90:           stgNative.approve(address(router), type(uint256).max);

/// @audit stgTokenReward on line 92
94:           stgTokenReward.approve(_swapper, type(uint256).max);

/// @audit stgTokenReward on line 151
153:          stgTokenReward.approve(_swapper, type(uint256).max);

/// @audit stgTokenReward on line 166
168:              uint256 stgBalanceAfter = stgTokenReward.balanceOf(address(this));

/// @audit stgTokenReward on line 168
174:                      address(stgTokenReward),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L131

[G‑11] <x> += <y> costs more gas than <x> = <x> + <y> for state variables

Using the addition operator instead of plus-equals saves 113 gas

There are 5 instances of this issue:

File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

446:          totalFees += balance;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L446

File: tap-token-audit/contracts/tokens/TapOFT.sol

204:          dso_supply -= mintedInWeek[week - 1];

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L204

File: tap-token-audit/contracts/Vesting.sol

115:          _totalClaimed += _claimable;

143:          _totalAmount += _amount;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L115

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

125:              feesPending -= feeAmount;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L125

[G‑12] Add unchecked {} for subtractions where the operands cannot underflow because of a previous require() or if-statement

require(a <= b); x = b - a => require(a <= b); unchecked { x = b - a }

There are 21 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit require() on line 142
146:                  balanceOf[msg.sender] = srcBalance - amount; // Underflow is checked

/// @audit require() on line 167
181:                  balanceOf[from] = srcBalance - amount; // Underflow is checked

/// @audit require() on line 174
177:                      allowance[from][msg.sender] = spenderAllowance - amount; // Underflow is checked

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L146

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit if-condition on line 112
113:              uint256 underFactor = ((minimumTargetUtilization - utilization) *

/// @audit if-condition on line 124
125:              uint256 overFactor = ((utilization - maximumTargetUtilization) *

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L113

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

/// @audit require() on line 164
166:          return balanceAfter - balanceBefore;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L166

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

/// @audit if-condition on line 623
630:                          _removeAmount - repayed,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L630

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit require() on line 264
268:          return wrappedNativeBalanceAfter - wrappedNativeBalanceBefore;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L268

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit if-condition on line 180
181:              uint256 aaveAmount = aaveBalanceAfter - aaveBalanceBefore;

/// @audit if-condition on line 258
261:              uint256 toWithdraw = amount - queued;

/// @audit if-condition on line 268
269:                  amount += (obtainedWrapped - toWithdraw);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L181

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit if-condition on line 199
202:              uint256 toWithdraw = (((amount - queued) * (10 ** decimals)) /

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L202

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit if-condition on line 144
146:              uint256 toWithdraw = (((amount - queued) * (10 ** 18)) /

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L146

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit if-condition on line 167
168:                  uint256 crvAmount = crvBalanceAfter - crvBalanceBefore;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L168

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit if-condition on line 158
159:                  uint256 crvAmount = crvBalanceAfter - crvBalanceBefore;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L159

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit if-condition on line 269
274:              gmxRewardRouter.unstakeEsGmx(vestable - freeEsGmx);

/// @audit if-condition on line 311
312:              gmxRewardRouter.stakeEsGmx(freeEsGmx - buffer);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L274

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit if-condition on line 149
150:              uint256 toWithdraw = amount - queued; //1:1 between eth<>stEth

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L150

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit if-condition on line 170
171:                  uint256 stgAmount = stgBalanceAfter - stgBalanceBefore;

/// @audit if-condition on line 249
251:              uint256 toWithdraw = amount - queued;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L171

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit if-condition on line 140
142:              uint256 toWithdraw = (((amount - queued) *

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L142

[G‑13] <array>.length should not be looked up in every loop of a for-loop

The overheads outlined below are PER LOOP, excluding the first loop

  • storage arrays incur a Gwarmaccess (100 gas)
  • memory arrays use MLOAD (3 gas)
  • calldata arrays use CALLDATALOAD (3 gas)

Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset

There are 24 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

215:          for (uint256 i = 0; i < calls.length; i++) {

666:          for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L215

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

45:                   for (uint256 i = 0; i < maxBorrowParts.length; i++) {

107:          for (uint256 i = 0; i < users.length; i++) {

384:          for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L45

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

187:          for (uint256 i = 0; i < calls.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L187

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

255:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L255

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

244:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L244

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

245:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L245

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

98:           for (uint256 i = 0; i < harvestableTapiocaOFTs.length; i++) {

140:          for (uint256 i = 0; i < _call.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L98

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

285:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L285

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

261:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L261

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

260:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L260

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

332:              for (uint256 i = 0; i < _users.length; i++) {

336:              for (uint256 i = 0; i < _users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L332

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

333:          for (uint256 i = 0; i < approvals.length; ) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L333

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

156:          for (uint256 i = 0; i < poolTokens.length; i++) {

225:          for (uint256 i = 0; i < poolTokens.length; i++) {

277:          for (uint256 i = 0; i < poolTokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L156

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

195:          for (uint256 i = 0; i < tokens.length; i++) {

255:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

273:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

280:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L195

[G‑14] ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for- and while-loops

The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas per loop

There are 27 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

215:          for (uint256 i = 0; i < calls.length; i++) {

666:          for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L215

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

45:                   for (uint256 i = 0; i < maxBorrowParts.length; i++) {

107:          for (uint256 i = 0; i < users.length; i++) {

384:          for (uint256 i = 0; i < users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L45

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

187:          for (uint256 i = 0; i < calls.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L187

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

98:           for (uint256 i = 0; i < harvestableTapiocaOFTs.length; i++) {

140:          for (uint256 i = 0; i < _call.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L98

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

332:              for (uint256 i = 0; i < _users.length; i++) {

336:              for (uint256 i = 0; i < _users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L332

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

339:          for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L339

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

202:          for (uint256 i = 0; i < length; i++) {

973:          for (uint256 i = 0; i < len; i++) {

1004:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L202

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

156:          for (uint256 i = 0; i < poolTokens.length; i++) {

225:          for (uint256 i = 0; i < poolTokens.length; i++) {

277:          for (uint256 i = 0; i < poolTokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L156

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

195:          for (uint256 i = 0; i < tokens.length; i++) {

255:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

273:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

280:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L195

File: YieldBox/contracts/NativeTokenFactory.sol

129:          for (uint256 i = 0; i < len; i++) {

141:          for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L129

File: YieldBox/contracts/YieldBox.sol

309:          for (uint256 i = 0; i < len; i++) {

320:          for (uint256 i = 0; i < len; i++) {

339:          for (uint256 i = 0; i < len; i++) {

345:          for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L309

[G‑15] private functions not called by the contract should be removed to save deployment gas

There is one instance of this issue:

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

631       function _executeViewModule(
632           Module _module,
633           bytes memory _data
634:      ) private view returns (bytes memory returnData) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L631-L634

[G‑16] Optimize names to save gas

public/external function names and public member variable names can be optimized to save gas. See this link for an example of how it works. Below are the interfaces/abstract contracts that can be optimized so that the most frequently-called functions use the least amount of gas possible during method lookup. Method IDs that have two leading zero bytes can save 128 gas each during deployment, and renaming functions to have lower method IDs will save 22 gas per call, per sorted position shifted

There are 54 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

/// @audit init(), getTotalDebt(), getDebtRate(), execute(), updateOperator(), accrue(), borrow(), repay(), addCollateral(), removeCollateral(), liquidate(), buyCollateral(), sellCollateral(), refreshPenroseFees(), setBigBangConfig()
39:   contract BigBang is BoringOwnable, Market {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L39

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

/// @audit approveBorrow(), permitBorrow()
24:   contract MarketERC20 is IERC20, IERC20Permit, EIP712 {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L24

File: tapioca-bar-audit/contracts/markets/Market.sol

/// @audit setBorrowOpeningFee(), setBorrowCap(), setMarketConfig(), updatePause(), computeClosingFactor(), computeTVLInfo(), updateExchangeRate(), computeLiquidatorReward()
14:   abstract contract Market is MarketERC20, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L14

File: tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol

/// @audit borrow(), repay()
8:    contract SGLBorrow is SGLLendingCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L8

File: tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol

/// @audit addCollateral(), removeCollateral()
8:    contract SGLCollateral is SGLLendingCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L8

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

/// @audit accrue(), getInterestDetails()
9:    contract SGLCommon is SGLStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L9

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

/// @audit multiHopBuyCollateral(), multiHopSellCollateral(), sellCollateral(), buyCollateral()
10:   contract SGLLeverage is SGLLendingCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L10

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

/// @audit init(), computeAllowedLendShare(), yieldBoxShares(), execute(), addAsset(), removeAsset(), addCollateral(), removeCollateral(), borrow(), repay(), sellCollateral(), buyCollateral(), multiHopBuyCollateral(), multiHopSellCollateral(), liquidate(), withdrawFeesEarned(), refreshPenroseFees(), setSingularityConfig(), setLiquidationQueueConfig()
37:   contract Singularity is SGLCommon {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L37

File: tapioca-bar-audit/contracts/Penrose.sol

/// @audit singularityMarkets(), bigBangMarkets(), singularityMasterContractLength(), bigBangMasterContractLength(), withdrawAllMarketFees(), setBigBangEthMarketDebtRate(), setBigBangEthMarket(), updatePause(), setConservator(), setUsdoToken(), registerSingularityMasterContract(), registerBigBangMasterContract(), registerSingularity(), addSingularity(), registerBigBang(), addBigBang(), executeMarketFn(), setFeeTo(), setSwapper(), _getMasterContractLength()
32:   contract Penrose is BoringOwnable, BoringFactory {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L32

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit setMaxFlashMintable(), setFlashMintFee(), setConservator(), updatePause(), setMinterStatus(), setBurnerStatus(), triggerSendFrom(), exerciseOption(), initMultiHopBuy(), removeAsset(), sendForLeverage(), sendAndLendOrRepay()
46:   contract BaseUSDO is BaseUSDOStorage, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L46

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

/// @audit initMultiHopBuy(), sendForLeverage(), multiHop(), leverageUp(), leverageUpInternal()
19:   contract USDOLeverageModule is BaseUSDOStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L19

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

/// @audit removeAsset(), sendAndLendOrRepay(), remove(), lend(), lendInternal()
21:   contract USDOMarketModule is BaseUSDOStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L21

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

/// @audit triggerSendFrom(), exerciseOption(), sendFromDestination(), exercise(), exerciseInternal()
16:   contract USDOOptionsModule is BaseUSDOStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L16

File: tapiocaz-audit/contracts/Balancer.sol

/// @audit checker(), rebalance(), initConnectedOFT(), addRebalanceAmount()
34:   contract Balancer is Owned {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L34

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

/// @audit tapiocaOFTLength(), harvestableTapiocaOFTsLength(), lastTOFT(), harvestFees(), executeTOFT(), executeCalls(), createTOFT()
26:   contract TapiocaWrapper is Ownable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L26

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

/// @audit triggerSendFrom(), exerciseOption(), initMultiSell(), removeCollateral(), sendToStrategy(), retrieveFromStrategy(), sendToYBAndBorrow(), sendForLeverage()
15:   contract BaseTOFT is BaseTOFTStorage, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L15

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

/// @audit initMultiSell(), sendForLeverage(), multiHop(), leverageDown(), leverageDownInternal()
21:   contract BaseTOFTLeverageModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L21

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

/// @audit removeCollateral(), sendToYBAndBorrow(), borrow(), borrowInternal(), remove()
20:   contract BaseTOFTMarketModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L20

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

/// @audit triggerSendFrom(), exerciseOption(), sendFromDestination(), exercise(), exerciseInternal()
16:   contract BaseTOFTOptionsModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L16

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

/// @audit sendToStrategy(), retrieveFromStrategy(), strategyDeposit(), depositToYieldbox(), strategyWithdraw()
16:   contract BaseTOFTStrategyModule is BaseTOFTStorage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L16

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

/// @audit wrap(), unwrap(), updateConnectedChain(), updateBalancerState(), extractUnderlying()
9:    contract mTapiocaOFT is BaseTOFT {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L9

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

/// @audit wrap(), unwrap()
21:   contract TapiocaOFT is BaseTOFT {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L21

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit currentWeek(), getParticipation(), claimable(), participate(), claimRewards(), claimAndSendRewards(), releaseTap(), exitPosition(), exitPositionAndSendTap(), advanceWeek(), distributeReward(), addRewardToken()
71:   contract TwTAP is TWAML, ONFT721, ERC721Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L71

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit getOTCDealDetails(), participate(), exerciseOption(), newEpoch(), aoTAPBrokerClaim(), setTapOracle(), setPhase2MerkleRoots(), registerUserForPhase(), setPaymentToken(), setPaymentTokenBeneficiary(), collectPaymentTokens()
43:   contract AirdropBroker is Pausable, BoringOwnable, FullMath {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L43

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

/// @audit isApprovedOrOwner(), attributes(), exists(), setTokenURI(), mint(), brokerClaim()
32:   contract AOTAP is ERC721, ERC721Permit, BaseBoringBatchable, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L32

File: tap-token-audit/contracts/options/oTAP.sol

/// @audit isApprovedOrOwner(), attributes(), exists(), setTokenURI(), mint(), brokerClaim()
30:   contract OTAP is ERC721, ERC721Permit, BaseBoringBatchable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L30

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit getOTCDealDetails(), participate(), exitPosition(), exerciseOption(), newEpoch(), oTAPBrokerClaim(), setTapOracle(), setPaymentToken(), setPaymentTokenBeneficiary(), collectPaymentTokens()
53:   contract TapiocaOptionBroker is Pausable, BoringOwnable, TWAML {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L53

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit getLock(), getSingularities(), getSingularityPools(), getTotalPoolDeposited(), isApprovedOrOwner(), lock(), unlock(), setSGLPoolWEight(), registerSingularity(), unregisterSingularity()
48:   contract TapiocaOptionLiquidityProvision is

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L48

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

/// @audit lockTwTapPosition(), claimRewards(), unlockTwTapPosition(), setTwTap()
31:   abstract contract BaseTapOFT is OFTV2 {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L31

File: tap-token-audit/contracts/tokens/LTap.sol

/// @audit deposit(), redeem(), setLockedUntil()
23:   contract LTap is BoringOwnable, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L23

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit setGovernanceChainIdentifier(), updatePause(), setMinter(), timestampToWeek(), getCurrentWeek(), getCurrentWeekEmission(), emitForWeek(), extractTAP(), removeTAP()
26:   contract TapOFT is BaseTapOFT, ERC20Permit {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L26

File: tap-token-audit/contracts/Vesting.sol

/// @audit claimable(), claimable(), vested(), vested(), totalClaimed(), claim(), registerUser(), init()
10:   contract Vesting is BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L10

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit singularityMarketInfo(), bigBangMarketInfo(), getCollateralAmountForShare(), getCollateralSharesForBorrowPart(), getAmountForBorrowPart(), getBorrowPartForAmount(), getAmountForAssetFraction(), getFractionForAmount(), burst(), withdrawToChain(), depositAddCollateralAndBorrowFromMarket(), depositRepayAndRemoveCollateralFromMarket(), mintFromBBAndLendOnSGL(), exitPositionAndRemoveCollateral()
30:   contract MagnetarV2 is Ownable, MagnetarV2Storage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L30

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

/// @audit withdrawToChain(), depositAddCollateralAndBorrowFromMarket(), depositRepayAndRemoveCollateralFromMarket(), mintFromBBAndLendOnSGL(), exitPositionAndRemoveCollateral()
20:   contract MagnetarMarketModule is MagnetarV2Storage {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L20

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

/// @audit multicall(), multicallValue()
22:   contract Multicall3 is Ownable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L22

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit coins(), get_dy(), exchange(), get_virtual_price(), gamma(), A()
10:   interface ICurvePool {

/// @audit get(), peek(), peekSpot(), symbol(), name()
30:   contract ARBTriCryptoOracle is ITOracle {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L10

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit deltaCredit(), totalLiquidity(), localDecimals(), token()
7:    interface IStargatePool {

/// @audit get(), peek(), peekSpot(), symbol(), name()
23:   contract SGOracle is IOracle {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L7

File: tapioca-periph-audit/contracts/oracle/Seer.sol

/// @audit get(), peek(), peekSpot(), symbol(), name()
7:    contract Seer is ITOracle, OracleMulti {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L7

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

/// @audit deploy(), computeAddress(), computeAddress()
7:    contract TapiocaDeployer {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L7

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), setMultiSwapper(), compound()
29:   contract AaveStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L29

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), compound(), updateCache()
28:   contract BalancerStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L28

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), compound()
28:   contract CompoundStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L28

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), setMultiSwapper(), setTricryptoLPGetter(), compound()
31:   contract ConvexTricryptoStrategy is

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L31

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), setMultiSwapper(), setTricryptoLPGetter(), compound()
30:   contract TricryptoLPStrategy is

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L30

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), setMultiSwapper(), setTricryptoLPGetter(), compound()
30:   contract TricryptoNativeStrategy is

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L30

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

/// @audit uniswapV3SwapCallback(), harvest(), harvestGmx(), setFeeRecipient(), withdrawFees()
23:   contract GlpStrategy is BaseERC20Strategy, BoringOwnable {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L23

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), compound()
30:   contract LidoEthStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L30

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), setMultiSwapper(), compound()
35:   contract StargateStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L35

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit compoundAmount(), setDepositThreshold(), compound()
30:   contract YearnStrategy is BaseERC20Strategy, BoringOwnable, ReentrancyGuard {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L30

File: YieldBox/contracts/NativeTokenFactory.sol

/// @audit transferOwnership(), claimOwnership(), createToken(), mint(), burn(), batchMint(), batchBurn()
21:   contract NativeTokenFactory is AssetRegister {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L21

File: YieldBox/contracts/YieldBox.sol

/// @audit depositAsset(), depositNFTAsset(), depositETHAsset(), withdraw(), transfer(), batchTransfer(), transferMultiple(), name(), symbol(), decimals(), assetTotals(), toShare(), toAmount(), amountOf(), deposit(), depositETH()
50:   contract YieldBox is YieldBoxPermit, BoringBatchable, NativeTokenFactory, ERC721TokenReceiver, ERC1155TokenReceiver {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L50

File: YieldBox/contracts/YieldBoxURIBuilder.sol

/// @audit name(), symbol(), decimals(), uri()
11:   contract YieldBoxURIBuilder {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L11

[G‑17] >= costs less gas than >

The compiler uses opcodes GT and ISZERO for solidity code that uses >, but only requires LT for >=, which saves 3 gas

There are 2 instances of this issue:

File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

797           borrowPart = maxBorrowPart > availableBorrowPart
798               ? availableBorrowPart
799:              : maxBorrowPart;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L797-L799

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

240           borrowPart = maxBorrowPart > availableBorrowPart
241               ? availableBorrowPart
242:              : maxBorrowPart;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L240-L242

[G‑18] internal functions not called by the contract should be removed to save deployment gas

If the functions are required by an interface, the contract should inherit from that interface and use the override keyword

There is one instance of this issue:

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

254       function _getAmountForBorrowPart(
255           uint256 borrowPart
256:      ) internal view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L254-L256

[G‑19] ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too)

Saves 5 gas per loop

There are 41 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

215:          for (uint256 i = 0; i < calls.length; i++) {

666:          for (uint256 i = 0; i < users.length; i++) {

669:                  liquidatedCount++;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L215

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

45:                   for (uint256 i = 0; i < maxBorrowParts.length; i++) {

107:          for (uint256 i = 0; i < users.length; i++) {

384:          for (uint256 i = 0; i < users.length; i++) {

387:                  liquidatedCount++;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L45

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

187:          for (uint256 i = 0; i < calls.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L187

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

98:           for (uint256 i = 0; i < harvestableTapiocaOFTs.length; i++) {

140:          for (uint256 i = 0; i < _call.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L98

File: tap-token-audit/contracts/governance/twTAP.sol

278:              pool.totalParticipants++; // Save participation

537:              pool.totalParticipants--;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L278

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

288:          epoch++;

332:              for (uint256 i = 0; i < _users.length; i++) {

336:              for (uint256 i = 0; i < _users.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L288

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

243:              pool.totalParticipants++; // Save participation

325:              pool.totalParticipants--;

423:          epoch++;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L243

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

308:              for (uint256 i = 0; i < sglLength; i++) {

339:          for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L308

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

202:          for (uint256 i = 0; i < length; i++) {

973:          for (uint256 i = 0; i < len; i++) {

1004:         for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L202

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

156:          for (uint256 i = 0; i < poolTokens.length; i++) {

225:          for (uint256 i = 0; i < poolTokens.length; i++) {

277:          for (uint256 i = 0; i < poolTokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L156

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

195:          for (uint256 i = 0; i < tokens.length; i++) {

255:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

273:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

280:          for (uint256 i = 0; i < tempData.tokens.length; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L195

File: YieldBox/contracts/BoringMath.sol

28:               result++;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L28

File: YieldBox/contracts/NativeTokenFactory.sol

129:          for (uint256 i = 0; i < len; i++) {

141:          for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L129

File: YieldBox/contracts/YieldBoxRebase.sol

28:           totalAmount++;

36:               share++;

51:           totalAmount++;

59:               amount++;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L28

File: YieldBox/contracts/YieldBox.sol

309:          for (uint256 i = 0; i < len; i++) {

320:          for (uint256 i = 0; i < len; i++) {

339:          for (uint256 i = 0; i < len; i++) {

345:          for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L309

[G‑20] Splitting require() statements that use && saves gas

See this issue which describes the fact that there is a larger deployment gas cost, but with enough runtime calls, the change ends up being cheaper by 3 gas

There are 7 instances of this issue:

File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

133           require(
134               address(_collateral) != address(0) &&
135                   address(_asset) != address(0) &&
136                   address(_oracle) != address(0),
137               "BigBang: bad pair"
138:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L133-L138

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

100           require(
101               address(_collateral) != address(0) &&
102                   address(_asset) != address(0) &&
103                   address(_oracle) != address(0),
104               "SGL: bad pair"
105:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L100-L105

File: tapioca-bar-audit/contracts/Penrose.sol

237           require(
238               markets_.length == swappers_.length &&
239                   swappers_.length == swapData_.length,
240               "Penrose: length mismatch"
241:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L237-L241

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

102           require(
103               success && (data.length == 0 || abi.decode(data, (bool))),
104               "BaseSwapper::safeApprove: approve failed"
105:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L102-L105

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

376           require(
377               success && (data.length == 0 || abi.decode(data, (bool))),
378               "OperationsLib::safeApprove: approve failed"
379:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L376-L379

File: YieldBox/contracts/YieldBox.sol

127:          require(asset.tokenType != TokenType.Native && asset.tokenType != TokenType.ERC721, "YieldBox: can't deposit type");

199:          require(asset.tokenType == TokenType.ERC20 && asset.contractAddress == address(wrappedNative), "YieldBox: not wrappedNative");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L127

[G‑21] Using private rather than public for constants, saves gas

If needed, the values can be read from the verified contract source code, or if there are multiple values there can be a single getter function that returns a tuple of the values of all currently-public constants. Saves 3406-3606 gas in deployment gas due to the compiler not having to create non-payable getter functions for deployment calldata, not having to store the bytes of the value outside of where it's used, and not adding another entry to the method ID table

There are 17 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/Penrose.sol

45:       uint256 public immutable tapAssetId;

53:       uint256 public immutable wethAssetId;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L45

File: tap-token-audit/contracts/governance/twTAP.sol

84:       uint256 public constant EPOCH_DURATION = 7 days;

111:      uint256 public immutable HOST_CHAIN_ID;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L84

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

69:       uint256 public constant PHASE_1_DISCOUNT = 50 * 1e4; // 50%

84:       uint256 public constant PHASE_3_AMOUNT_PER_USER = 714;

85:       uint256 public constant PHASE_3_DISCOUNT = 50 * 1e4;

93:       uint256 public constant PHASE_4_DISCOUNT = 33 * 1e4;

95:       uint256 public constant EPOCH_DURATION = 2 days;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L69

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

78:       uint256 public immutable EPOCH_DURATION; // 7 days = 604800

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L78

File: tap-token-audit/contracts/tokens/TapOFT.sol

41:       uint256 public constant INITIAL_SUPPLY = 46_686_595 * 1e18; // Everything minus DSO

49:       uint256 public constant WEEK = 604800;

53:       uint256 public immutable emissionsStartTime;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L41

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

40:       uint256 public constant GAMMA0 = 28_000_000_000_000; // 2.8e-5

41:       uint256 public constant A0 = 2 * 3 ** 3 * 10_000;

42:       uint256 public constant DISCOUNT0 = 1_087_460_000_000_000; // 0.00108..

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L40

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

48:       uint256 public immutable pid;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L48

[G‑22] Don't compare boolean expressions to boolean literals

if (<x> == true) => if (<x>), if (<x> == false) => if (!<x>)

There are 6 instances of this issue:

File: tapioca-bar-audit/contracts/Penrose.sol

175:              isSingularityMasterContractRegistered[mc] == true,

183:              isBigBangMasterContractRegistered[mc] == true,

322:              isSingularityMasterContractRegistered[mcAddress] == false,

344:              isBigBangMasterContractRegistered[mcAddress] == false,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L175

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

426:              userParticipation[msg.sender][subPhase] == false,

450:              userParticipation[tokenIDToAddress][3] == false,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L426

[G‑23] Multiple if-statements with mutually-exclusive conditions should be changed to if-else statements

If two conditions are the same, their blocks should be combined

There are 2 instances of this issue:

File: tapioca-bar-audit/contracts/markets/Market.sol

264           if (borrowPartDecimals > 18) {
265               borrowPartScaled = borrowPart / (10 ** (borrowPartDecimals - 18));
266           }
267           if (borrowPartDecimals < 18) {
268               borrowPartScaled = borrowPart * (10 ** (18 - borrowPartDecimals));
269:          }

272           if (collateralPartDecimals > 18) {
273               collateralPartInAssetScaled =
274                   collateralPartInAsset /
275                   (10 ** (collateralPartDecimals - 18));
276           }
277           if (collateralPartDecimals < 18) {
278               collateralPartInAssetScaled =
279                   collateralPartInAsset *
280                   (10 ** (18 - collateralPartDecimals));
281:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L264-L269

[G‑24] require() or revert() statements that check input arguments should be at the top of the function

Checks that involve constants should come before checks that involve state variables, function calls, and calculations. By doing these checks first, the function is able to revert before wasting a Gcoldsload (2100 gas*) in a function that may ultimately revert in the unhappy case.

There are 3 instances of this issue:

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

/// @audit expensive op on line 115
116:          require(val != paused, "USDO: same state");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L116

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

/// @audit expensive op on line 96
104:          require(duration > 0, "TapOFT: Small duration");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L104

File: tap-token-audit/contracts/tokens/TapOFT.sol

/// @audit expensive op on line 221
222:          require(_amount > 0, "amount not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L222

[G‑25] Empty blocks should be removed or emit something

The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting. If the contract is meant to be extended, the contract should be abstract and the function signatures be added without any default implementation. If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions, the else-if/else conditions should be nested under the negation of the if-statement, because they involve different classes of checks, which may lead to the introduction of errors when the code is later modified (if (x) {...} else if (y) {...} else {...} => if (!x) { if (y) {...} else {...} }). Empty receive()/fallback() payable functions that are not used, can be removed to save deployment gas.

There are 23 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

267:                  {} catch Error(string memory reason) {

282:                  {} catch Error(string memory reason) {

298:                  {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L267

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

256:                  {} catch Error(string memory reason) {

271:                  {} catch Error(string memory reason) {

287:                  {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L256

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

257:                  {} catch Error(string memory reason) {

272:                  {} catch Error(string memory reason) {

288:                  {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L257

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

297:                  {} catch Error(string memory reason) {

312:                  {} catch Error(string memory reason) {

328:                  {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L297

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

273:                  {} catch Error(string memory reason) {

288:                  {} catch Error(string memory reason) {

304:                  {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L273

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

272:                  {} catch Error(string memory reason) {

287:                  {} catch Error(string memory reason) {

303:                  {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L272

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

138:          try twTap.participate(to, amount, duration) {} catch Error(

344:              {} catch Error(string memory reason) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L138

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

707:          {} catch {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L707

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

273:              try gmxVester.withdraw() {} catch {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L273

[G‑26] Superfluous event fields

block.timestamp and block.number are added to event information by default so adding them manually wastes gas

There is one instance of this issue:

File: tapioca-bar-audit/contracts/Penrose.sol

138:      event ProtocolWithdrawal(IMarket[] markets, uint256 timestamp);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L138

[G‑27] Use custom errors rather than revert()/require() strings to save gas

Custom errors are available from solidity version 0.8.4. Custom errors save ~50 gas each time they're hit by avoiding having to allocate and store the revert string. Not defining the strings also save deployment gas

There are 244 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

133           require(
134               address(_collateral) != address(0) &&
135                   address(_asset) != address(0) &&
136                   address(_oracle) != address(0),
137               "BigBang: bad pair"
138:          );

219:              require(success || !revertOnFail, _getRevertMsg(result));

344:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

371:          require(amountOut >= minAmountOut, "SGL: not enough");

391:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

413:          require(amountOut >= minAmountOut, "SGL: not enough");

476:                  require(_minDebtRate < maxDebtRate, "BigBang: not valid");

482:                  require(_maxDebtRate > minDebtRate, "BigBang: not valid");

496                   require(
497                       _liquidationMultiplier < FEE_PRECISION,
498                       "BigBang: not valid"
499:                  );

593:          require(penrose.swappers(swapper), "BigBang: Invalid swapper");

680:          require(liquidatedCount > 0, "SGL: no users found");

699               require(
700                   share <= yieldBox.balanceOf(address(this), _tokenId) - total,
701                   "BigBang: too much"
702:              );

750           require(
751               totalBorrowCap == 0 || totalBorrow.elastic <= totalBorrowCap,
752               "BigBang: borrow cap reached"
753:          );

820:          require(borrowAmount != 0, "SGL: solvent");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L133-L138

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

142:              require(srcBalance >= amount, "ERC20: balance too low");

144:                  require(to != address(0), "ERC20: no zero address"); // Moved down so low balance calls safe some gas

167:              require(srcBalance >= amount, "ERC20: balance too low");

173                       require(
174                           spenderAllowance >= amount,
175                           "ERC20: allowance too low"
176:                      );

179:                  require(to != address(0), "ERC20: no zero address"); // Moved down so other failed calls safe some gas

261:          require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

277:          require(signer == owner, "ERC20Permit: invalid signature");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L142

File: tapioca-bar-audit/contracts/markets/Market.sol

116:          require(!paused, "Market: paused");

126:          require(_isSolvent(from, exchangeRate), "Market: insolvent");

131:          require(!initialized, "Market: initialized");

143:          require(_val <= FEE_PRECISION, "Market: not valid");

172:              require(_borrowOpeningFee <= FEE_PRECISION, "Market: not valid");

193:              require(_callerFee <= FEE_PRECISION, "Market: not valid");

198:              require(_protocolFee <= FEE_PRECISION, "Market: not valid");

203               require(
204                   _liquidationBonusAmount < FEE_PRECISION,
205                   "Market: not valid"
206:              );

211:              require(_minLiquidatorReward < FEE_PRECISION, "Market: not valid");

212               require(
213                   _minLiquidatorReward < maxLiquidatorReward,
214                   "Market: not valid"
215:              );

220:              require(_maxLiquidatorReward < FEE_PRECISION, "Market: not valid");

221               require(
222                   _maxLiquidatorReward > minLiquidatorReward,
223                   "Market: not valid"
224:              );

234               require(
235                   _collateralizationRate <= FEE_PRECISION,
236                   "Market: not valid"
237:              );

246:          require(msg.sender == conservator, "Market: unauthorized");

247:          require(val != paused, "Market: same state");

344:              require(rate > 0, "Market: invalid rate");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L116

File: tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol

187               require(
188                   share <= yieldBox.balanceOf(address(this), _assetId) - total,
189                   "SGL: too much"
190:              );

240:          require(_totalAsset.base >= 1000, "SGL: min limit");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L187-L190

File: tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol

66            require(
67                totalBorrowCap == 0 || totalBorrow.base <= totalBorrowCap,
68                "SGL: borrow cap reached"
69:           );

75:           require(_totalAsset.base >= 1000, "SGL: min limit");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L66-L69

File: tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol

29            require(
30                penrose.swappers(ISwapper(externalData.swapper)),
31                "SGL: Invalid swapper"
32:           );

65            require(
66                penrose.swappers(ISwapper(externalData.swapper)),
67                "SGL: Invalid swapper"
68:           );

104:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

126:          require(amountOut >= minAmountOut, "SGL: not enough");

155:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

182:          require(amountOut >= minAmountOut, "SGL: not enough");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L29-L32

File: tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol

152:          require(allBorrowAmount != 0, "SGL: solvent");

264:          require(borrowAmount != 0, "SGL: solvent");

327:          require(penrose.swappers(swapper), "SGL: Invalid swapper");

397:          require(liquidatedCount > 0, "SGL: no users found");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L152

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

100           require(
101               address(_collateral) != address(0) &&
102                   address(_asset) != address(0) &&
103                   address(_oracle) != address(0),
104               "SGL: bad pair"
105:          );

191:              require(success || !revertOnFail, _getRevertMsg(result));

507               require(
508                   _maximumTargetUtilization < FULL_UTILIZATION,
509                   "SGL: not valid"
510:              );

522               require(
523                   _minimumInterestPerSecond < maximumInterestPerSecond,
524                   "SGL: not valid"
525:              );

534               require(
535                   _maximumInterestPerSecond > minimumInterestPerSecond,
536                   "SGL: not valid"
537:              );

554               require(
555                   _lqCollateralizationRate <= FEE_PRECISION,
556                   "SGL: not valid"
557:              );

566:              require(_liquidationMultiplier < FEE_PRECISION, "SGL: not valid");

582:              require(_liquidationQueue.onlyOnce(), "SGL: LQ not initalized");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L100-L105

File: tapioca-bar-audit/contracts/Penrose.sol

174           require(
175               isSingularityMasterContractRegistered[mc] == true,
176               "Penrose: MC not registered"
177:          );

182           require(
183               isBigBangMasterContractRegistered[mc] == true,
184               "Penrose: MC not registered"
185:          );

190:          require(!paused, "Penrose: paused");

237           require(
238               markets_.length == swappers_.length &&
239                   swappers_.length == swapData_.length,
240               "Penrose: length mismatch"
241:          );

242:          require(address(swappers_[0]) != address(0), "Penrose: zero address");

243:          require(address(markets_[0]) != address(0), "Penrose: zero address");

272:          require(msg.sender == conservator, "Penrose: unauthorized");

273:          require(val != paused, "Penrose: same state");

282:          require(_conservator != address(0), "Penrose: address not valid");

321           require(
322               isSingularityMasterContractRegistered[mcAddress] == false,
323               "Penrose: MC registered"
324:          );

343           require(
344               isBigBangMasterContractRegistered[mcAddress] == false,
345               "Penrose: MC registered"
346:          );

438               require(
439                   isSingularityMasterContractRegistered[
440                       masterContractOf[mc[i]]
441                   ] || isBigBangMasterContractRegistered[masterContractOf[mc[i]]],
442                   "Penrose: MC not registered"
443:              );

446:                  require(success[i], _getRevertMsg(result[i]));

505:          require(swappers[swapper], "Penrose: Invalid swapper");

506:          require(isMarketRegistered[address(market)], "Penrose: Invalid market");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L174-L177

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

97:           require(_val < FLASH_MINT_FEE_PRECISION, "USDO: fee too big");

106:          require(_conservator != address(0), "USDO: address not valid");

115:          require(msg.sender == conservator, "USDO: unauthorized");

116:          require(val != paused, "USDO: same state");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L97

File: tapioca-bar-audit/contracts/usd0/USDO.sol

26:           require(!paused, "USDO: paused");

68:           require(token == address(this), "USDO: token not valid");

87:           require(token == address(this), "USDO: token not valid");

88:           require(maxFlashLoan(token) >= amount, "USDO: amount too big");

89:           require(amount > 0, "USDO: amount not valid");

93            require(
94                receiver.onFlashLoan(msg.sender, token, amount, fee, data) ==
95                    FLASH_MINT_CALLBACK_SUCCESS,
96                "USDO: failed"
97:           );

100:          require(_allowance >= (amount + fee), "USDO: repay not approved");

110:          require(allowedMinter[_getChainId()][msg.sender], "USDO: unauthorized");

119:          require(allowedBurner[_getChainId()][msg.sender], "USDO: unauthorized");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L26

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

46:           require(block.chainid == hostChainID, "TOFT_host");

354               require(
355                   allowance(_fromAddress, msg.sender) >= _amount,
356                   "TOFT_allowed"
357:              );

364:          require(msg.value > 0, "TOFT_0");

381:          require(sent, "TOFT_failed");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L46

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

281:          require(sent, "TOFT_failed");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L281

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

56:           require(amount > 0, "TOFT_0");

98:           require(amount > 0, "TOFT_0");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L56

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

93:           require(!balancers[msg.sender], "TOFT_auth");

105:          require(connectedChains[block.chainid], "TOFT_host");

106:          require(!balancers[msg.sender], "TOFT_auth");

142:          require(balancers[msg.sender], "TOFT_auth");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L93

File: tap-token-audit/contracts/governance/twTAP.sol

257:          require(_duration >= EPOCH_DURATION, "twTAP: Lock not a week");

313:          require(expiry < type(uint56).max, "twTAP: too long");

365:          require(msg.sender == address(tapOFT), "twTAP: only tapOFT");

390:          require(msg.sender == address(tapOFT), "twTAP: only tapOFT");

433           require(
434               lastProcessedWeek == currentWeek(),
435               "twTAP: Advance week first"
436:          );

473           require(
474               msg.sender == tokenOwner ||
475                   _to == tokenOwner ||
476                   isApprovedForAll(tokenOwner, msg.sender) ||
477                   getApproved(_tokenId) == msg.sender,
478               "twTAP: cannot claim"
479:          );

530:          require(position.expiry <= block.timestamp, "twTAP: Lock not expired");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L257

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

158:          require(aoTapOption.expiry > block.timestamp, "adb: Option expired");

167           require(
168               paymentTokenOracle.oracle != IOracle(address(0)),
169               "adb: Payment token not supported"
170:          );

174:          require(eligibleTapAmount >= _tapAmount, "adb: Too high");

177:          require(tapAmount >= 1e18, "adb: Too low");

203:          require(cachedEpoch > 0, "adb: Airdrop not started");

204:          require(cachedEpoch <= 4, "adb: Airdrop ended");

233:          require(aoTapOption.expiry > block.timestamp, "adb: Option expired");

242           require(
243               paymentTokenOracle.oracle != IOracle(address(0)),
244               "adb: Payment token not supported"
245:          );

246           require(
247               aoTAP.isApprovedOrOwner(msg.sender, _aoTAPTokenID),
248               "adb: Not approved or owner"
249:          );

255:          require(eligibleTapAmount >= _tapAmount, "adb: Too high");

258:          require(chosenAmount >= 1e18, "adb: Too low");

281           require(
282               block.timestamp >= lastEpochUpdate + EPOCH_DURATION,
283               "adb: too soon"
284:          );

329:          require(_users.length == _amounts.length, "adb: invalid input");

368           require(
369               paymentTokenBeneficiary != address(0),
370               "adb: Payment token beneficiary not set"
371:          );

392:          require(_eligibleAmount > 0, "adb: Not eligible");

419           require(
420               MerkleProof.verify(_merkleProof, phase2MerkleRoots[_role], leaf),
421               "adb: Not eligible"
422:          );

425           require(
426               userParticipation[msg.sender][subPhase] == false,
427               "adb: Already participated"
428:          );

447:          require(PCNFT.ownerOf(_tokenID) == msg.sender, "adb: Not eligible");

449           require(
450               userParticipation[tokenIDToAddress][3] == false,
451               "adb: Already participated"
452:          );

467:          require(_eligibleAmount > 0, "adb: Not eligible");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L158

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

46:           require(msg.sender == broker, "AOTAP: only onlyBroker");

98            require(
99                _isApprovedOrOwner(msg.sender, _tokenId),
100               "AOTAP: only approved or owner"
101:          );

129           require(
130               _isApprovedOrOwner(msg.sender, _tokenId),
131               "AOTAP: only approved or owner"
132:          );

140:          require(broker == address(0), "AOTAP: only once");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L46

File: tap-token-audit/contracts/options/oTAP.sol

40:           require(msg.sender == broker, "OTAP: only onlyBroker");

84            require(
85                _isApprovedOrOwner(msg.sender, _tokenId),
86                "OTAP: only approved or owner"
87:           );

116           require(
117               _isApprovedOrOwner(msg.sender, _tokenId),
118               "OTAP: only approved or owner"
119:          );

127:          require(broker == address(0), "OTAP: only once");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L40

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

170           require(
171               paymentTokenOracle.oracle != IOracle(address(0)),
172               "tOB: Payment token not supported"
173:          );

175:          require(isPositionActive, "tOB: Option expired");

187:          require(eligibleTapAmount >= _tapAmount, "tOB: Too high");

190:          require(tapAmount >= 1e18, "tOB: Too low");

219:          require(isPositionActive, "tOB: Position is not active");

220:          require(lock.lockDuration >= EPOCH_DURATION, "tOB: Duration too short");

224           require(
225               tOLP.isApprovedOrOwner(msg.sender, _tOLPTokenID),
226               "tOB: Not approved or owner"
227:          );

297:          require(oTAP.exists(_oTAPTokenID), "tOB: oTAP position does not exist");

303           require(
304               block.timestamp >= lock.lockTime + lock.lockDuration,
305               "tOB: Lock not expired"
306:          );

368           require(
369               paymentTokenOracle.oracle != IOracle(address(0)),
370               "tOB: Payment token not supported"
371:          );

372           require(
373               oTAP.isApprovedOrOwner(msg.sender, _oTAPTokenID),
374               "tOB: Not approved or owner"
375:          );

376:          require(isPositionActive, "tOB: Option expired");

388:          require(eligibleTapAmount >= _tapAmount, "tOB: Too high");

391:          require(chosenAmount >= 1e18, "tOB: Too low");

414           require(
415               block.timestamp >= lastEpochUpdate + EPOCH_DURATION,
416               "tOB: too soon"
417:          );

419:          require(singularities.length > 0, "tOB: No active singularities");

482           require(
483               paymentTokenBeneficiary != address(0),
484               "tOB: Payment token beneficiary not set"
485:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L170-L173

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

177:          require(_lockDuration > 0, "tOLP: lock duration must be > 0");

178:          require(_amount > 0, "tOLP: amount must be > 0");

181:          require(sglAssetID > 0, "tOLP: singularity not active");

212:          require(_exists(_tokenId), "tOLP: Expired position");

215           require(
216               block.timestamp >=
217                   lockPosition.lockTime + lockPosition.lockDuration,
218               "tOLP: Lock not expired"
219:          );

220           require(
221               activeSingularities[_singularity].sglAssetID ==
222                   lockPosition.sglAssetID,
223               "tOLP: Invalid singularity"
224:          );

226           require(
227               _isApprovedOrOwner(msg.sender, _tokenId),
228               "tOLP: not owner nor approved"
229:          );

263           require(
264               activeSingularities[singularity].sglAssetID > 0,
265               "tOLP: not registered"
266:          );

281:          require(assetID > 0, "tOLP: invalid asset ID");

282           require(
283               activeSingularities[singularity].sglAssetID == 0,
284               "tOLP: already registered"
285:          );

301:          require(sglAssetID > 0, "tOLP: not registered");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L177

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

104:          require(duration > 0, "TapOFT: Small duration");

222:          require(twTap.ownerOf(tokenID) == to, "TapOFT: Not owner");

307:          require(twTap.ownerOf(tokenID) == to, "TapOFT: Not owner");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L104

File: tap-token-audit/contracts/tokens/LTap.sol

47:           require(block.timestamp > lockedUntil, "Still locked");

54:           require(_lockedUntil <= maxLockedUntil, "Too late");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L47

File: tap-token-audit/contracts/tokens/TapOFT.sol

89:           require(!paused, "TAP: paused");

118:          require(_lzEndpoint != address(0), "LZ endpoint not valid");

127               require(
128                   totalSupply() == INITIAL_SUPPLY,
129                   "initial supply not valid"
130:              );

153:          require(val != paused, "TAP: same state");

161:          require(_minter != address(0), "address not valid");

198:          require(_getChainId() == governanceChainIdentifier, "chain not valid");

221:          require(msg.sender == minter, "unauthorized");

222:          require(_amount > 0, "amount not valid");

225:          require(emissionForWeek[week] >= _amount, "exceeds allowable amount");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L89

File: tap-token-audit/contracts/Vesting.sol

68:           require(_duration > 0, "Vesting: no vesting");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L68

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

205                   require(
206                       _action.call.length > 0,
207                       string.concat(
208                           "MagnetarV2: Missing call for action with index",
209                           string(abi.encode(i))
210                       )
211:                  );

714:          require(msg.value == valAccumulator, "MagnetarV2: value mismatch");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L205-L211

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

337:          require(_from == msg.sender, "MagnetarV2: operator not approved");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L337

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

456                       require(
457                           participateData.tOLPTokenId == tOLPTokenId,
458                           "Magnetar: tOLPTokenId mismatch"
459:                      );

464               require(
465                   lockData.target != address(0),
466                   "Magnetar: lock target mismatch"
467:              );

468:              require(tOLPTokenId != 0, "Magnetar: tOLPTokenId 0");

510               require(
511                   removeAndRepayData.exitData.oTAPTokenID > 0,
512                   "Magnetar: oTAPTokenID 0"
513:              );

527               require(
528                   ownerOfTapTokenId == user || ownerOfTapTokenId == address(this),
529                   "Magnetar: oTAPTokenID owner mismatch"
530:              );

556                       require(
557                           tOLPId == removeAndRepayData.unlockData.tokenId,
558                           "Magnetar: tOLPId mismatch"
559:                      );

743:          require(withdrawData.length > 0, "MagnetarV2: withdrawData is empty");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L456-L459

File: tapioca-periph-audit/contracts/Multicall/Multicall3.sol

90:           require(msg.value == valAccumulator, "Multicall3: value mismatch");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L90

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

102           require(
103               success && (data.length == 0 || abi.decode(data, (bool))),
104               "BaseSwapper::safeApprove: approve failed"
105:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L102-L105

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

156:          require(outputAmount >= amountOutMin, "insufficient-amount-out");

164:          require(balanceAfter > balanceBefore, "swap failed");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L156

File: tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol

28            require(
29                address(this).balance >= amount,
30                "Create2: insufficient balance"
31:           );

32            require(
33                bytecode.length != 0,
34                string.concat(
35                    "Create2: bytecode length is zero for contract ",
36                    contractName
37                )
38:           );

43            require(
44                addr != address(0),
45                string.concat(
46                    "Create2: Failed on deploy for contract ",
47                    contractName
48                )
49:           );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L28-L31

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

255:          require(available >= amount, "AaveStrategy: amount not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L255

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

184           require(
185               lpBalanceAfter > lpBalanceBefore,
186               "BalancerStrategy: vault deposit failed"
187:          );

196:          require(available >= amount, "BalancerStrategy: amount not valid");

208           require(
209               amount <= wrappedNative.balanceOf(address(this)),
210               "BalancerStrategy: not enough"
211:          );

263           require(
264               wrappedNativeBalanceAfter > wrappedNativeBalanceBefore,
265               "BalancerStrategy: vault withdrawal failed"
266:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L184-L187

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

141:          require(available >= amount, "CompoundStrategy: amount not valid");

155           require(
156               wrappedNative.balanceOf(address(this)) >= amount,
157               "CompoundStrategy: not enough"
158:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L141

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

245           require(
246               tempData.rewardContracts.length == tempData.tokens.length,
247               "ConvexTricryptoStrategy: claim data not valid"
248:          );

249           require(
250               tempData.rewardContracts.length > 0,
251               "ConvexTricryptoStrategy: nothing to claim for"
252:          );

325           require(
326               available >= amount,
327               "ConvexTricryptoStrategy: amount not valid"
328:          );

340           require(
341               wrappedNative.balanceOf(address(this)) >= amount,
342               "ConvexTricryptoStrategy: not enough"
343:          );

363           require(
364               successEmtptyApproval,
365               "OperationsLib::safeApprove: approval reset failed"
366:          );

376           require(
377               success && (data.length == 0 || abi.decode(data, (bool))),
378               "OperationsLib::safeApprove: approve failed"
379:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L245-L248

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

234:          require(available >= amount, "TricryptoLPStrategy: amount not valid");

242           require(
243               lpToken.balanceOf(address(this)) >= amount,
244               "TricryptoLPStrategy: not enough"
245:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L234

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

221           require(
222               available >= amount,
223               "TricryptoNativeStrategy: amount not valid"
224:          );

235           require(
236               wrappedNative.balanceOf(address(this)) >= amount,
237               "TricryptoNativeStrategy: not enough"
238:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L221-L224

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

60:           require(address(weth) == _gmxRewardRouter.weth(), "WETH mismatch");

62:           require(_glpRewardRouter.gmx() == address(0), "Bad GLP reward router");

66:           require(_gmx != address(0), "Bad GMX reward router");

91:           require(msg.sender == address(gmxWethPool), "Not the pool");

333:          require(amountOut * priceDenom >= gmxAmount * priceNum, "Not enough");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L60

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

131:              require(!stEth.isStakingPaused(), "LidoStrategy: staking paused");

146:          require(available >= amount, "LidoStrategy: amount not valid");

162:          require(queued >= amount, "LidoStrategy: not enough");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L131

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

246:          require(available >= amount, "StargateStrategy: amount not valid");

262           require(
263               amount <= wrappedNative.balanceOf(address(this)),
264               "Stargate: not enough"
265:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L246

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

137:          require(available >= amount, "YearnStrategy: amount not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L137

File: YieldBox/contracts/BoringMath.sol

6:            require(a <= type(uint128).max, "BoringMath: uint128 Overflow");

11:           require(a <= type(uint64).max, "BoringMath: uint64 Overflow");

16:           require(a <= type(uint32).max, "BoringMath: uint32 Overflow");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L6

File: YieldBox/contracts/NativeTokenFactory.sol

46:           require(msg.sender == owner[tokenId], "NTF: caller is not the owner");

59:               require(newOwner != address(0) || renounce, "NTF: zero address");

77:           require(msg.sender == _pendingOwner, "NTF: caller != pending owner");

117:          require(assets[tokenId].tokenType == TokenType.Native, "NTF: Not native");

139:          require(assets[tokenId].tokenType == TokenType.Native, "NTF: Not native");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L46

File: YieldBox/contracts/YieldBoxPermit.sol

51:           require(block.timestamp <= deadline, "YieldBoxPermit: expired deadline");

58:           require(signer == owner, "YieldBoxPermit: invalid signature");

80:           require(block.timestamp <= deadline, "YieldBoxPermit: expired deadline");

87:           require(signer == owner, "YieldBoxPermit: invalid signature");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L51

File: YieldBox/contracts/YieldBox.sol

127:          require(asset.tokenType != TokenType.Native && asset.tokenType != TokenType.ERC721, "YieldBox: can't deposit type");

175:          require(asset.tokenType == TokenType.ERC721, "YieldBox: not ERC721");

199:          require(asset.tokenType == TokenType.ERC20 && asset.contractAddress == address(wrappedNative), "YieldBox: not wrappedNative");

232:          require(asset.tokenType != TokenType.Native, "YieldBox: can't withdraw Native");

317:          require(to != address(0), "No 0 address");

340:              require(tos[i] != address(0), "YieldBox: to not set"); // To avoid a bad UI from burning funds

360:          require(operator != address(0), "YieldBox: operator not set"); // Important for security

361:          require(operator != address(this), "YieldBox: can't approve yieldBox");

382:          require(operator != address(0), "YieldBox: operator not set"); // Important for security

383:          require(operator != address(this), "YieldBox: can't approve yieldBox");

395:          require(assetId < assetCount(), "YieldBox: asset not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L127

[G‑28] Functions guaranteed to revert when called by normal users can be marked payable

If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are
CALLVALUE(2),DUP1(3),ISZERO(3),PUSH2(3),JUMPI(10),PUSH1(3),DUP1(3),REVERT(0),JUMPDEST(1),POP(2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost

There are 87 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

101:      function init(bytes calldata data) external onlyOnce {

442       function refreshPenroseFees(
443           address
444:      ) external onlyOwner notPaused returns (uint256 feeShares) {

466       function setBigBangConfig(
467           uint256 _minDebtRate,
468           uint256 _maxDebtRate,
469           uint256 _debtRateAgainstEthMarket,
470           uint256 _liquidationMultiplier
471:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L101

File: tapioca-bar-audit/contracts/markets/Market.sol

142:      function setBorrowOpeningFee(uint256 _val) external onlyOwner {

151:      function setBorrowCap(uint256 _cap) external notPaused onlyOwner {

158       function setMarketConfig(
159           uint256 _borrowOpeningFee,
160           IOracle _oracle,
161           bytes calldata _oracleData,
162           address _conservator,
163           uint256 _callerFee,
164           uint256 _protocolFee,
165           uint256 _liquidationBonusAmount,
166           uint256 _minLiquidatorReward,
167           uint256 _maxLiquidatorReward,
168           uint256 _totalBorrowCap,
169           uint256 _collateralizationRate
170:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L142

File: tapioca-bar-audit/contracts/markets/singularity/Singularity.sol

62:       function init(bytes calldata data) external onlyOnce {

477       function refreshPenroseFees(
478           address feeTo
479:      ) external onlyOwner notPaused returns (uint256 feeShares) {

489       function setSingularityConfig(
490           uint256 _lqCollateralizationRate,
491           uint256 _liquidationMultiplier,
492           uint256 _minimumTargetUtilization,
493           uint256 _maximumTargetUtilization,
494           uint64 _minimumInterestPerSecond,
495           uint64 _maximumInterestPerSecond,
496           uint256 _interestElasticity
497:      ) external onlyOwner {

576       function setLiquidationQueueConfig(
577           ILiquidationQueue _liquidationQueue,
578           address _bidExecutionSwapper,
579           address _usdoSwapper
580:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L62

File: tapioca-bar-audit/contracts/Penrose.sol

256:      function setBigBangEthMarketDebtRate(uint256 _rate) external onlyOwner {

263:      function setBigBangEthMarket(address _market) external onlyOwner {

281:      function setConservator(address _conservator) external onlyOwner {

291:      function setUsdoToken(address _usdoToken) external onlyOwner {

317       function registerSingularityMasterContract(
318           address mcAddress,
319           IPenrose.ContractType contractType_
320:      ) external onlyOwner {

339       function registerBigBangMasterContract(
340           address mcAddress,
341           IPenrose.ContractType contractType_
342:      ) external onlyOwner {

381       function addSingularity(
382           address mc,
383           address _contract
384:      ) external onlyOwner registeredSingularityMasterContract(mc) {

414       function addBigBang(
415           address mc,
416           address _contract
417:      ) external onlyOwner registeredBigBangMasterContract(mc) {

424       function executeMarketFn(
425           address[] calldata mc,
426           bytes[] memory data,
427           bool forceSuccess
428       )
429           external
430           onlyOwner
431           notPaused
432:          returns (bool[] memory success, bytes[] memory result)

455:      function setFeeTo(address feeTo_) external onlyOwner {

464:      function setSwapper(ISwapper swapper, bool enable) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L256

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

88:       function setMaxFlashMintable(uint256 _val) external onlyOwner {

96:       function setFlashMintFee(uint256 _val) external onlyOwner {

105:      function setConservator(address _conservator) external onlyOwner {

125:      function setMinterStatus(address _for, bool _status) external onlyOwner {

134:      function setBurnerStatus(address _for, bool _status) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L88

File: tapiocaz-audit/contracts/Balancer.sol

219       function initConnectedOFT(
220           address _srcOft,
221           uint16 _dstChainId,
222           address _dstOft,
223           bytes memory _ercData
224:      ) external onlyOwner {

250       function addRebalanceAmount(
251           address _srcOft,
252           uint16 _dstChainId,
253           uint256 _amount
254:      ) external onlyValidDestination(_srcOft, _dstChainId) onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L219-L224

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

154       function createTOFT(
155           address _erc20,
156           bytes calldata _bytecode,
157           bytes32 _salt,
158           bool _linked
159:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L154-L159

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

116       function updateConnectedChain(
117           uint256 _chain,
118           bool _status
119:      ) external onlyOwner {

131       function updateBalancerState(
132           address _balancer,
133           bool _status
134:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L116-L119

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

85        function unwrap(
86            address _toAddress,
87            uint256 _amount
88:       ) external onlyHostChain {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L85-L88

File: tap-token-audit/contracts/governance/twTAP.sol

455:      function addRewardToken(IERC20 token) external onlyOwner returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L455

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

308       function setTapOracle(
309           IOracle _tapOracle,
310           bytes calldata _tapOracleData
311:      ) external onlyOwner {

318       function setPhase2MerkleRoots(
319           bytes32[4] calldata _merkleRoots
320:      ) external onlyOwner {

324       function registerUserForPhase(
325           uint256 _phase,
326           address[] calldata _users,
327           uint256[] calldata _amounts
328:      ) external onlyOwner {

344       function setPaymentToken(
345           ERC20 _paymentToken,
346           IOracle _oracle,
347           bytes calldata _oracleData
348:      ) external onlyOwner {

357       function setPaymentTokenBeneficiary(
358           address _paymentTokenBeneficiary
359:      ) external onlyOwner {

365       function collectPaymentTokens(
366           address[] calldata _paymentTokens
367:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L308-L311

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

109       function mint(
110           address _to,
111           uint128 _expiry,
112           uint128 _discount,
113           uint256 _amount
114:      ) external onlyBroker returns (uint256 tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L109-L114

File: tap-token-audit/contracts/options/oTAP.sol

96        function mint(
97            address _to,
98            uint128 _expiry,
99            uint128 _discount,
100           uint256 _tOLP
101:      ) external onlyBroker returns (uint256 tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L96-L101

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

446       function setTapOracle(
447           IOracle _tapOracle,
448           bytes calldata _tapOracleData
449:      ) external onlyOwner {

458       function setPaymentToken(
459           ERC20 _paymentToken,
460           IOracle _oracle,
461           bytes calldata _oracleData
462:      ) external onlyOwner {

471       function setPaymentTokenBeneficiary(
472           address _paymentTokenBeneficiary
473:      ) external onlyOwner {

479       function collectPaymentTokens(
480           address[] calldata _paymentTokens
481:      ) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L446-L449

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

259       function setSGLPoolWEight(
260           IERC20 singularity,
261           uint256 weight
262:      ) external onlyOwner updateTotalSGLPoolWeights {

276       function registerSingularity(
277           IERC20 singularity,
278           uint256 assetID,
279           uint256 weight
280:      ) external onlyOwner updateTotalSGLPoolWeights {

297       function unregisterSingularity(
298           IERC20 singularity
299:      ) external onlyOwner updateTotalSGLPoolWeights {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L259-L262

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

326:      function setTwTap(address _twTap) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L326

File: tap-token-audit/contracts/tokens/LTap.sol

53:       function setLockedUntil(uint256 _lockedUntil) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L53

File: tap-token-audit/contracts/tokens/TapOFT.sol

140       function setGovernanceChainIdentifier(
141           uint256 _identifier
142:      ) external onlyOwner {

152:      function updatePause(bool val) external onlyOwner {

160:      function setMinter(address _minter) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L140-L142

File: tap-token-audit/contracts/Vesting.sol

130:      function registerUser(address _user, uint256 _amount) external onlyOwner {

151:      function init(IERC20 _token, uint256 _seededAmount) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L130

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

61:       function setPoolFee(uint24 _newFee) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L61

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

122:      function setDepositThreshold(uint256 amount) external onlyOwner {

129:      function setMultiSwapper(address _swapper) external onlyOwner {

209:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L122

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

109:      function setDepositThreshold(uint256 amount) external onlyOwner {

120:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L109

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

89:       function setDepositThreshold(uint256 amount) external onlyOwner {

100:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L89

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

148:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

163:      function setDepositThreshold(uint256 amount) external onlyOwner {

170:      function setMultiSwapper(address _swapper) external onlyOwner {

179:      function setTricryptoLPGetter(address _lpGetter) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L148

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

134:      function setDepositThreshold(uint256 amount) external onlyOwner {

141:      function setMultiSwapper(address _swapper) external onlyOwner {

150:      function setTricryptoLPGetter(address _lpGetter) external onlyOwner {

199:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L134

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

125:      function setDepositThreshold(uint256 amount) external onlyOwner {

132:      function setMultiSwapper(address _swapper) external onlyOwner {

141:      function setTricryptoLPGetter(address _lpGetter) external onlyOwner {

182:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L125

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

104:      function harvestGmx(uint256 priceNum, uint256 priceDenom) public onlyOwner {

113:      function setFeeRecipient(address recipient) external onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L104

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

93:       function setDepositThreshold(uint256 amount) external onlyOwner {

104:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L93

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

142:      function setDepositThreshold(uint256 amount) external onlyOwner {

149:      function setMultiSwapper(address _swapper) external onlyOwner {

193:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L142

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

90:       function setDepositThreshold(uint256 amount) external onlyOwner {

101:      function emergencyWithdraw() external onlyOwner returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L90

File: YieldBox/contracts/NativeTokenFactory.sol

56:       function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {

109:      function mint(uint256 tokenId, address to, uint256 amount) public onlyOwner(tokenId) {

127:      function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L56

[G‑29] Constructors can be marked payable

Payable functions cost less gas to execute, since the compiler does not have to add extra checks to ensure that a payment wasn't provided. A constructor can safely be marked as payable, since only the deployer would be able to pass funds, and the project itself would not pass any funds.

There are 50 instances of this issue:

see instances
File: tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol

98:       constructor() MarketERC20("Tapioca BigBang") {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L98

File: tapioca-bar-audit/contracts/markets/MarketERC20.sol

109:      constructor(string memory name) EIP712(name, "1") {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L109

File: tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol

148:      constructor() MarketERC20("Tapioca Singularity") {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L148

File: tapioca-bar-audit/contracts/Penrose.sol

86        constructor(
87            YieldBox _yieldBox,
88            IERC20 tapToken_,
89            IERC20 wethToken_,
90:           address _owner

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L86-L90

File: tapioca-bar-audit/contracts/usd0/BaseUSDO.sol

67        constructor(
68            address _lzEndpoint,
69            IYieldBoxBase _yieldBox,
70            address _owner,
71            address payable _leverageModule,
72            address payable _marketModule,
73            address payable _optionsModule
74:       ) BaseUSDOStorage(_lzEndpoint, _yieldBox) ERC20Permit("USDO") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L67-L74

File: tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol

70        constructor(
71            address _lzEndpoint,
72            IYieldBoxBase _yieldBox
73:       ) OFTV2("USDO", "USDO", 8, _lzEndpoint) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L70-L73

File: tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol

22        constructor(
23            address _lzEndpoint,
24            IYieldBoxBase _yieldBox
25:       ) BaseUSDOStorage(_lzEndpoint, _yieldBox) {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L22-L25

File: tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol

25        constructor(
26            address _lzEndpoint,
27            IYieldBoxBase _yieldBox
28:       ) BaseUSDOStorage(_lzEndpoint, _yieldBox) {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L25-L28

File: tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol

19        constructor(
20            address _lzEndpoint,
21            IYieldBoxBase _yieldBox
22:       ) BaseUSDOStorage(_lzEndpoint, _yieldBox) {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L19-L22

File: tapioca-bar-audit/contracts/usd0/USDO.sol

35        constructor(
36            address _lzEndpoint,
37            IYieldBoxBase _yieldBox,
38            address _owner,
39            address payable _leverageModule,
40            address payable _marketModule,
41            address payable _optionsModule
42        )
43            BaseUSDO(
44                _lzEndpoint,
45                _yieldBox,
46                _owner,
47                _leverageModule,
48                _marketModule,
49                _optionsModule
50:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L35-L50

File: tapiocaz-audit/contracts/Balancer.sol

122       constructor(
123           address _routerETH,
124           address _router,
125           address _owner
126:      ) Owned(_owner) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L122-L126

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

67:       constructor(address _owner) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L67

File: tapiocaz-audit/contracts/tOFT/BaseTOFT.sol

50        constructor(
51            address _lzEndpoint,
52            address _erc20,
53            IYieldBoxBase _yieldBox,
54            string memory _name,
55            string memory _symbol,
56            uint8 _decimal,
57            uint256 _hostChainID,
58            address payable _leverageModule,
59            address payable _strategyModule,
60            address payable _marketModule,
61            address payable _optionsModule
62        )
63            BaseTOFTStorage(
64                _lzEndpoint,
65                _erc20,
66                _yieldBox,
67                _name,
68                _symbol,
69                _decimal,
70                _hostChainID
71            )
72:           ERC20Permit(string(abi.encodePacked("TapiocaOFT-", _name)))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L50-L72

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

45        constructor(
46            address _lzEndpoint,
47            address _erc20,
48            IYieldBoxBase _yieldBox,
49            string memory _name,
50            string memory _symbol,
51            uint8 _decimal,
52            uint256 _hostChainID
53        )
54            OFTV2(
55                string(abi.encodePacked("TapiocaOFT-", _name)),
56                string(abi.encodePacked("t", _symbol)),
57                _decimal / 2,
58                _lzEndpoint
59:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L45-L59

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol

25        constructor(
26            address _lzEndpoint,
27            address _erc20,
28            IYieldBoxBase _yieldBox,
29            string memory _name,
30            string memory _symbol,
31            uint8 _decimal,
32            uint256 _hostChainID
33        )
34            BaseTOFTStorage(
35                _lzEndpoint,
36                _erc20,
37                _yieldBox,
38                _name,
39                _symbol,
40                _decimal,
41                _hostChainID
42:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L25-L42

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol

24        constructor(
25            address _lzEndpoint,
26            address _erc20,
27            IYieldBoxBase _yieldBox,
28            string memory _name,
29            string memory _symbol,
30            uint8 _decimal,
31            uint256 _hostChainID
32        )
33            BaseTOFTStorage(
34                _lzEndpoint,
35                _erc20,
36                _yieldBox,
37                _name,
38                _symbol,
39                _decimal,
40                _hostChainID
41:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L24-L41

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol

19        constructor(
20            address _lzEndpoint,
21            address _erc20,
22            IYieldBoxBase _yieldBox,
23            string memory _name,
24            string memory _symbol,
25            uint8 _decimal,
26            uint256 _hostChainID
27        )
28            BaseTOFTStorage(
29                _lzEndpoint,
30                _erc20,
31                _yieldBox,
32                _name,
33                _symbol,
34                _decimal,
35                _hostChainID
36:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L19-L36

File: tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol

20        constructor(
21            address _lzEndpoint,
22            address _erc20,
23            IYieldBoxBase _yieldBox,
24            string memory _name,
25            string memory _symbol,
26            uint8 _decimal,
27            uint256 _hostChainID
28        )
29            BaseTOFTStorage(
30                _lzEndpoint,
31                _erc20,
32                _yieldBox,
33                _name,
34                _symbol,
35                _decimal,
36                _hostChainID
37:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L20-L37

File: tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol

49        constructor(
50            address _lzEndpoint,
51            address _erc20,
52            IYieldBoxBase _yieldBox,
53            string memory _name,
54            string memory _symbol,
55            uint8 _decimal,
56            uint256 _hostChainID,
57            address payable _leverageModule,
58            address payable _strategyModule,
59            address payable _marketModule,
60            address payable _optionsModule
61        )
62            BaseTOFT(
63                _lzEndpoint,
64                _erc20,
65                _yieldBox,
66                _name,
67                _symbol,
68                _decimal,
69                _hostChainID,
70                _leverageModule,
71                _strategyModule,
72                _marketModule,
73                _optionsModule
74:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L49-L74

File: tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol

33        constructor(
34            address _lzEndpoint,
35            address _erc20,
36            IYieldBoxBase _yieldBox,
37            string memory _name,
38            string memory _symbol,
39            uint8 _decimal,
40            uint256 _hostChainID,
41            address payable _leverageModule,
42            address payable _strategyModule,
43            address payable _marketModule,
44            address payable _optionsModule
45        )
46            BaseTOFT(
47                _lzEndpoint,
48                _erc20,
49                _yieldBox,
50                _name,
51                _symbol,
52                _decimal,
53                _hostChainID,
54                _leverageModule,
55                _strategyModule,
56                _marketModule,
57                _optionsModule
58:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L33-L58

File: tap-token-audit/contracts/governance/twTAP.sol

115       constructor(
116           address payable _tapOFT,
117           address _owner,
118           address _layerZeroEndpoint,
119           uint256 _hostChainID,
120           uint256 _minGas
121       )
122           ONFT721("Time Weighted TAP", "twTAP", _minGas, _layerZeroEndpoint)
123:          ERC721Permit("Time Weighted TAP")

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L115-L123

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

98        constructor(
99            address _aoTAP,
100           address payable _tapOFT,
101           address _pcnft,
102           address _paymentTokenBeneficiary,
103:          address _owner

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L98-L103

File: tap-token-audit/contracts/option-airdrop/aoTAP.sol

39        constructor(
40            address _owner
41:       ) ERC721("Airdrop Option TAP", "aoTAP") ERC721Permit("Airdrop Option TAP") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L39-L41

File: tap-token-audit/contracts/options/oTAP.sol

37:       constructor() ERC721("Option TAP", "oTAP") ERC721Permit("Option TAP") {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L37

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

81        constructor(
82            address _tOLP,
83            address _oTAP,
84            address payable _tapOFT,
85            address _paymentTokenBeneficiary,
86            uint256 _epochDuration,
87:           address _owner

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L81-L87

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

67        constructor(
68            address _yieldBox,
69            address _owner
70        )
71            ERC721("TapiocaOptionLiquidityProvision", "tOLP")
72:           ERC721Permit("TapiocaOptionLiquidityProvision")

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L67-L72

File: tap-token-audit/contracts/tokens/BaseTapOFT.sol

44        constructor(
45            string memory _name,
46            string memory _symbol,
47            uint8 _sharedDec,
48            address _lzEndpoint
49:       ) OFTV2(_name, _symbol, _sharedDec, _lzEndpoint) {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L44-L49

File: tap-token-audit/contracts/tokens/LTap.sol

32        constructor(
33            IERC20 _tapToken,
34            uint256 _maxLockedUntil
35:       ) ERC20("LTAP", "LTAP") ERC20Permit("LTAP") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L32-L35

File: tap-token-audit/contracts/tokens/TapOFT.sol

107       constructor(
108           address _lzEndpoint,
109           address _contributors,
110           address _earlySupporters,
111           address _supporters,
112           address _lbp,
113           address _dao,
114           address _airdrop,
115           uint256 _governanceChainId,
116           address _conservator
117:      ) BaseTapOFT("TapOFT", "TAP", 8, _lzEndpoint) ERC20Permit("TapOFT") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L107-L117

File: tap-token-audit/contracts/Vesting.sol

67:       constructor(uint256 _cliff, uint256 _duration, address _owner) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L67

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

44:       constructor(address _owner, address payable _marketModule) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L44

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

44        constructor(
45            string memory __name,
46            string memory __symbol,
47            ICurvePool pool,
48            AggregatorV2V3Interface btcFeed,
49            AggregatorV2V3Interface ethFeed,
50            AggregatorV2V3Interface usdtFeed,
51:           AggregatorV2V3Interface wbtcFeed

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L44-L51

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

10:       constructor(IGmxGlpManager glpManager_) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L10

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

30        constructor(
31            string memory __name,
32            string memory __symbol,
33            IStargatePool pool,
34:           AggregatorV2V3Interface _underlying

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L30-L34

File: tapioca-periph-audit/contracts/oracle/Seer.sol

12        constructor(
13            string memory __name,
14            string memory __symbol,
15            uint8 _decimals,
16            address[] memory addressInAndOutUni,
17            IUniswapV3Pool[] memory _circuitUniswap,
18            uint8[] memory _circuitUniIsMultiplied,
19            uint32 _twapPeriod,
20            uint16 observationLength,
21            uint8 _uniFinalCurrency,
22            address[] memory _circuitChainlink,
23            uint8[] memory _circuitChainIsMultiplied,
24            uint32 _stalePeriod,
25            address[] memory guardians,
26            bytes32 _description
27        )
28            OracleMulti(
29                addressInAndOutUni,
30                _circuitUniswap,
31                _circuitUniIsMultiplied,
32                _twapPeriod,
33                observationLength,
34                _uniFinalCurrency,
35                _circuitChainlink,
36                _circuitChainIsMultiplied,
37                _stalePeriod,
38                guardians,
39                _description
40:           )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L12-L40

File: tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol

36        constructor(
37            ICurvePool _curvePool,
38            IYieldBox _yieldBox
39:       ) validAddress(address(_curvePool)) validAddress(address(_yieldBox)) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L36-L39

File: tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol

30        constructor(
31            address _router,
32            address _factory,
33            IYieldBox _yieldBox
34        )
35            validAddress(_router)
36            validAddress(_factory)
37:           validAddress(address(_yieldBox))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L30-L37

File: tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol

45        constructor(
46            IYieldBox _yieldBox,
47            ISwapRouter _swapRouter,
48            IUniswapV3Factory _factory
49        )
50            validAddress(address(_yieldBox))
51            validAddress(address(_swapRouter))
52:           validAddress(address(_factory))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L45-L52

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

58        constructor(
59            IYieldBox _yieldBox,
60            address _token,
61            address _lendingPool,
62            address _incentivesController,
63            address _receiptToken,
64            address _multiSwapper
65:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L58-L65

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

58        constructor(
59            IYieldBox _yieldBox,
60            address _token,
61            address _vault,
62            bytes32 _poolId,
63            address _bal,
64            address _helpers
65:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L58-L65

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

50        constructor(
51            IYieldBox _yieldBox,
52            address _token,
53            address _cToken
54:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L50-L54

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

84        constructor(
85            IYieldBox _yieldBox,
86            address _token,
87            address _rewadPool,
88            address _booster,
89            address _zap,
90            address _lpGetter,
91            address _multiSwapper
92:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L84-L92

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

63        constructor(
64            IYieldBox _yieldBox,
65            address _token,
66            address _lpGauge,
67            address _lpGetter,
68            address _minter,
69            address _multiSwapper
70:       ) BaseERC20Strategy(_yieldBox, ITricryptoLPGetter(_lpGetter).lpToken()) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L63-L70

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

62        constructor(
63            IYieldBox _yieldBox,
64            address _token,
65            address _lpGauge,
66            address _lpGetter,
67            address _minter,
68            address _multiSwapper
69:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L62-L69

File: tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol

53        constructor(
54            IYieldBox _yieldBox,
55            IGmxRewardRouterV2 _gmxRewardRouter,
56            IGmxRewardRouterV2 _glpRewardRouter,
57            IERC20 _sGlp
58:       ) BaseERC20Strategy(_yieldBox, address(_sGlp)) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L53-L58

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

52        constructor(
53            IYieldBox _yieldBox,
54            address _token,
55            address _stEth,
56            address _curvePool
57:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L52-L57

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

67        constructor(
68            IYieldBox _yieldBox,
69            address _token,
70            address _ethRouter,
71            address _lpStaking,
72            uint256 _stakingPid,
73            address _lpToken,
74            address _swapper,
75            address _stgEthPool
76:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L67-L76

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

51        constructor(
52            IYieldBox _yieldBox,
53            address _token,
54            address _vault
55:       ) BaseERC20Strategy(_yieldBox, _token) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L51-L55

File: YieldBox/contracts/YieldBoxPermit.sol

40:       constructor(string memory name) EIP712(name, "1") {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L40

File: YieldBox/contracts/YieldBox.sol

91:       constructor(IWrappedNative wrappedNative_, YieldBoxURIBuilder uriBuilder_) YieldBoxPermit("YieldBox") {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L91

@thebrittfactor
Copy link

[G‑30] Structs can be packed into fewer storage slots

Each slot saved can avoid an extra Gsset (20000 gas) for the first setting of the struct. Subsequent reads as well as writes have smaller gas savings

There are 5 instances of this issue:

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

/// @audit Variable ordering with 2 slots instead of the current 3:
///           bytes(32):bytecode, address(20):toft, bool(1):revertOnFailure
27        struct ExecutionCall {
28            address toft;
29            bytes bytecode;
30            bool revertOnFailure;
31:       }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L27-L31

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

/// @audit Variable ordering with 3 slots instead of the current 4:
///           uint256(32):value, bytes(32):call, address(20):target, uint16(2):id, bool(1):allowFailure
78        struct Call {
79            uint16 id;
80            address target;
81            uint256 value;
82            bool allowFailure;
83            bytes call;
84:       }

/// @audit Variable ordering with 6 slots instead of the current 7:
///           uint256(32):value, uint256(32):deadline, bytes32(32):r, bytes32(32):s, address(20):owner, uint8(1):v, address(20):spender
91        struct PermitData {
92            address owner;
93            address spender;
94            uint256 value;
95            uint256 deadline;
96            uint8 v;
97            bytes32 r;
98            bytes32 s;
99:       }

/// @audit Variable ordering with 5 slots instead of the current 6:
///           uint256(32):deadline, bytes32(32):r, bytes32(32):s, address(20):owner, uint8(1):v, address(20):spender
101       struct PermitAllData {
102           address owner;
103           address spender;
104           uint256 deadline;
105           uint8 v;
106           bytes32 r;
107           bytes32 s;
108:      }

/// @audit Variable ordering with 5 slots instead of the current 6:
///           uint256(32):collateralAmount, uint256(32):borrowAmount, bytes(32):withdrawData, address(20):market, bool(1):extractFromSender, bool(1):deposit, bool(1):withdraw, address(20):user
212       struct HelperBorrowData {
213           address market;
214           address user;
215           uint256 collateralAmount;
216           uint256 borrowAmount;
217           bool extractFromSender;
218           bool deposit;
219           bool withdraw;
220           bytes withdrawData;
221:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L78-L84

[G‑31] Inverting the condition of an if-else-statement wastes gas

Flipping the true and false blocks instead saves 3 gas

There is one instance of this issue:

File: tapiocaz-audit/contracts/TapiocaWrapper.sol

190           if (!_linked) {
191               TapiocaOFT toft = TapiocaOFT(
192                   payable(
193                       Create2.deploy(
194                           0,
195                           keccak256(
196                               abi.encodePacked(
197                                   keccak256(_bytecode),
198                                   address(this),
199                                   _erc20,
200                                   _salt
201                               )
202                           ),
203                           _bytecode
204                       )
205                   )
206               );
207               oft = address(toft);
208           } else {
209               mTapiocaOFT toft = mTapiocaOFT(
210                   payable(
211                       Create2.deploy(
212                           0,
213                           keccak256(
214                               abi.encodePacked(
215                                   keccak256(_bytecode),
216                                   address(this),
217                                   _erc20,
218                                   _salt
219                               )
220                           ),
221                           _bytecode
222                       )
223                   )
224               );
225               oft = address(toft);
226:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L190-L226

[G‑32] Division by two should use bit shifting

<x> / 2 is the same as <x> >> 1. While the compiler uses the SHR opcode to accomplish both, the version that uses division incurs an overhead of 20 gas due to JUMPs to and from a compiler utility function that introduces checks which can be avoided by using unchecked {} around the division by two

There are 3 instances of this issue:

File: tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol

57:               _decimal / 2,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L57

File: tap-token-audit/contracts/twAML.sol

150:              uint256 x = y / 2 + 1;

153:                  x = (y / x + x) / 2;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L150

[G‑33] Structs can be packed into fewer storage slots by truncating timestamp bytes

By using a uint32 rather than a larger type for variables that track timestamps, one can save gas by using fewer storage slots per struct, at the expense of the protocol breaking after the year 2106 (when uint32 wraps). If this is an acceptable tradeoff, each slot saved can avoid an extra Gsset (20000 gas) for the first setting of the struct. Subsequent reads as well as writes have smaller gas savings

There is one instance of this issue:

File: tap-token-audit/contracts/Vesting.sol

/// @audit Variable ordering with 3 slots instead of the current 4:
///           uint256(32):amount, uint256(32):claimed, uint32(4):latestClaimTimestamp, bool(1):revoked
32        struct UserData {
33            uint256 amount;
34            uint256 claimed;
35            uint256 latestClaimTimestamp;
36            bool revoked;
37:       }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L32-L37

[G‑34] Multiple accesses of a mapping/array should use a local variable cache

The instances below point to the second+ access of a value inside a mapping/array, within a function. Caching a mapping's value in a local storage or calldata variable when the value is accessed multiple times, saves ~42 gas per access due to not having to recalculate the key's keccak256 hash (Gkeccak256 - 30 gas) and that calculation's associated stack operations. Caching an array's struct avoids recalculating the array offsets into memory/calldata

There are 10 instances of this issue:

File: tap-token-audit/contracts/governance/twTAP.sol

/// @audit weekTotals[<etc>] on line 343
344:          weekTotals[w1 + 1].netActiveVotes -= int256(votes);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L344

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit paymentTokens[_paymentToken] on line 349
350:          paymentTokens[_paymentToken].oracleData = _oracleData;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L350

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

/// @audit paymentTokens[_paymentToken] on line 463
464:          paymentTokens[_paymentToken].oracleData = _oracleData;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L464

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

/// @audit activeSingularities[_singularity] on line 180
187:          activeSingularities[_singularity].totalDeposited += _amount;

/// @audit activeSingularities[_singularity] on line 221
247:          activeSingularities[_singularity].totalDeposited -= lockPosition.amount;

/// @audit activeSingularities[singularity] on line 264
267:          activeSingularities[singularity].poolWeight = weight;

/// @audit activeSingularities[singularity] on line 283
287:          activeSingularities[singularity].sglAssetID = assetID;

/// @audit activeSingularities[singularity] on line 287
288:          activeSingularities[singularity].poolWeight = weight > 0 ? weight : 1;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L187

File: tap-token-audit/contracts/Vesting.sol

/// @audit users[_user] on line 86
86:           return _vested(users[_user].amount) - users[_user].claimed;

/// @audit users[<etc>] on line 116
117:          users[msg.sender].latestClaimTimestamp = block.timestamp;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L86

[G‑35] internal functions only called once can be inlined to save gas

Not inlining costs 20 to 40 gas because of two extra JUMP instructions and additional stack operations needed for function calls.

There are 26 instances of this issue:

see instances
File: tap-token-audit/contracts/governance/twTAP.sol

483:      function _claimRewards(uint256 _tokenId, address _to) internal {

499       function _claimRewardsOn(
500           uint256 _tokenId,
501           address _to,
502:          IERC20[] memory _rewardTokens

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L483

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

390:      function _participatePhase1() internal returns (uint256 oTAPTokenID) {

410       function _participatePhase2(
411           bytes calldata _data
412:      ) internal returns (uint256 oTAPTokenID) {

442       function _participatePhase3(
443           bytes calldata _data
444:      ) internal returns (uint256 oTAPTokenID) {

465:      function _participatePhase4() internal returns (uint256 oTAPTokenID) {

487       function _processOTCDeal(
488           ERC20 _paymentToken,
489           PaymentTokenOracle memory _paymentTokenOracle,
490           uint256 tapAmount,
491:          uint256 discount

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L390

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

508       function _processOTCDeal(
509           ERC20 _paymentToken,
510           PaymentTokenOracle memory _paymentTokenOracle,
511           uint256 tapAmount,
512:          uint256 discount

559:      function _emitToGauges(uint256 _epochTAP) internal {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L508-L512

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

336:      function _computeSGLPoolWeights() internal view returns (uint256) {

348:      function _isPositionActive(uint256 tokenId) internal view returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L336

File: tap-token-audit/contracts/tokens/TapOFT.sol

253:      function _computeEmission() internal view returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L253

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

225:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L225

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

130:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L130

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

113:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L113

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

291:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L291

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

210:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L210

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

196:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L196

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

118:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L118

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

214:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L214

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

111:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L111

File: YieldBox/contracts/YieldBox.sol

247       function _withdrawNFT(
248           Asset storage asset,
249           uint256 assetId,
250           address from,
251           address to
252:      ) internal returns (uint256 amountOut, uint256 shareOut) {

270       function _withdrawFungible(
271           Asset storage asset,
272           uint256 assetId,
273           address from,
274           address to,
275           uint256 amount,
276           uint256 share
277:      ) internal returns (uint256 amountOut, uint256 shareOut) {

316:      function _transferBatch(address from, address to, uint256[] calldata ids, uint256[] calldata values) internal override {

371:      function _setApprovalForAll(address _owner, address operator, bool approved) internal override {

394:      function _setApprovalForAsset(address _owner, address operator, uint256 assetId, bool approved) internal override {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L247-L252

[G‑36] require()/revert() strings longer than 32 bytes cost extra gas

Each extra memory word of bytes past the original 32 incurs an MSTORE which costs 3 gas

There are 23 instances of this issue:

see instances
File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

368           require(
369               paymentTokenBeneficiary != address(0),
370               "adb: Payment token beneficiary not set"
371:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L368-L371

File: tap-token-audit/contracts/options/TapiocaOptionBroker.sol

297:          require(oTAP.exists(_oTAPTokenID), "tOB: oTAP position does not exist");

482           require(
483               paymentTokenBeneficiary != address(0),
484               "tOB: Payment token beneficiary not set"
485:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L297

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol

337:          require(_from == msg.sender, "MagnetarV2: operator not approved");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2Storage.sol#L337

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

527               require(
528                   ownerOfTapTokenId == user || ownerOfTapTokenId == address(this),
529                   "Magnetar: oTAPTokenID owner mismatch"
530:              );

743:          require(withdrawData.length > 0, "MagnetarV2: withdrawData is empty");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L527-L530

File: tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol

102           require(
103               success && (data.length == 0 || abi.decode(data, (bool))),
104               "BaseSwapper::safeApprove: approve failed"
105:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L102-L105

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

184           require(
185               lpBalanceAfter > lpBalanceBefore,
186               "BalancerStrategy: vault deposit failed"
187:          );

196:          require(available >= amount, "BalancerStrategy: amount not valid");

263           require(
264               wrappedNativeBalanceAfter > wrappedNativeBalanceBefore,
265               "BalancerStrategy: vault withdrawal failed"
266:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L184-L187

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

141:          require(available >= amount, "CompoundStrategy: amount not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L141

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

245           require(
246               tempData.rewardContracts.length == tempData.tokens.length,
247               "ConvexTricryptoStrategy: claim data not valid"
248:          );

249           require(
250               tempData.rewardContracts.length > 0,
251               "ConvexTricryptoStrategy: nothing to claim for"
252:          );

325           require(
326               available >= amount,
327               "ConvexTricryptoStrategy: amount not valid"
328:          );

340           require(
341               wrappedNative.balanceOf(address(this)) >= amount,
342               "ConvexTricryptoStrategy: not enough"
343:          );

363           require(
364               successEmtptyApproval,
365               "OperationsLib::safeApprove: approval reset failed"
366:          );

376           require(
377               success && (data.length == 0 || abi.decode(data, (bool))),
378               "OperationsLib::safeApprove: approve failed"
379:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L245-L248

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

234:          require(available >= amount, "TricryptoLPStrategy: amount not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L234

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

221           require(
222               available >= amount,
223               "TricryptoNativeStrategy: amount not valid"
224:          );

235           require(
236               wrappedNative.balanceOf(address(this)) >= amount,
237               "TricryptoNativeStrategy: not enough"
238:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L221-L224

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

246:          require(available >= amount, "StargateStrategy: amount not valid");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L246

File: YieldBox/contracts/YieldBoxPermit.sol

58:           require(signer == owner, "YieldBoxPermit: invalid signature");

87:           require(signer == owner, "YieldBoxPermit: invalid signature");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L58

[G‑37] keccak256() should only need to be called on a specific string literal once

It should be saved to an immutable variable, and the variable used instead. If the hash is being used as a part of a function selector, the cast to bytes4 should also only be done once

There are 3 instances of this issue:

File: tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol

366                   keccak256(
367                       "onERC1155Received(address,address,uint256,uint256,bytes)"
368:                  )

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L366-L368

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

358:                  bytes4(keccak256("approve(address,uint256)")),

371:                  bytes4(keccak256("approve(address,uint256)")),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L358

[G‑38] Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.

https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html
Each operation involving a uint8 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8) as compared to ones involving uint256, due to the compiler having to clear the higher bits of the memory word before operating on the uint8, as well as the associated stack operations of doing so. Use a larger size then downcast where needed

There are 5 instances of this issue:

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

/// @audit uint64 lastEpochUpdate
287:          lastEpochUpdate = uint64(block.timestamp);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L287

File: YieldBox/contracts/BoringMath.sol

/// @audit uint128 c
7:            c = uint128(a);

/// @audit uint64 c
12:           c = uint64(a);

/// @audit uint32 c
17:           c = uint32(a);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/BoringMath.sol#L7

File: YieldBox/contracts/NativeTokenFactory.sol

/// @audit uint32 tokenId
92:           tokenId = assets.length.to32();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L92

[G‑39] Stack variable used as a cheaper cache for a state variable is only used once

If the variable is only accessed once, it's cheaper to use the state variable directly that one time, and save the 3 gas the extra stack assignment would spend

There is one instance of this issue:

File: tap-token-audit/contracts/option-airdrop/AirdropBroker.sol

160:          uint256 cachedEpoch = epoch;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L160

[G‑40] Consider using bytes32 rather than a string

Using the bytes types for fixed-length strings is more efficient than having the EVM have to incur the overhead of string processing. Consider whether the value needs to be a string. A good reason to keep it as a string would be if the variable is defined in an interface that this project does not own.

There are 8 instances of this issue:

File: contracts/oracle/Seer.sol

8:       string public _name;

9:       string public _symbol;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L8-L8

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

31:      string public _name;

32:      string public _symbol;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L31-L31

File: contracts/oracle/implementations/SGOracle.sol

24:      string public _name;

25:      string public _symbol;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L24-L24

File: contracts/glp/GlpStrategy.sol

26:      string public constant override name = "sGLP";

27       string public constant override description =
28:          "Holds staked GLP tokens and compounds the rewards";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L26-L26

[G‑41] The result of function calls should be cached rather than re-calling the function

The instances below point to the second+ call of the function within a single function

There are 8 instances of this issue:

File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit market.oracle() on line 918
930:          (, info.oracleExchangeRate) = IOracle(market.oracle()).peek(

/// @audit market.oracleData() on line 919
931:              market.oracleData()

/// @audit market.oracle() on line 918
933:          info.spotExchangeRate = IOracle(market.oracle()).peekSpot(

/// @audit market.oracleData() on line 919
934:              market.oracleData()

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L930

File: tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol

/// @audit marketInterface.collateralId() on line 264
279:                      marketInterface.collateralId(),

/// @audit bigBang.assetId() on line 627
629:                          bigBang.assetId(),

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L279

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit stakedRewardToken.cooldown() on line 172
175:              stakedRewardToken.cooldown();

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L175

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit lpGetter.lpToken() on line 78
79:           IERC20(lpGetter.lpToken()).approve(_lpGetter, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L79

[G‑42] Use a more recent version of solidity

Use a solidity version of at least 0.8.2 to get simple compiler automatic inlining
Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads
Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings
Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value

There are 2 instances of this issue:

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

2:    pragma solidity >=0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L2

File: YieldBox/contracts/YieldBoxPermit.sol

3:    pragma solidity ^0.8.0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L3

[G‑43] Not using the named return variables anywhere in the function is confusing

Consider changing the variable to be an unnamed one, since the variable is never assigned, nor is it returned by name. If the optimizer is not turned on, leaving the code as it is will also waste gas for the stack variable.

There are 69 instances of this issue:

see instances
File: tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol

/// @audit amount
76        function getCollateralAmountForShare(
77            IMarket market,
78            uint256 share
79:       ) public view returns (uint256 amount) {

/// @audit collateralShares
89        function getCollateralSharesForBorrowPart(
90            IMarket market,
91            uint256 borrowPart,
92            uint256 liquidationMultiplierPrecision,
93            uint256 exchangeRatePrecision
94:       ) public view returns (uint256 collateralShares) {

/// @audit amount
117       function getAmountForBorrowPart(
118           IMarket market,
119           uint256 borrowPart
120:      ) public view returns (uint256 amount) {

/// @audit part
133       function getBorrowPartForAmount(
134           IMarket market,
135           uint256 amount
136:      ) public view returns (uint256 part) {

/// @audit amount
150       function getAmountForAssetFraction(
151           ISingularity singularity,
152           uint256 fraction
153:      ) public view returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L76-L79

File: tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol

/// @audit success
/// @audit rate
71        function get(
72            bytes calldata
73:       ) external virtual returns (bool success, uint256 rate) {

/// @audit success
/// @audit rate
82        function peek(
83            bytes calldata
84:       ) external view virtual returns (bool success, uint256 rate) {

/// @audit rate
92        function peekSpot(
93            bytes calldata
94:       ) external view virtual returns (uint256 rate) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L71-L73

File: tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol

/// @audit success
/// @audit rate
24        function get(
25            bytes calldata
26:       ) public view override returns (bool success, uint256 rate) {

/// @audit success
/// @audit rate
32        function peek(
33            bytes calldata
34:       ) public view override returns (bool success, uint256 rate) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/GLPOracle.sol#L24-L26

File: tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol

/// @audit _maxPrice
49:       function _get() internal view returns (uint256 _maxPrice) {

/// @audit success
/// @audit rate
61        function get(
62            bytes calldata
63:       ) external virtual returns (bool success, uint256 rate) {

/// @audit success
/// @audit rate
72        function peek(
73            bytes calldata
74:       ) external view virtual returns (bool success, uint256 rate) {

/// @audit rate
82        function peekSpot(
83            bytes calldata
84:       ) external view virtual returns (uint256 rate) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/SGOracle.sol#L49

File: tapioca-periph-audit/contracts/oracle/Seer.sol

/// @audit success
/// @audit rate
52        function get(
53            bytes calldata
54:       ) external virtual returns (bool success, uint256 rate) {

/// @audit success
/// @audit rate
64        function peek(
65            bytes calldata
66:       ) external view virtual returns (bool success, uint256 rate) {

/// @audit rate
75        function peekSpot(
76            bytes calldata
77:       ) external view virtual returns (uint256 rate) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L52-L54

File: tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol

/// @audit name_
83:       function name() external pure override returns (string memory name_) {

/// @audit description_
88        function description()
89            external
90            pure
91            override
92:           returns (string memory description_)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L83

File: tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol

/// @audit name_
85:       function name() external pure override returns (string memory name_) {

/// @audit description_
90        function description()
91            external
92            pure
93            override
94:           returns (string memory description_)

/// @audit result
100:      function compoundAmount() external pure returns (uint256 result) {

/// @audit amount
130:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L85

File: tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol

/// @audit name_
65:       function name() external pure override returns (string memory name_) {

/// @audit description_
70        function description()
71            external
72            pure
73            override
74:           returns (string memory description_)

/// @audit result
80:       function compoundAmount() public pure returns (uint256 result) {

/// @audit amount
113:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L65

File: tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol

/// @audit name_
115:      function name() external pure override returns (string memory name_) {

/// @audit description_
120       function description()
121           external
122           pure
123           override
124:          returns (string memory description_)

/// @audit amount
291:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L115

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol

/// @audit name_
89:       function name() external pure override returns (string memory name_) {

/// @audit description_
94        function description()
95            external
96            pure
97            override
98:           returns (string memory description_)

/// @audit amount
210:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L89

File: tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol

/// @audit name_
88:       function name() external pure override returns (string memory name_) {

/// @audit description_
93        function description()
94            external
95            pure
96            override
97:           returns (string memory description_)

/// @audit amount
196:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L88

File: tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol

/// @audit name_
69:       function name() external pure override returns (string memory name_) {

/// @audit description_
74        function description()
75            external
76            pure
77            override
78:           returns (string memory description_)

/// @audit result
84:       function compoundAmount() public pure returns (uint256 result) {

/// @audit amount
118:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L69

File: tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol

/// @audit name_
101:      function name() external pure override returns (string memory name_) {

/// @audit description_
106       function description()
107           external
108           pure
109           override
110:          returns (string memory description_)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L101

File: tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol

/// @audit name_
66:       function name() external pure override returns (string memory name_) {

/// @audit description_
71        function description()
72            external
73            pure
74            override
75:           returns (string memory description_)

/// @audit result
81:       function compoundAmount() public pure returns (uint256 result) {

/// @audit amount
111:      function _currentBalance() internal view override returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L66

File: YieldBox/contracts/YieldBox.sol

/// @audit amount
102:      function _tokenBalanceOf(Asset storage asset) internal view returns (uint256 amount) {

/// @audit amountOut
/// @audit shareOut
118       function depositAsset(
119           uint256 assetId,
120           address from,
121           address to,
122           uint256 amount,
123           uint256 share
124:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

/// @audit amountOut
/// @audit shareOut
168       function depositNFTAsset(
169           uint256 assetId,
170           address from,
171           address to
172:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

/// @audit amountOut
/// @audit shareOut
196:      function depositETHAsset(uint256 assetId, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

/// @audit amountOut
/// @audit shareOut
223       function withdraw(
224           uint256 assetId,
225           address from,
226           address to,
227           uint256 amount,
228           uint256 share
229:      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

/// @audit amountOut
/// @audit shareOut
247       function _withdrawNFT(
248           Asset storage asset,
249           uint256 assetId,
250           address from,
251           address to
252:      ) internal returns (uint256 amountOut, uint256 shareOut) {

/// @audit amountOut
/// @audit shareOut
270       function _withdrawFungible(
271           Asset storage asset,
272           uint256 assetId,
273           address from,
274           address to,
275           uint256 amount,
276           uint256 share
277:      ) internal returns (uint256 amountOut, uint256 shareOut) {

/// @audit amountOut
/// @audit shareOut
500:      function depositETH(IStrategy strategy, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L102

[G‑44] Avoid contract existence checks by using low level calls

Prior to 0.8.10 the compiler inserted extra code, including EXTCODESIZE (100 gas), to check for contract existence for external function calls. In more recent solidity versions, the compiler will not insert these checks if the external call has a return value. Similar behavior can be achieved in earlier versions by using low-level calls, since low level calls never check for contract existence

There are 2 instances of this issue:

File: YieldBox/contracts/YieldBoxURIBuilder.sol

/// @audit toHexString()
90:                   abi.encodePacked("ERC1155:", uint256(uint160(asset.contractAddress)).toHexString(20), "/", asset.tokenId.toString())

/// @audit toHexString()
106:                  ? abi.encodePacked(',"tokenAddress":"', uint256(uint160(asset.contractAddress)).toHexString(20), '"')

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L90

[G‑45] String literals passed to abi.encode()/abi.encodePacked() should not be split by commas

String literals can be split into multiple parts and still be considered as a single string literal. Adding commas between each chunk makes it no longer a single string, and instead multiple strings. EACH new comma costs 21 gas due to stack operations and separate MSTOREs

There is one instance of this issue:

File: YieldBox/contracts/YieldBoxURIBuilder.sol

/// @audit 1 commas
61:                   return string(abi.encodePacked("ERC1155", " (", asset.strategy.name(), ")"));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L61

Disputed Issues

The issues below may be reported by other bots/wardens, but can be penalized/ignored since either the rule or the specified instances are invalid

[D‑01] Storage Write Removal Bug On Conditional Early Termination

In solidity versions 0.8.13 through 0.8.16, there is a bug involving the use of the Yul functions return() and stop(). If those functions aren't called, or if the Solidity version doesn't match, the finding is invalid.

There are 16 instances of this issue:

see instances
File: contracts/Penrose.sol

478          assembly {
479              // Slice the sighash.
480              _returnData := add(_returnData, 0x04)
481:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L478-L481

File: contracts/markets/Market.sol

378          assembly {
379              // Slice the sighash.
380              _returnData := add(_returnData, 0x04)
381:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L378-L381

File: contracts/usd0/BaseUSDOStorage.sol

93           assembly {
94               // Slice the sighash.
95               _returnData := add(_returnData, 0x04)
96:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L93-L96

File: contracts/tOFT/BaseTOFTStorage.sol

73           assembly {
74               // Slice the sighash.
75               _returnData := add(_returnData, 0x04)
76:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L73-L76

File: contracts/governance/twTAP.sol

573          assembly {
574              chainId := chainid()
575:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L573-L575

File: contracts/twAML.sol

21           assembly {
22               let mm := mulmod(a, b, not(0))
23               prod0 := mul(a, b)
24               prod1 := sub(sub(mm, prod0), lt(mm, prod0))
25:          }

33               assembly {
34                   result := div(prod0, denominator)
35:              }

50           assembly {
51               remainder := mulmod(a, b, denominator)
52:          }

54           assembly {
55               prod1 := sub(prod1, gt(remainder, prod0))
56               prod0 := sub(prod0, remainder)
57:          }

64           assembly {
65               denominator := div(denominator, twos)
66:          }

69           assembly {
70               prod0 := div(prod0, twos)
71:          }

75           assembly {
76               twos := add(div(sub(0, twos), twos), 1)
77:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/twAML.sol#L21-L25

File: contracts/Magnetar/MagnetarV2.sol

1082         assembly {
1083             // Slice the sighash.
1084             _returnData := add(_returnData, 0x04)
1085:        }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L1082-L1085

File: contracts/Multicall/Multicall3.sol

98           assembly {
99               // Slice the sighash.
100              _returnData := add(_returnData, 0x04)
101:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L98-L101

File: contracts/TapiocaDeployer/TapiocaDeployer.sol

40           assembly {
41               addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
42:          }

73           assembly {
74               let ptr := mload(0x40) // Get free memory pointer
75   
76               // |                   | ↓ ptr ...  ↓ ptr + 0x0B (start) ...  ↓ ptr + 0x20 ...  ↓ ptr + 0x40 ...   |
77               // |-------------------|---------------------------------------------------------------------------|
78               // | bytecodeHash      |                                                        CCCCCCCCCCCCC...CC |
79               // | salt              |                                      BBBBBBBBBBBBB...BB                   |
80               // | deployer          | 000000...0000AAAAAAAAAAAAAAAAAAA...AA                                     |
81               // | 0xFF              |            FF                                                             |
82               // |-------------------|---------------------------------------------------------------------------|
83               // | memory            | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
84               // | keccak(start, 85) |            ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
85   
86               mstore(add(ptr, 0x40), bytecodeHash)
87               mstore(add(ptr, 0x20), salt)
88               mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
89               let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
90               mstore8(start, 0xff)
91               addr := keccak256(start, 85)
92:          }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/TapiocaDeployer/TapiocaDeployer.sol#L40-L42

[D‑02] Do not calculate constant variables, which will save gas

The compiler automatically expands simple expressions into their literal values, so manually doing the expansion doesn't save gas, and this finding is invalid

There are 5 instances of this issue:

File: contracts/markets/MarketERC20.sol

29       bytes32 private constant _PERMIT_TYPEHASH =
30           keccak256(
31               "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
32:          );

33       bytes32 private constant _PERMIT_TYPEHASH_BORROW =
34           keccak256(
35               "PermitBorrow(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
36:          );

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L29-L32

File: contracts/usd0/BaseUSDOStorage.sol

38       bytes32 internal constant FLASH_MINT_CALLBACK_SUCCESS =
39:          keccak256("ERC3156FlashBorrower.onFlashLoan");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L38-L39

File: contracts/YieldBoxPermit.sol

27       bytes32 private constant _PERMIT_TYPEHASH =
28:          keccak256("Permit(address owner,address spender,uint256 assetId,uint256 nonce,uint256 deadline)");

31       bytes32 private constant _PERMIT_ALL_TYPEHASH =
32:          keccak256("PermitAll(address owner,address spender,uint256 nonce,uint256 deadline)");

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L27-L28

[D‑03] Use delete instead of setting mapping/state variable to zero, to save gas

Using delete instead of assigning zero to state variables does not save any extra gas with the optimizer on (saves 5-8 gas with optimizer completely off), so this finding is invalid, especially since if they were interested in gas savings, they'd have the optimizer enabled.

There are 16 instances of this issue:

see instances
File: contracts/markets/bigBang/BigBang.sol

460:             totalFees = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L460-L460

File: contracts/markets/singularity/SGLCommon.sol

246:                 _yieldBoxShares[from][ASSET_SIG] = 0; //some assets accrue in time

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L246-L246

File: contracts/markets/singularity/SGLLendingCommon.sol

51:              _yieldBoxShares[from][COLLATERAL_SIG] = 0; //accrues in time

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L51-L51

File: contracts/markets/singularity/Singularity.sol

467:         accrueInfo.feesEarnedFraction = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L467-L467

File: contracts/Vesting.sol

138:         data.claimed = 0;

140:         data.latestClaimTimestamp = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L138-L138

File: contracts/governance/twTAP.sol

160:             participant.multiplier = 0;

293:                     pool.cumulative = 0;

547:                     pool.cumulative = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L160-L160

File: contracts/option-airdrop/AirdropBroker.sol

395:         phase1Users[msg.sender] = 0;

470:         phase4Users[msg.sender] = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L395-L395

File: contracts/options/TapiocaOptionBroker.sol

256:                     pool.cumulative = 0;

318:                     pool.cumulative = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L256-L256

File: contracts/balancer/BalancerStrategy.sol

161:                 maxAmountsIn[i] = 0;

230:                 minAmountsOut[i] = 0;

281:             minAmountsOut[i] = 0;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L161-L161

[D‑04] abi.encode() is less efficient than abi.encodepacked()

abi.encodePacked() does not always save gas over abi.encode() and in fact often costs more gas. The comparison sometimes linked to itself even shows that when addresses are involved, the packed flavor costs more gas. Furthermore, the test was done on Solidity 0.4.24, and there have been a lot of changes since then. Without more specific tests or explanations, it's not correct to say that the change always saves gas.

There are 17 instances of this issue:

see instances
File: contracts/usd0/modules/USDOLeverageModule.sol

72:          bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L72-L72

File: contracts/usd0/modules/USDOMarketModule.sol

40:          bytes memory lzPayload = abi.encode(

78:          bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L40-L40

File: contracts/usd0/modules/USDOOptionsModule.sol

32:          bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L32-L32

File: contracts/Balancer.sol

316:                 dstNativeAddr: abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L316-L316

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

56:          bytes memory lzPayload = abi.encode(

89:          bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L56-L56

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

56:          bytes memory lzPayload = abi.encode(

105:         bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L56-L56

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

47:          bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L47-L47

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

60:          bytes memory lzPayload = abi.encode(

102:         bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L60-L60

File: contracts/tokens/BaseTapOFT.sol

96:          bytes memory lzPayload = abi.encode(

172:         bytes memory lzPayload = abi.encode(

266:         bytes memory lzPayload = abi.encode(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L96-L96

File: contracts/YieldBoxPermit.sol

53:          bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, assetId, _useNonce(owner), deadline));

82:          bytes32 structHash = keccak256(abi.encode(_PERMIT_ALL_TYPEHASH, owner, spender, _useNonce(owner), deadline));

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L53-L53

[D‑05] Contracts do not work with fee-on-transfer tokens

An ERC20 token being used, in and of itself, is not evidence of a fee-on-transfer issue; there must be other evidence that the balance accounting gets broken, and these lines do not contain such evidence.

There are 72 instances of this issue:

see instances
File: contracts/Penrose.sol

292:         usdoToken = IERC20(_usdoToken);

298:                     IERC20(_usdoToken)

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L292-L292

File: contracts/markets/bigBang/BigBang.sol

116:                     IERC20,

140:         asset = IERC20(_asset);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L116-L116

File: contracts/markets/singularity/Singularity.sol

83:                      IERC20,

85:                      IERC20,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L83-L83

File: contracts/usd0/modules/USDOLeverageModule.sol

217:         IERC20(swapData.tokenOut).approve(externalData.tOft, amountOut);

289:                     IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L217-L217

File: contracts/usd0/modules/USDOMarketModule.sol

278:                     IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L278-L278

File: contracts/usd0/modules/USDOOptionsModule.sol

279:                     IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L279-L279

File: contracts/TapiocaWrapper.sol

160:         if (address(tapiocaOFTsByErc20[_erc20]) != address(0x0)) {

161:             revert TapiocaWrapper__AlreadyDeployed(_erc20);

165:             _createTOFT(_erc20, _bytecode, _salt, _linked)

167:         if (address(iOFT.erc20()) != _erc20) {

172:         tapiocaOFTsByErc20[_erc20] = iOFT;

177:         emit CreateOFT(iOFT, _erc20);

217:                                 _erc20,

199:                                 _erc20,

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L160-L160

File: contracts/tOFT/BaseTOFT.sol

65:              _erc20,

460:                     IERC20(address(this))

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L65-L65

File: contracts/tOFT/BaseTOFTStorage.sol

61:          erc20 = _erc20;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L61-L61

File: contracts/tOFT/TapiocaOFT.sol

48:              _erc20,

74:          if (erc20 == address(0)) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L48-L48

File: contracts/tOFT/mTapiocaOFT.sol

64:              _erc20,

94:          if (erc20 == address(0)) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L64-L64

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

36:              _erc20,

215:         IERC20(erc20).approve(externalData.swapper, amount);

217:             .buildSwapData(erc20, swapData.tokenOut, amount, 0, false, false);

319:                     IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L36-L36

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

35:              _erc20,

295:                     IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L35-L35

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

30:              _erc20,

294:                     IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L30-L30

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

31:              _erc20,

184:         _erc20.approve(address(yieldBox), _amount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L31-L31

File: contracts/tokens/BaseTapOFT.sol

335:                 IERC20Permit(approvals[i].target).permit(

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L335-L335

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

157:             IERC20(collateralAddress).approve(

234:             IERC20(assetAddress).approve(address(yieldBox), depositAmount);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L157-L157

File: contracts/aave/AaveStrategy.sol

66:          wrappedNative = IERC20(_token);

72:          rewardToken = IERC20(stakedRewardToken.REWARD_TOKEN());

73:          receiptToken = IERC20(_receiptToken);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L66-L66

File: contracts/balancer/BalancerStrategy.sol

66:          wrappedNative = IERC20(_token);

67:          bal = IERC20(_bal);

78:          IERC20(address(pool)).approve(_vault, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L66-L66

File: contracts/compound/CompoundStrategy.sol

55:          wrappedNative = IERC20(_token);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L55-L55

File: contracts/convex/ConvexTricryptoStrategy.sol

93:          wrappedNative = IERC20(_token);

102:         lpToken = IERC20(booster.poolInfo(pid).lptoken);

103:         rewardToken = IERC20(rewardPool.rewardToken());

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L93-L93

File: contracts/curve/TricryptoLPStrategy.sol

71:          wrappedNative = IERC20(_token);

76:          lpToken = IERC20(lpGetter.lpToken());

77:          rewardToken = IERC20(lpGauge.crv_token());

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L71-L71

File: contracts/curve/TricryptoNativeStrategy.sol

70:          wrappedNative = IERC20(_token);

76:          rewardToken = IERC20(lpGauge.crv_token());

78:          IERC20(lpGetter.lpToken()).approve(_lpGauge, type(uint256).max);

79:          IERC20(lpGetter.lpToken()).approve(_lpGetter, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L70-L70

File: contracts/glp/GlpStrategy.sol

59:          weth = IERC20(_yieldBox.wrappedNative());

68:          gmx = IERC20(_gmx);

69:          esGmx = IERC20(_gmxRewardRouter.esGmx());

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L59-L59

File: contracts/lido/LidoEthStrategy.sol

58:          wrappedNative = IERC20(_token);

62:          IERC20(_stEth).approve(_curvePool, type(uint256).max);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L58-L58

File: contracts/stargate/StargateStrategy.sol

77:          wrappedNative = IERC20(_token);

88:          stgNative = IERC20(_lpToken);

92:          stgTokenReward = IERC20(lpStaking.stargate());

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L77-L77

File: contracts/yearn/YearnStrategy.sol

56:          wrappedNative = IERC20(_token);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L56-L56

File: contracts/YieldBoxURIBuilder.sol

28:                  IERC20 token = IERC20(asset.contractAddress);

58:                  IERC20 token = IERC20(asset.contractAddress);

72:              IERC20 token = IERC20(asset.contractAddress);

94:              IERC20 token = IERC20(asset.contractAddress);

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L28-L28

[D‑06] Tokens may be minted to address(0x0)

In the cases below, _mint() prevents minting to address(0x0)

There are 10 instances of this issue:

File: contracts/usd0/USDO.sol

81       function flashLoan(
82           IERC3156FlashBorrower receiver,
83           address token,
84           uint256 amount,
85           bytes calldata data
86       ) external override notPaused returns (bool) {
87           require(token == address(this), "USDO: token not valid");
88           require(maxFlashLoan(token) >= amount, "USDO: amount too big");
89           require(amount > 0, "USDO: amount not valid");
90           uint256 fee = flashFee(token, amount);
91           _mint(address(receiver), amount);
92   
93           require(
94               receiver.onFlashLoan(msg.sender, token, amount, fee, data) ==
95                   FLASH_MINT_CALLBACK_SUCCESS,
96               "USDO: failed"
97           );
98   
99           uint256 _allowance = allowance(address(receiver), address(this));
100          require(_allowance >= (amount + fee), "USDO: repay not approved");
101          _approve(address(receiver), address(this), _allowance - (amount + fee));
102          _burn(address(receiver), amount + fee);
103          return true;
104:     }

109      function mint(address _to, uint256 _amount) external notPaused {
110          require(allowedMinter[_getChainId()][msg.sender], "USDO: unauthorized");
111          _mint(_to, _amount);
112          emit Minted(_to, _amount);
113:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L81-L104

File: contracts/tOFT/BaseTOFT.sol

348      function _wrap(
349          address _fromAddress,
350          address _toAddress,
351          uint256 _amount
352      ) internal virtual {
353          if (_fromAddress != msg.sender) {
354              require(
355                  allowance(_fromAddress, msg.sender) >= _amount,
356                  "TOFT_allowed"
357              );
358          }
359          IERC20(erc20).safeTransferFrom(_fromAddress, address(this), _amount);
360          _mint(_toAddress, _amount);
361:     }

363      function _wrapNative(address _toAddress) internal virtual {
364          require(msg.value > 0, "TOFT_0");
365          _mint(_toAddress, msg.value);
366:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L348-L361

File: contracts/tokens/LTap.sol

41       function deposit(uint256 amount) external {
42           tapToken.transferFrom(msg.sender, address(this), amount);
43           _mint(msg.sender, amount);
44:      }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L41-L44

File: contracts/tokens/TapOFT.sol

220      function extractTAP(address _to, uint256 _amount) external notPaused {
221          require(msg.sender == minter, "unauthorized");
222          require(_amount > 0, "amount not valid");
223  
224          uint256 week = _timestampToWeek(block.timestamp);
225          require(emissionForWeek[week] >= _amount, "exceeds allowable amount");
226          _mint(_to, _amount);
227          mintedInWeek[week] += _amount;
228          emit Minted(msg.sender, _to, _amount);
229:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L220-L229

File: contracts/NativeTokenFactory.sol

109      function mint(uint256 tokenId, address to, uint256 amount) public onlyOwner(tokenId) {
110          _mint(to, tokenId, amount);
111:     }

127      function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {
128          uint256 len = tos.length;
129          for (uint256 i = 0; i < len; i++) {
130              _mint(tos[i], tokenId, amounts[i]);
131          }
132:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L109-L111

File: contracts/YieldBox.sol

168      function depositNFTAsset(
169          uint256 assetId,
170          address from,
171          address to
172      ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {
173          // Checks
174          Asset storage asset = assets[assetId];
175          require(asset.tokenType == TokenType.ERC721, "YieldBox: not ERC721");
176  
177          // Effects
178          _mint(to, assetId, 1);
179  
180          // Interactions
181          IERC721(asset.contractAddress).safeTransferFrom(from, address(asset.strategy), asset.tokenId);
182  
183          asset.strategy.deposited(1);
184  
185          emit Deposited(msg.sender, from, to, assetId, 1, 1, 1, 1, true);
186  
187          return (1, 1);
188:     }

196      function depositETHAsset(uint256 assetId, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {
197          // Checks
198          Asset storage asset = assets[assetId];
199          require(asset.tokenType == TokenType.ERC20 && asset.contractAddress == address(wrappedNative), "YieldBox: not wrappedNative");
200  
201          // Effects
202          uint256 share = amount._toShares(totalSupply[assetId], _tokenBalanceOf(asset), false);
203  
204          _mint(to, assetId, share);
205  
206          // Interactions
207          wrappedNative.deposit{ value: amount }();
208          // Strategies always receive wrappedNative (supporting both wrapped and raw native tokens adds too much complexity)
209          wrappedNative.safeTransfer(address(asset.strategy), amount);
210          asset.strategy.deposited(amount);
211  
212          emit Deposited(msg.sender, msg.sender, to, assetId, amount, share, amountOut, shareOut, false);
213  
214          return (amount, share);
215:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L168-L188

[D‑07] Contracts are not using their OZ Upgradeable counterparts

The rule is true only when the contract being defined is upgradeable, which isn't the case for these invalid examples

There are 59 instances of this issue:

see instances
File: contracts/markets/MarketERC20.sol

5:   import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

6:   import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L5-L5

File: contracts/usd0/BaseUSDO.sol

8:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L8-L8

File: contracts/usd0/BaseUSDOStorage.sol

8:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L8-L8

File: contracts/Balancer.sol

7:   import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L7-L7

File: contracts/TapiocaWrapper.sol

8:   import "@openzeppelin/contracts/utils/Create2.sol";

9:   import "@openzeppelin/contracts/access/Ownable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L8-L8

File: contracts/tOFT/BaseTOFTStorage.sol

9:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

10:  import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

11:  import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L9-L9

File: contracts/Vesting.sol

4:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

5:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L4-L4

File: contracts/governance/twTAP.sol

6:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

7:   import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L6-L6

File: contracts/option-airdrop/AirdropBroker.sol

4:   import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

6:   import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

7:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

8:   import "@openzeppelin/contracts/security/Pausable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L4-L4

File: contracts/option-airdrop/aoTAP.sol

6:   import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

7:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L6-L6

File: contracts/options/TapiocaOptionBroker.sol

5:   import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

6:   import "@openzeppelin/contracts/security/Pausable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L5-L5

File: contracts/options/TapiocaOptionLiquidityProvision.sol

5:   import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";

7:   import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

8:   import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

9:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

10:  import "@openzeppelin/contracts/security/Pausable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L5-L5

File: contracts/options/oTAP.sol

5:   import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

6:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L5-L5

File: contracts/tokens/BaseTapOFT.sol

5:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L5-L5

File: contracts/tokens/LTap.sol

5:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L5-L5

File: contracts/tokens/TapOFT.sol

4:   import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L4-L4

File: contracts/Magnetar/MagnetarV2.sol

5:   import "@openzeppelin/contracts/access/Ownable.sol";

6:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L5-L5

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

8:   import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

9:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

10:  import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L8-L8

File: contracts/Multicall/Multicall3.sol

4:   import "@openzeppelin/contracts/access/Ownable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L4-L4

File: contracts/Swapper/BaseSwapper.sol

4:   import "@openzeppelin/contracts/access/Ownable.sol";

5:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L4-L4

File: contracts/Swapper/CurveSwapper.sol

4:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L4-L4

File: contracts/Swapper/UniswapV3Swapper.sol

9:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L9-L9

File: contracts/oracle/implementations/ARBTriCryptoOracle.sol

5:   import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/implementations/ARBTriCryptoOracle.sol#L5-L5

File: contracts/aave/AaveStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L4-L4

File: contracts/balancer/BalancerStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L4-L4

File: contracts/compound/CompoundStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L4-L4

File: contracts/convex/ConvexTricryptoStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L4-L4

File: contracts/curve/TricryptoLPStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L4-L4

File: contracts/curve/TricryptoNativeStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L4-L4

File: contracts/lido/LidoEthStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L4-L4

File: contracts/stargate/StargateStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L4-L4

File: contracts/yearn/YearnStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L4-L4

File: contracts/YieldBox.sol

36:  import "@openzeppelin/contracts/utils/Strings.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L36-L36

File: contracts/YieldBoxPermit.sol

5:   import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

6:   import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

7:   import "@openzeppelin/contracts/utils/Counters.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L5-L5

[D‑08] Change public function visibility to external to save gas

Both public and external functions use the same amount of gas (both deployment and runtime gas), so this finding is invalid

There are 70 instances of this issue:

see instances
File: contracts/Penrose.sol

199      function singularityMarkets()
200          public
201          view
202          returns (address[] memory markets)
203:     {

209:     function bigBangMarkets() public view returns (address[] memory markets) {

214:     function singularityMasterContractLength() public view returns (uint256) {

219:     function bigBangMasterContractLength() public view returns (uint256) {

232      function withdrawAllMarketFees(
233          IMarket[] calldata markets_,
234          ISwapper[] calldata swappers_,
235          IPenrose.SwapData[] calldata swapData_
236:     ) public notPaused {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L199-L203

File: contracts/markets/Market.sol

256      function computeClosingFactor(
257          uint256 borrowPart,
258          uint256 collateralPartInAsset,
259          uint256 borrowPartDecimals,
260          uint256 collateralPartDecimals,
261          uint256 ratesPrecision
262:     ) public view returns (uint256) {

305      function computeTVLInfo(
306          address user,
307          uint256 _exchangeRate
308      )
309          public
310          view
311          returns (uint256 amountToSolvency, uint256 minTVL, uint256 maxTVL)
312:     {

356      function computeLiquidatorReward(
357          address user,
358          uint256 _exchangeRate
359:     ) public view returns (uint256) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L256-L262

File: contracts/markets/MarketERC20.sol

116:     function nonces(address owner) public view returns (uint256) {

201      function approveBorrow(
202          address spender,
203          uint256 amount
204:     ) public returns (bool) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L116-L116

File: contracts/markets/bigBang/BigBang.sol

242      function borrow(
243          address from,
244          address to,
245          uint256 amount
246:     ) public notPaused solvent(from) returns (uint256 part, uint256 share) {

263      function repay(
264          address from,
265          address to,
266          bool,
267          uint256 part
268:     ) public notPaused allowedBorrow(from, part) returns (uint256 amount) {

282      function addCollateral(
283          address from,
284          address to,
285          bool skim,
286          uint256 amount,
287          uint256 share
288:     ) public allowedBorrow(from, share) notPaused {

296      function removeCollateral(
297          address from,
298          address to,
299          uint256 share
300:     ) public notPaused solvent(from) allowedBorrow(from, share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L242-L246

File: contracts/markets/singularity/SGLBorrow.sol

21       function borrow(
22           address from,
23           address to,
24           uint256 amount
25:      ) public notPaused solvent(from) returns (uint256 part, uint256 share) {

45       function repay(
46           address from,
47           address to,
48           bool skim,
49           uint256 part
50:      ) public notPaused allowedBorrow(from, part) returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L21-L25

File: contracts/markets/singularity/SGLCollateral.sol

21       function addCollateral(
22           address from,
23           address to,
24           bool skim,
25           uint256 amount,
26           uint256 share
27:      ) public notPaused allowedBorrow(from, share) {

35       function removeCollateral(
36           address from,
37           address to,
38           uint256 share
39:      ) public notPaused solvent(from) allowedBorrow(from, share) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L21-L27

File: contracts/markets/singularity/SGLCommon.sol

17:      function accrue() public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L17-L17

File: contracts/markets/singularity/SGLStorage.sol

154:     function symbol() public view returns (string memory) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L154-L154

File: contracts/markets/singularity/Singularity.sol

204      function addAsset(
205          address from,
206          address to,
207          bool skim,
208          uint256 share
209:     ) public notPaused allowedLend(from, share) returns (uint256 fraction) {

219      function removeAsset(
220          address from,
221          address to,
222          uint256 fraction
223:     ) public notPaused returns (uint256 share) {

235      function addCollateral(
236          address from,
237          address to,
238          bool skim,
239          uint256 amount,
240          uint256 share
241:     ) public {

259:     function removeCollateral(address from, address to, uint256 share) public {

277      function borrow(
278          address from,
279          address to,
280          uint256 amount
281:     ) public returns (uint256 part, uint256 share) {

296      function repay(
297          address from,
298          address to,
299          bool skim,
300          uint256 part
301:     ) public returns (uint256 amount) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L204-L209

File: contracts/usd0/modules/USDOLeverageModule.sol

93:      function multiHop(bytes memory _payload) public {

133      function leverageUp(
134          address module,
135          uint16 _srcChainId,
136          bytes memory _srcAddress,
137          uint64 _nonce,
138          bytes memory _payload
139:     ) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L93-L93

File: contracts/usd0/modules/USDOMarketModule.sol

104:     function remove(bytes memory _payload) public {

134      function lend(
135          address module,
136          uint16 _srcChainId,
137          bytes memory _srcAddress,
138          uint64 _nonce,
139          bytes memory _payload
140:     ) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L104-L104

File: contracts/usd0/modules/USDOOptionsModule.sol

103:     function sendFromDestination(bytes memory _payload) public {

138      function exercise(
139          address module,
140          uint16 _srcChainId,
141          bytes memory _srcAddress,
142          uint64 _nonce,
143          bytes memory _payload
144:     ) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L103-L103

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

111:     function multiHop(bytes memory _payload) public {

148      function leverageDown(
149          address module,
150          uint16 _srcChainId,
151          bytes memory _srcAddress,
152          uint64 _nonce,
153          bytes memory _payload
154:     ) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L111-L111

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

126      function borrow(
127          address module,
128          uint16 _srcChainId,
129          bytes memory _srcAddress,
130          uint64 _nonce,
131          bytes memory _payload
132:     ) public payable {

204:     function remove(bytes memory _payload) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L126-L132

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

118:     function sendFromDestination(bytes memory _payload) public {

153      function exercise(
154          address module,
155          uint16 _srcChainId,
156          bytes memory _srcAddress,
157          uint64 _nonce,
158          bytes memory _payload
159:     ) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L118-L118

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

122      function strategyDeposit(
123          address module,
124          uint16 _srcChainId,
125          bytes memory _srcAddress,
126          uint64 _nonce,
127          bytes memory _payload,
128          IERC20 _erc20
129:     ) public {

188      function strategyWithdraw(
189          uint16 _srcChainId,
190          bytes memory _payload
191:     ) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L122-L129

File: contracts/governance/twTAP.sol

155      function getParticipation(
156          uint _tokenId
157:     ) public view returns (Participation memory participant) {

397:     function advanceWeek(uint256 _limit) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L155-L157

File: contracts/Magnetar/MagnetarV2.sol

76       function getCollateralAmountForShare(
77           IMarket market,
78           uint256 share
79:      ) public view returns (uint256 amount) {

89       function getCollateralSharesForBorrowPart(
90           IMarket market,
91           uint256 borrowPart,
92           uint256 liquidationMultiplierPrecision,
93           uint256 exchangeRatePrecision
94:      ) public view returns (uint256 collateralShares) {

117      function getAmountForBorrowPart(
118          IMarket market,
119          uint256 borrowPart
120:     ) public view returns (uint256 amount) {

133      function getBorrowPartForAmount(
134          IMarket market,
135          uint256 amount
136:     ) public view returns (uint256 part) {

150      function getAmountForAssetFraction(
151          ISingularity singularity,
152          uint256 fraction
153:     ) public view returns (uint256 amount) {

171      function getFractionForAmount(
172          ISingularity singularity,
173          uint256 amount
174:     ) public view returns (uint256 fraction) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L76-L79

File: contracts/Multicall/Multicall3.sol

41       function multicall(
42           Call[] calldata calls
43:      ) public payable returns (Result[] memory returnData) {

63       function multicallValue(
64           CallValue[] calldata calls
65:      ) public payable returns (Result[] memory returnData) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L41-L43

File: contracts/balancer/BalancerStrategy.sol

117:     function compound(bytes memory) public {}

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L117-L117

File: contracts/compound/CompoundStrategy.sol

80:      function compoundAmount() public pure returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L80-L80

File: contracts/curve/TricryptoNativeStrategy.sol

103:     function compoundAmount() public returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L103-L103

File: contracts/glp/GlpStrategy.sol

104:     function harvestGmx(uint256 priceNum, uint256 priceDenom) public onlyOwner {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L104-L104

File: contracts/lido/LidoEthStrategy.sol

84:      function compoundAmount() public pure returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L84-L84

File: contracts/yearn/YearnStrategy.sol

81:      function compoundAmount() public pure returns (uint256 result) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L81-L81

File: contracts/NativeTokenFactory.sol

56:      function transferOwnership(uint256 tokenId, address newOwner, bool direct, bool renounce) public onlyOwner(tokenId) {

73:      function claimOwnership(uint256 tokenId) public {

90:      function createToken(string calldata name, string calldata symbol, uint8 decimals, string calldata uri) public returns (uint32 tokenId) {

109:     function mint(uint256 tokenId, address to, uint256 amount) public onlyOwner(tokenId) {

116:     function burn(uint256 tokenId, address from, uint256 amount) public allowed(from, tokenId) {

127:     function batchMint(uint256 tokenId, address[] calldata tos, uint256[] calldata amounts) public onlyOwner(tokenId) {

138:     function batchBurn(uint256 tokenId, address[] calldata froms, uint256[] calldata amounts) public {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L56-L56

File: contracts/YieldBox.sol

168      function depositNFTAsset(
169          uint256 assetId,
170          address from,
171          address to
172:     ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

223      function withdraw(
224          uint256 assetId,
225          address from,
226          address to,
227          uint256 amount,
228          uint256 share
229:     ) public allowed(from, assetId) returns (uint256 amountOut, uint256 shareOut) {

303:     function transfer(address from, address to, uint256 assetId, uint256 share) public allowed(from, assetId) {

307:     function batchTransfer(address from, address to, uint256[] calldata assetIds_, uint256[] calldata shares_) public {

336:     function transferMultiple(address from, address[] calldata tos, uint256 assetId, uint256[] calldata shares) public allowed(from, assetId) {

477      function deposit(
478          TokenType tokenType,
479          address contractAddress,
480          IStrategy strategy,
481          uint256 tokenId,
482          address from,
483          address to,
484          uint256 amount,
485          uint256 share
486:     ) public returns (uint256 amountOut, uint256 shareOut) {

500:     function depositETH(IStrategy strategy, address to, uint256 amount) public payable returns (uint256 amountOut, uint256 shareOut) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L168-L172

[D‑09] Save gas with the use of specific import statements

Importing whole files rather than specific identifiers does not waste gas, so this finding is invalid

There are 324 instances of this issue:

see instances
File: contracts/Penrose.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:   import "@boringcrypto/boring-solidity/contracts/BoringFactory.sol";

7:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/YieldBox.sol";

8:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

9:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/ERC20WithoutStrategy.sol";

10:  import "tapioca-periph/contracts/interfaces/ISingularity.sol";

11:  import "tapioca-periph/contracts/interfaces/IPenrose.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/Penrose.sol#L4-L4

File: contracts/markets/Market.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

7:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/YieldBox.sol";

8:   import "tapioca-periph/contracts/interfaces/IOracle.sol";

9:   import "tapioca-periph/contracts/interfaces/IPenrose.sol";

10:  import "./MarketERC20.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/Market.sol#L4-L4

File: contracts/markets/MarketERC20.sol

6:   import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/MarketERC20.sol#L6-L6

File: contracts/markets/bigBang/BigBang.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:   import "@boringcrypto/boring-solidity/contracts/ERC20.sol";

7:   import "tapioca-periph/contracts/interfaces/IBigBang.sol";

8:   import "tapioca-periph/contracts/interfaces/ISendFrom.sol";

9:   import "tapioca-periph/contracts/interfaces/ISwapper.sol";

12:  import "../Market.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/bigBang/BigBang.sol#L4-L4

File: contracts/markets/singularity/SGLBorrow.sol

4:   import "./SGLLendingCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLBorrow.sol#L4-L4

File: contracts/markets/singularity/SGLCollateral.sol

4:   import "./SGLLendingCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCollateral.sol#L4-L4

File: contracts/markets/singularity/SGLCommon.sol

4:   import "./SGLStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLCommon.sol#L4-L4

File: contracts/markets/singularity/SGLLendingCommon.sol

4:   import "./SGLCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLendingCommon.sol#L4-L4

File: contracts/markets/singularity/SGLLeverage.sol

4:   import "./SGLLendingCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLeverage.sol#L4-L4

File: contracts/markets/singularity/SGLLiquidation.sol

4:   import "./SGLCommon.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLLiquidation.sol#L4-L4

File: contracts/markets/singularity/SGLStorage.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

6:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

8:   import "tapioca-periph/contracts/interfaces/ISwapper.sol";

9:   import "tapioca-periph/contracts/interfaces/IPenrose.sol";

10:  import "tapioca-periph/contracts/interfaces/ISingularity.sol";

11:  import "tapioca-periph/contracts/interfaces/ILiquidationQueue.sol";

12:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/YieldBox.sol";

14:  import "../Market.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/SGLStorage.sol#L4-L4

File: contracts/markets/singularity/Singularity.sol

4:   import "./SGLCommon.sol";

5:   import "./SGLLiquidation.sol";

6:   import "./SGLCollateral.sol";

7:   import "./SGLBorrow.sol";

8:   import "./SGLLeverage.sol";

10:  import "tapioca-periph/contracts/interfaces/ISendFrom.sol";

11:  import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/markets/singularity/Singularity.sol#L4-L4

File: contracts/usd0/BaseUSDO.sol

5:   import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

8:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

12:  import "tapioca-periph/contracts/interfaces/IYieldBoxBase.sol";

14:  import "tapioca-periph/contracts/interfaces/ICommonData.sol";

16:  import "./BaseUSDOStorage.sol";

17:  import "./modules/USDOLeverageModule.sol";

18:  import "./modules/USDOMarketModule.sol";

19:  import "./modules/USDOOptionsModule.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDO.sol#L5-L5

File: contracts/usd0/BaseUSDOStorage.sol

5:   import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

8:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

12:  import "tapioca-periph/contracts/interfaces/IYieldBoxBase.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/BaseUSDOStorage.sol#L5-L5

File: contracts/usd0/USDO.sol

4:   import "tapioca-sdk/dist/contracts/interfaces/ILayerZeroEndpoint.sol";

5:   import "tapioca-periph/contracts/interfaces/IERC3156FlashLender.sol";

6:   import "./BaseUSDO.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/USDO.sol#L4-L4

File: contracts/usd0/modules/USDOLeverageModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:   import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:  import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

11:  import "tapioca-periph/contracts/interfaces/ISingularity.sol";

12:  import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

13:  import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

15:  import "../BaseUSDOStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOLeverageModule.sol#L5-L5

File: contracts/usd0/modules/USDOMarketModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringRebase.sol";

10:  import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

11:  import "tapioca-periph/contracts/interfaces/IMagnetar.sol";

12:  import "tapioca-periph/contracts/interfaces/IMarket.sol";

13:  import "tapioca-periph/contracts/interfaces/ISingularity.sol";

14:  import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

15:  import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

17:  import "../BaseUSDOStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOMarketModule.sol#L5-L5

File: contracts/usd0/modules/USDOOptionsModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

9:   import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

10:  import "tapioca-periph/contracts/interfaces/ITapiocaOptionsBroker.sol";

11:  import "tapioca-periph/contracts/interfaces/ISendFrom.sol";

12:  import "../BaseUSDOStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-bar-audit/contracts/usd0/modules/USDOOptionsModule.sol#L5-L5

File: contracts/Balancer.sol

4:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

5:   import "tapioca-periph/contracts/interfaces/IStargateRouter.sol";

6:   import "@rari-capital/solmate/src/auth/Owned.sol";

7:   import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/Balancer.sol#L4-L4

File: contracts/TapiocaWrapper.sol

4:   import "./tOFT/TapiocaOFT.sol";

5:   import "./tOFT/mTapiocaOFT.sol";

6:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

8:   import "@openzeppelin/contracts/utils/Create2.sol";

9:   import "@openzeppelin/contracts/access/Ownable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/TapiocaWrapper.sol#L4-L4

File: contracts/tOFT/BaseTOFT.sol

4:   import "./BaseTOFTStorage.sol";

7:   import "./modules/BaseTOFTLeverageModule.sol";

8:   import "./modules/BaseTOFTStrategyModule.sol";

9:   import "./modules/BaseTOFTMarketModule.sol";

10:  import "./modules/BaseTOFTOptionsModule.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L4-L4

File: contracts/tOFT/BaseTOFTStorage.sol

5:   import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

6:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

10:  import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

11:  import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

14:  import "tapioca-periph/contracts/interfaces/IYieldBoxBase.sol";

15:  import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

16:  import "tapioca-periph/contracts/interfaces/ICommonData.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFTStorage.sol#L5-L5

File: contracts/tOFT/TapiocaOFT.sol

3:   import "./BaseTOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/TapiocaOFT.sol#L3-L3

File: contracts/tOFT/mTapiocaOFT.sol

3:   import "./BaseTOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/mTapiocaOFT.sol#L3-L3

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:   import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:  import "tapioca-periph/contracts/interfaces/IMagnetar.sol";

11:  import "tapioca-periph/contracts/interfaces/ISingularity.sol";

12:  import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

13:  import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

14:  import "tapioca-periph/contracts/interfaces/ITapiocaOptionsBroker.sol";

15:  import "tapioca-periph/contracts/interfaces/ITapiocaOptionLiquidityProvision.sol";

17:  import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L5-L5

File: contracts/tOFT/modules/BaseTOFTMarketModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:   import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:  import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

11:  import "tapioca-periph/contracts/interfaces/IMagnetar.sol";

12:  import "tapioca-periph/contracts/interfaces/IMarket.sol";

13:  import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

14:  import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

16:  import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTMarketModule.sol#L5-L5

File: contracts/tOFT/modules/BaseTOFTOptionsModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

8:   import "tapioca-periph/contracts/interfaces/IPermitBorrow.sol";

9:   import "tapioca-periph/contracts/interfaces/IPermitAll.sol";

10:  import "tapioca-periph/contracts/interfaces/ITapiocaOptionsBroker.sol";

12:  import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTOptionsModule.sol#L5-L5

File: contracts/tOFT/modules/BaseTOFTStrategyModule.sol

5:   import "tapioca-sdk/dist/contracts/libraries/LzLib.sol";

9:   import "tapioca-periph/contracts/interfaces/ISwapper.sol";

10:  import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

12:  import "../BaseTOFTStorage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTStrategyModule.sol#L5-L5

File: contracts/Vesting.sol

4:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

5:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/Vesting.sol#L4-L4

File: contracts/governance/twTAP.sol

6:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

7:   import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

8:   import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

9:   import "../tokens/TapOFT.sol";

10:  import "../twAML.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L6-L6

File: contracts/option-airdrop/AirdropBroker.sol

4:   import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

5:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

6:   import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

7:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

8:   import "@openzeppelin/contracts/security/Pausable.sol";

9:   import "tapioca-periph/contracts/interfaces/IOracle.sol";

10:  import "../tokens/TapOFT.sol";

11:  import "../twAML.sol";

12:  import "./aoTAP.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/AirdropBroker.sol#L4-L4

File: contracts/option-airdrop/aoTAP.sol

5:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

6:   import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

7:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

9:   import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/option-airdrop/aoTAP.sol#L5-L5

File: contracts/options/TapiocaOptionBroker.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:   import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

6:   import "@openzeppelin/contracts/security/Pausable.sol";

7:   import "tapioca-periph/contracts/interfaces/IOracle.sol";

8:   import "./TapiocaOptionLiquidityProvision.sol";

9:   import "../tokens/TapOFT.sol";

10:  import "../twAML.sol";

11:  import "./oTAP.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionBroker.sol#L4-L4

File: contracts/options/TapiocaOptionLiquidityProvision.sol

5:   import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

8:   import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

9:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

10:  import "@openzeppelin/contracts/security/Pausable.sol";

11:  import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

12:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L5-L5

File: contracts/options/oTAP.sol

5:   import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

6:   import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

7:   import "tapioca-sdk/dist/contracts/util/ERC4494.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/oTAP.sol#L5-L5

File: contracts/tokens/BaseTapOFT.sol

5:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

7:   import "tapioca-periph/contracts/interfaces/ITapiocaOFT.sol";

8:   import "tapioca-sdk/dist/contracts/token/oft/v2/OFTV2.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/BaseTapOFT.sol#L5-L5

File: contracts/tokens/LTap.sol

4:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

5:   import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/LTap.sol#L4-L4

File: contracts/tokens/TapOFT.sol

5:   import "./BaseTapOFT.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/tokens/TapOFT.sol#L5-L5

File: contracts/Magnetar/modules/MagnetarMarketModule.sol

16:  import "../MagnetarV2Storage.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/modules/MagnetarMarketModule.sol#L16-L16

File: contracts/Multicall/Multicall3.sol

4:   import "@openzeppelin/contracts/access/Ownable.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Multicall/Multicall3.sol#L4-L4

File: contracts/Swapper/BaseSwapper.sol

4:   import "@openzeppelin/contracts/access/Ownable.sol";

5:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

7:   import "tapioca-sdk/dist/contracts/YieldBox/contracts/interfaces/IYieldBox.sol";

9:   import "../interfaces/ISwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/BaseSwapper.sol#L4-L4

File: contracts/Swapper/CurveSwapper.sol

4:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

5:   import "./interfaces/ICurvePool.sol";

6:   import "./BaseSwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/CurveSwapper.sol#L4-L4

File: contracts/Swapper/UniswapV2Swapper.sol

4:   import "./interfaces/IUniswapV2Factory.sol";

5:   import "./interfaces/IUniswapV2Router02.sol";

6:   import "./BaseSwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV2Swapper.sol#L4-L4

File: contracts/Swapper/UniswapV3Swapper.sol

4:   import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";

5:   import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";

6:   import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol";

7:   import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";

8:   import "@uniswap/v3-periphery/contracts/interfaces/IQuoterV2.sol";

9:   import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

11:  import "./libraries/OracleLibrary.sol";

12:  import "./BaseSwapper.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Swapper/UniswapV3Swapper.sol#L4-L4

File: contracts/oracle/Seer.sol

4:   import "./OracleMulti.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/oracle/Seer.sol#L4-L4

File: contracts/aave/AaveStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:  import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

12:  import "./interfaces/IStkAave.sol";

13:  import "./interfaces/ILendingPool.sol";

14:  import "./interfaces/IIncentivesController.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/aave/AaveStrategy.sol#L4-L4

File: contracts/balancer/BalancerStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:  import "./interfaces/IBalancerVault.sol";

12:  import "./interfaces/IBalancerPool.sol";

13:  import "./interfaces/IBalancerHelpers.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/balancer/BalancerStrategy.sol#L4-L4

File: contracts/compound/CompoundStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

12:  import "../../tapioca-periph/contracts/interfaces/INative.sol";

13:  import "./interfaces/ICToken.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/compound/CompoundStrategy.sol#L4-L4

File: contracts/convex/ConvexTricryptoStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:  import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

12:  import "../curve/interfaces/ITricryptoLPGetter.sol";

14:  import "./interfaces/IConvexBooster.sol";

15:  import "./interfaces/IConvexRewardPool.sol";

16:  import "./interfaces/IConvexZap.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L4-L4

File: contracts/curve/TricryptoLPStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:  import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

13:  import "./interfaces/ITricryptoLPGetter.sol";

14:  import "./interfaces/ITricryptoLPGauge.sol";

15:  import "./interfaces/ICurveMinter.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoLPStrategy.sol#L4-L4

File: contracts/curve/TricryptoNativeStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:  import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

13:  import "./interfaces/ITricryptoLPGetter.sol";

14:  import "./interfaces/ITricryptoLPGauge.sol";

15:  import "./interfaces/ICurveMinter.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/curve/TricryptoNativeStrategy.sol#L4-L4

File: contracts/glp/GlpStrategy.sol

5:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

6:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

7:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

9:   import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";

11:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/enums/YieldBoxTokenType.sol";

12:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

14:  import "../interfaces/IFeeCollector.sol";

15:  import "../interfaces/gmx/IGlpManager.sol";

16:  import "../interfaces/gmx/IGmxRewardDistributor.sol";

17:  import "../interfaces/gmx/IGmxRewardRouter.sol";

18:  import "../interfaces/gmx/IGmxRewardTracker.sol";

19:  import "../interfaces/gmx/IGmxVester.sol";

20:  import "../interfaces/gmx/IGmxVault.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/glp/GlpStrategy.sol#L5-L5

File: contracts/lido/LidoEthStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

12:  import "./interfaces/IStEth.sol";

13:  import "./interfaces/ICurveEthStEthPool.sol";

14:  import "../../tapioca-periph/contracts/interfaces/INative.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/lido/LidoEthStrategy.sol#L4-L4

File: contracts/stargate/StargateStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

11:  import "../../tapioca-periph/contracts/interfaces/ISwapper.sol";

13:  import "./interfaces/IRouter.sol";

14:  import "./interfaces/IRouterETH.sol";

15:  import "./interfaces/ILPStaking.sol";

16:  import "../../tapioca-periph/contracts/interfaces/INative.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/stargate/StargateStrategy.sol#L4-L4

File: contracts/yearn/YearnStrategy.sol

4:   import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

6:   import "@boringcrypto/boring-solidity/contracts/BoringOwnable.sol";

7:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC20.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "tapioca-sdk/dist/contracts/YieldBox/contracts/strategies/BaseStrategy.sol";

12:  import "./interfaces/IYearnVault.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/yearn/YearnStrategy.sol#L4-L4

File: contracts/NativeTokenFactory.sol

3:   import "./AssetRegister.sol";

4:   import "./BoringMath.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/NativeTokenFactory.sol#L3-L3

File: contracts/YieldBox.sol

26:  import "./interfaces/IWrappedNative.sol";

27:  import "./interfaces/IStrategy.sol";

28:  import "@boringcrypto/boring-solidity/contracts/interfaces/IERC721.sol";

29:  import "@boringcrypto/boring-solidity/contracts/interfaces/IERC1155.sol";

30:  import "@boringcrypto/boring-solidity/contracts/libraries/Base64.sol";

31:  import "@boringcrypto/boring-solidity/contracts/Domain.sol";

32:  import "./ERC721TokenReceiver.sol";

33:  import "./ERC1155TokenReceiver.sol";

34:  import "./ERC1155.sol";

35:  import "@boringcrypto/boring-solidity/contracts/BoringBatchable.sol";

36:  import "@openzeppelin/contracts/utils/Strings.sol";

37:  import "./AssetRegister.sol";

38:  import "./NativeTokenFactory.sol";

39:  import "./YieldBoxRebase.sol";

40:  import "./YieldBoxURIBuilder.sol";

41:  import "./YieldBoxPermit.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBox.sol#L26-L26

File: contracts/YieldBoxPermit.sol

5:   import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

6:   import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

7:   import "@openzeppelin/contracts/utils/Counters.sol";

8:   import "./interfaces/IYieldBox.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxPermit.sol#L5-L5

File: contracts/YieldBoxRebase.sol

5:   import "./interfaces/IStrategy.sol";

6:   import "@boringcrypto/boring-solidity/contracts/interfaces/IERC1155.sol";

7:   import "@boringcrypto/boring-solidity/contracts/libraries/Base64.sol";

8:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringAddress.sol";

9:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

10:  import "@boringcrypto/boring-solidity/contracts/Domain.sol";

11:  import "./ERC1155TokenReceiver.sol";

12:  import "./ERC1155.sol";

13:  import "@boringcrypto/boring-solidity/contracts/BoringBatchable.sol";

14:  import "@boringcrypto/boring-solidity/contracts/BoringFactory.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxRebase.sol#L5-L5

File: contracts/YieldBoxURIBuilder.sol

3:   import "@openzeppelin/contracts/utils/Strings.sol";

4:   import "@boringcrypto/boring-solidity/contracts/libraries/Base64.sol";

5:   import "@boringcrypto/boring-solidity/contracts/libraries/BoringERC20.sol";

6:   import "./interfaces/IYieldBox.sol";

7:   import "./NativeTokenFactory.sol";

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/YieldBox/contracts/YieldBoxURIBuilder.sol#L3-L3

[D‑10] safeTransfer function does not check for contract existence

The examples below are either not token transfers, or are making high-level transfer()/transferFrom() calls (which check for contract existence), or are from a library that checks for contract existence.

There are 2 instances of this issue:

File: contracts/tOFT/BaseTOFT.sol

379      function _safeTransferETH(address to, uint256 amount) internal {
380          (bool sent, ) = to.call{value: amount}("");
381          require(sent, "TOFT_failed");
382:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/BaseTOFT.sol#L379-L382

File: contracts/tOFT/modules/BaseTOFTLeverageModule.sol

279      function _safeTransferETH(address to, uint256 amount) private {
280          (bool sent, ) = to.call{value: amount}("");
281          require(sent, "TOFT_failed");
282:     }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapiocaz-audit/contracts/tOFT/modules/BaseTOFTLeverageModule.sol#L279-L282

[D‑11] Shorten the array rather than copying to a new one

None of these examples are of filtering out entries from an array.

There are 7 instances of this issue:

File: contracts/governance/twTAP.sol

170          uint256[] memory result = new uint256[](len);
171  
172          Participation memory position = participants[_tokenId];
173:         uint256 votes;

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/governance/twTAP.sol#L170-L173

File: contracts/options/TapiocaOptionLiquidityProvision.sol

134          SingularityPool[] memory pools = new SingularityPool[](len);
135          unchecked {
136              for (uint256 i = 0; i < len; ++i) {
137:                 pools[i] = activeSingularities[

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tap-token-audit/contracts/options/TapiocaOptionLiquidityProvision.sol#L134-L137

File: contracts/Magnetar/MagnetarV2.sol

970          SingularityInfo[] memory result = new SingularityInfo[](len);
971  
972          Rebase memory _totalAsset;
973:         for (uint256 i = 0; i < len; i++) {

1001         BigBangInfo[] memory result = new BigBangInfo[](len);
1002 
1003         IBigBang.AccrueInfo memory _accrueInfo;
1004:        for (uint256 i = 0; i < len; i++) {

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-periph-audit/contracts/Magnetar/MagnetarV2.sol#L970-L973

File: contracts/convex/ConvexTricryptoStrategy.sol

254          uint256[] memory balancesBefore = new uint256[](tempData.tokens.length);
255          for (uint256 i = 0; i < tempData.tokens.length; i++) {
256              balancesBefore[i] = IERC20(tempData.tokens[i]).balanceOf(
257:                 address(this)

272          uint256[] memory balancesAfter = new uint256[](tempData.tokens.length);
273          for (uint256 i = 0; i < tempData.tokens.length; i++) {
274              balancesAfter[i] = IERC20(tempData.tokens[i]).balanceOf(
275:                 address(this)

279          uint256[] memory finalBalances = new uint256[](tempData.tokens.length);
280          for (uint256 i = 0; i < tempData.tokens.length; i++) {
281              finalBalances[i] = balancesAfter[i] - balancesBefore[i];
282:         }

https://github.com/code-423n4/2023-07-tapioca/blob/e6eef060495b31173578570215e80f9e95330b9a/tapioca-yieldbox-strategies-audit/contracts/convex/ConvexTricryptoStrategy.sol#L254-L257

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment