Gigaswap - Audit

CertiKFiles named in the report

CertiK reviewed GigaSwap (Gigaswap - Audit) on 7 Feb 2024: 30 findings, 1 critical; 25 marked fixed, 5 open.

1 critical finding, fixed
Open the reportOpen GigaSwap’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings30

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical001
High203
Medium008
Low3013
Critical`position.count1` Not UpdatedFixed

In the contract Erc20Sale, the function `applyOffer()` can be called by the position owner to accept the buyer's order. On line 142, the buyer's asset status is updated, but the seller's asset status is not updated. ```solidity=141 // transfer asset2 to position offer.asset2Count -= buyCount; position.count2 += buyCount; ``` That is to say, after the function `applyOffer()` is called, the seller can still retrieve the assets of the order by calling the `withdraw()` function.

HighLack Of Access ControlFixed

The function `withdrawTo()` can be called by anyone as it has no access restriction. This enables anyone to call this and withdraw the asset of the contract.

HighPotential Incorrect Calculation Of `position.counFixed

The function `applyOffer()` can be called by the seller to fill the order, the variable `position.count2` represents the number of assets2 that the buyer can get, if the `priceNom` and `priceDenom` of the order are not the same, then the buyer will get the incorrect number of assets. ```solidity=143 position.count2 += buyCount; ```

HighUnable To Receive ERC721 TokenFixed

The contract `Erc721ItemAssetsController` need to receive the ERC721 tokens, however, the interface `IERC721Receiver` is not implemented by the recipient, so the transfer will be reverted.

MediumIncompatibility with Deflationary TokensFixed

When transferring deflationary ERC20 tokens, the input amount may not be equal to the received amount due to the charged transaction fee. For example, if a user sends 100 deflationary tokens (with a 10% transaction fee), only 90 tokens actually arrived to the contract. However, a failure to discount such fees may allow the same user to withdraw 100 tokens from the contract, which causes the contract to lose 10 tokens in such a transaction. Reference: https://thoreum-finance.medium.com/what-exploit-happened-today-for-gocerberus-and-garuda-also-for-lokum-ybear-piggy-caramelswap-3943ee23a39f ```solidity=68 feeToken.transferFrom(msg.sender, address(this), amount); ``` - Transferring tokens by `amount`. ```solidity=70 totalFeetokensLocked += amount; ``` - The `amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees.

MediumMissing Keyword `payable`Fixed

The function `_lock()` uses `msg.value` structure and is designed to lock the user‘s NFTs into the contract, but the `payable` keyword is missing from the `lockSeconds()`, `lockSecondsFor()`, `lockTime()`, `lockTimeFor()`, `lockPermanent()`, making it impossible to receive native tokens.

MediumNo public `swap` functionFixed

The `_swap()` function is used to swap one asset for another, but `_swap()` is modified to be internal and cannot be called by the user, so the user cannot swap assets.

MediumNot Approved Transfer AmountFixed

When the `buy()` function is called to buy the tokens, the user transfers native tokens to the current contract. If the `Erc20Sale` is not approved to transfer funds from the current contract `Erc20SaleWeth`, the transfer of assets from the current contract to the `Erc20Sale` will fail, resulting in the function being reverted. In Erc20SaleWeth.sol ```solidity=39 _sale.buy(positionId, to, count, priceNom, priceDenom, address(this)); ``` In Erc20Sale.sol ```solidity=366 IERC20(pos.asset2).safeTransferFrom(msg.sender, address(this), spend); ```

MediumPotential division by zeroFixed

The function `addLiquidity()` can be called by anyone to add liquidity, and when no assets exist in the pool, `assetA.count()` is equal to 0, then the `addLiquidity` function will be reverted, since the denominator of line 197 is equal to 0.

MediumPotential improper mint liquidityFixed

The `createAlgorithm()` function is called by `Factory` to set `fee`, `constraints`, `liquidityToken`, `feeTokens` and `feeDistributer` for the position, this function does not accept any assets, but mint liquidity for the owner, then when another user adds liquidity to the position, the owner will share the user's assets in proportion to the liquidity.

Show 10 more
MediumPotential Reentrancy AttackFixed

A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. File: TradingPairAlgorithm.sol ```solidity=519 positionsController.withdrawInternal(own, msg.sender, asset1Count); ``` File: EthAssetsController.sol ```solidity=54 function _withdraw( uint256 assetId, address recipient, uint256 count ) internal override { (bool sent, ) = payable(recipient).call{ value: count }(''); require(sent, 'sent ether error: ether is not sent'); } ```

MediumThe number of added liquidity tokens may be zeroFixed

The `addLiquidity()` function can be called by anyone to add liquidity to a pair. If there is a difference in precision between the two assets, the calculated amount of asset B may result in a value of 0. However, when calling the `withdraw()` function, users have the ability to withdraw asset B proportionally to the liquidity they provided. ```solidity=197 vars.countB = (count * assetB.count()) / assetA.count(); ``` For example:\ assetA[KISHU] : https://etherscan.io/address/0xa2b4c0af19cc16a6cfacce81f192b024d625817d \ assetB[USDC] : https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48

LowFunction `getDecimals()` Returns Hardcoded ValuesFixed

In the library ItemRefAsAssetLibrary, there is a view function `getDecimals()` that returns different decimal numbers for different asset types. When the asset type is ERC20 token, the return value is hardcoded to be `9`, which will lead to compatibility issues if the decimal of the specific ERC20 token turns out to be other numbers.

LowFunction Can Be Modified With `view`Fixed

There are functions that do not require modifying the contract state, nor do they need to receive Ether. However, these functions are not labeled with `view` modifiers. Here is the list of applicable functions: * PositionsController.positionsCount() * Vote.erc20Address() * Vote.userVote()

LowInconsistent Conditional RequirementsFixed

The function `withdraw()` is modified by the `onlyDealsController` and can only be called by the `DealsController` contract, which is inconsistent with the 119 lines of code that show that the function can also be called by the owner of the point. ```solidity=118 require( address(_dealsController) == msg.sender || ownerAddr == msg.sender, 'only owner or deals controller can withdraw' ); ```

LowIncorrect Event EmitFixed

In the function `createLiquidity()` of the contract GigaSwapToken, the event emits a wrong value. ```solidity=420 _balances[msg.sender] = 1e19; emit Transfer(address(0), msg.sender, initialLiquidity); ```

LowLack of access control in `transferToAsset()` funFixed

The `transferToAsset()` function can be called by anyone to transfer assets to the current contract. The `transferToAssetFrom()` function does the same thing, but is modified by `onlyFactory`.

LowLocked EtherFixed

The contract has one or more payable functions, but does not have a function to withdraw the fund. ```solidity=5 receive() external payable; ``` ```solidity=58 function execute(uint256 pointId, address addr) external payable; ``` ```solidity=65 function withdraw(uint256 pointId) external payable; ``` ```solidity=25 receive() external payable {} ``` ```solidity=110 function withdraw(uint256 pointId) external payable onlyDealsController { ``` ```solidity=129 function execute(uint256 pointId, address addr) ```

LowPull-Over-Push PatternFixed

In the contracts `PositionsController`, `PositionsFactory`, `TradingPairAlgorithm`, `AssetsControllerBase`, `Erc20AssetsController`, `Erc721ItemAssetsController`, `EthAssetsController` and `VoteExecutorBase`, there are functions that can receive Ethers: * PositionsController.transferToAsset() * PositionsController.transferToAssetFrom() * PositionsFactory.createLockPosition() * PositionsFactory.createTradingPairPosition() * TradingPairAlgorithm.addLiquidity() * AssetsControllerBase.transferToAsset() * Erc20AssetsController.initialize() * Erc721ItemAssetsController.initialize() * EthAssetsController.initialize() * VoteExecutorBase._startVote() These functions will calculate and deduct the required amount of Ether and send the extra Ethers back to ether the `msg.sender` or a passed-in surplus-receiving address.

LowQuestionable Usage of `positionId`Fixed

In Erc20Sale.sol, the ordering logic incorporates the `positionId` parameter; however, it is worth noting that the order price is not related to the asset1/asset2 ratio within the position of `positionId`. Instead, the order price is determined by the buyer through the createOffer function, which takes input parameters asset1Count and asset2Count. The function `applyOffer` called by the buyer does not include a price check and will accept and execute the order in its entirety.

Show 5 more
LowTests Fail To RunFixed

When running `test` on the parent folder, an error occurs: ```bash TradingPair: 8) "before each" hook for "проверка ридера сделок" Weth: 9) "before each" hook for "without allowance" stacking: 10) "before each" hook for "клайм стакового токена" Erc20SaleReal: 11) "before each" hook for "bug 1" RealTest: 12) "before each" hook for "проверка торговой пары 3" swapper: 13) "before each" hook for "проверка наличия фабрики" Vote: 14) "before each" hook for "начальная ситуация" 0 passing (18ms) 14 failing ```

LowTypos in Comments and CodesFixed

There are several typos in the contracts, please see the above to find the locations, and the word with typos are listed here: - Begining - Distributers - Interwal - Liisted - Ofer - Percentil - Poind - addres - algotithm - algotithms - ammount - applyed - creane - dealpoints - deviding - distributers - distrubute - enouth - feeasset - incrementations - interwal - lquidity - maxbuy - maxbyu - nfos - notging - ofer - oply - owanble - percentil - permament - pnly - recepient - retruns - reves - setted - slppage - speciffic - swaped - tyoe - usefull

LowUnused Import FileFixed

The `IERC721Receiver`interface is imported in the `Erc721Locker.sol` file but are not utilized.

LowUnused ValueFixed

```solidity=108 value = msg.value; ``` - The variable `value` is never used after this assignment.

LowVariables That Could Be Declared as ImmutableFixed

The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (87)

  • contracts/fee/vote/FeeSettingsSetFeeAddressVote.sol
  • contracts/swapper/DealsController.sol
  • contracts/lib/erc20/IErc20ForFactory.sol
  • contracts/lib/erc20/Erc20ForFactory.sol
  • contracts/weth/gWETH.sol
  • contracts/fee/vote/FeeSettingsWriter.sol
  • contracts/fee/FeeSettings.sol
  • contracts/giga_swap_erc20_token/vote/executors/GigaSwapTokenRemoveExtraContractAddressVote.sol
  • contracts/fixed_price_sales/Erc20SaleWeth.sol
  • contracts/lib/erc20/Erc20Min.sol
  • contracts/swapper/DealPointsController.sol
  • contracts/swapper/DealPointData.sol
  • contracts/giga_swap_erc20_token/GigaSwapToken.sol
  • contracts/votes/IVote.sol
  • contracts/position_trading/algorithms/TradingPair/TradingPairData.sol
  • contracts/position_trading/PositionsFactory.sol
  • contracts/giga_swap_erc20_token/vote/executors/GigaSwapTokenSetExtraContractAddressVote.sol
  • contracts/votes/VoteExecutorBase.sol
  • contracts/fixed_price_sales/IErc20Sale.sol
  • contracts/swapper/DealPointRef.sol
  • contracts/position_trading/algorithms/TradingPair/ITradingPairFeeDistributer.sol
  • contracts/lib/erc20/IErc20ForFactoryFactory.sol
  • contracts/fee/FeeSettingsDecorator.sol
  • contracts/position_trading/AssetData.sol
  • contracts/swapper/GigaSwap.sol
  • contracts/swapper/IDealPointsController.sol
  • contracts/votes/IVoteExecutor.sol
  • contracts/swapper/DealsFactory.sol
  • contracts/position_trading/assets/AssetsControllerBase.sol
  • contracts/swapper/Deal.sol
  • contracts/position_trading/algorithms/PositionAlgorithm.sol
  • contracts/giga_swap_erc20_token/vote/GigaSwapTokenWriter.sol
  • contracts/position_trading/AssetCreationData.sol
  • contracts/giga_swap_erc20_token/vote/executors/GigaSwapTokenSetShareVote.sol
  • contracts/weth/IgWETH.sol
  • contracts/swapper/IDealsController.sol
  • contracts/fixed_price_sales/IErc20SaleCounterOffer.sol
  • contracts/position_trading/algorithms/TradingPair/TradingPairConstraints.sol
  • contracts/lib/ownable/IOwnable.sol
  • contracts/fee/IFeeSettingsSetters.sol
  • contracts/position_trading/algorithms/TradingPair/ITradingPairAlgorithm.sol
  • contracts/swapper/plugins/erc721/erc721item/Erc721ItemDealPointsController.sol
  • contracts/position_trading/ItemRefAsAssetLibrary.sol
  • contracts/swapper/plugins/erc20/IErc20DealPointsController.sol
  • contracts/lib/ownable/Ownable.sol
  • contracts/votes/VoteDataLib.sol
  • contracts/swapper/plugins/erc721/erc721count/IErc721CountDealPointsController.sol
  • contracts/position_trading/assets/Erc721ItemAssetsController.sol
  • contracts/swapper/plugins/erc721/erc721count/Erc721CountDealPointsController.sol
  • contracts/lib/factories/ContractData.sol
  • contracts/position_trading/AssetTransferData.sol
  • contracts/swapper/plugins/erc20/Erc20DealPointsController.sol
  • contracts/giga_swap_erc20_token/vote/executors/GigaSwapTokenSetBuyFeeVote.sol
  • contracts/fee/IFeeSettings.sol
  • contracts/position_trading/algorithms/TradingPair/FeeSettings.sol
  • contracts/lib/erc20/Erc20ForFactoryFactory.sol
  • contracts/giga_swap_erc20_token/vote/executors/GigaSwapTokenSetWithdrawAddressVote.sol
  • contracts/giga_swap_erc20_token/vote/executors/GigaSwapTokenSetSellFeeVote.sol
  • contracts/position_trading/algorithms/PositionLocker/PositionLockerAlgorithm.sol
  • contracts/swapper/plugins/erc721/erc721item/IErc721ItemDealPointsController.sol
  • contracts/position_trading/IPositionsController.sol
  • contracts/votes/VoteData.sol
  • contracts/position_trading/algorithms/TradingPair/TradingPairReader.sol
  • contracts/lib/factories/HasFactories.sol
  • contracts/position_trading/PositionsController.sol
  • contracts/fee/vote/FeeSettingsSetFeePercentVote.sol
  • contracts/giga_swap_erc20_token/vote/IGigaSwapTokenSetters.sol
  • contracts/votes/Vote.sol
  • contracts/fixed_price_sales/Erc20Sale.sol
  • contracts/farming/IFarming.sol
  • contracts/position_trading/ItemRef.sol
  • contracts/swapper/DealPointDataInternal.sol
  • contracts/position_trading/IAssetsController.sol
  • contracts/position_trading/assets/Erc20AssetsController.sol
  • contracts/lib/factories/IHasFactories.sol
  • contracts/fee/vote/FeeSettingsSetFeeEthVote.sol
  • contracts/position_trading/IAssetListener.sol
  • contracts/position_trading/algorithms/TradingPair/TradingPairFeeDistributer.sol
  • contracts/lib/ownable/OwnableSimple.sol
  • contracts/swapper/plugins/ether/IEtherDealPointsController.sol
  • contracts/position_trading/PositionSnapshot.sol
  • contracts/position_trading/algorithms/PositionLockerBase.sol
  • contracts/position_trading/assets/EthAssetsController.sol
  • contracts/swapper/plugins/ether/EtherDealPointsController.sol
  • contracts/position_trading/IPositionAlgorithm.sol
  • contracts/position_trading/algorithms/TradingPair/TradingPairAlgorithm.sol
  • contracts/farming/Farming.sol

Part of GigaSwap’s security record

GigaSwap
Audits1 audit by 1 firmLast audit Feb 2024, by CertiK.
Critical findingsNo open critical findingsIn that report, 1 critical finding was reported. It is marked fixed by the firm that reported it.
Open GigaSwap’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us