JOJO - Ⅲ

CertiKFiles named in the report

CertiK reviewed JOJO (JOJO - Ⅲ) on 9 Dec 2022: 18 findings, 0 critical; 11 marked fixed, 3 acknowledged, 4 open.

No open critical findings
Open the reportOpen JOJO’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings18

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

SeverityOpenAcknowledgedFixed
Critical000
High010
Medium020
Low4011
Low`external` functions can accept `calldata` argumeFixed

`external` functions can accept `calldata` arguments instead of `memory`, if the arguments are not modified. It allows to avoid copying and save gas.

Low`liquidationThreshold` scaling factor can be declFixed

`liquidationThreshold` is represented as a fixed-point number with the scaling factor `10**18`. It can be declared as a constant to improve the code readability. Same factor is used by `liquidationPriceOff`, `insuranceFeeRate`.

Low`params` can use `storage` specifierFixed

In `_isAllSafe()` the local variable `params` is declared as `memory`. However, only two fields are accessed. The variable can be declared as `storage`.

Low`view` functions can be declared in `JOJOView`Fixed

`JOJOExternal` implements several `view` functions: `isSafe()`, `isAllSafe()`, `getFundingRate()`. They can be moved to `JOJOView` for consistency.

LowFailed `ERC2362.valueFor()` request is not handleFixed

`EIP-2362` standard defines the status codes returned by `valueFor()`. `valueFor()` will return a status code of 404 if the value for an id is not available yet, 400 in case of bad request. `getMarkPrice()` doesn't handle the status codes.

LowIncompatibility 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=72 IERC20(state.secondaryAsset).safeTransferFrom( msg.sender, address(this), secondaryAmount ); ``` - Transferring tokens by `secondaryAmount`. ```solidity=77 state.secondaryCredit[to] += secondaryAmount; ``` - The `secondaryAmount` appears to be used for bookkeeping purposes without compensating the potential transfer fees.

LowPerpetual asks the Dealer for `fundingRate`Fixed

In `Perpetual.balanceOf()` current `fundingRate` is retrieved via `IDealer(owner()).getFundingRate(address(this))` instead of direct state field access. The trades and liquidations are settled using `fundingRate` directly.

LowSecondary asset `decimals` is not checkedFixed

`setSecondaryAsset()` allows to set any address as `secondaryAsset`. It can't later be reassigned. `decimals` is not checked, however, expected to be the same as `primaryAsset`. Wrong `secondaryAsset` will break the contract.

LowTyposFixed

"shoule" is supposed to be "should". "happens" is supposed to be "happen". "ALREASY" is supposed to be "ALREADY". "LEASE" is supposed to be "LEAST". "Operatiors" is supposed to be "Operators". "implemnents" is supposed to be "implementation". "newReducedCredkt" is supposed to be "newReducedCredit". "mathcing" is supposed to be "matching". "whold" is supposed to be "whole". And some others.

LowUninitialized State Variable `roundId`Fixed

One or more state variables are used without being initialized in the constructor. ```solidity=15 uint256 public roundId; ``` - `roundId` is never initialized, but used in `EmergencyOracle.setMarkPrice`.

Show 1 more
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 (26)

  • contracts/adaptor/constOracle.sol
  • contracts/impl/Perpetual.sol
  • contracts/lib/Position.sol
  • contracts/lib/Liquidation.sol
  • contracts/impl/JOJOOperation.sol
  • contracts/intf/IDecimalERC20.sol
  • contracts/fundingRateKeeper/FundingRateUpdateLimiter.sol
  • contracts/lib/Types.sol
  • contracts/lib/Funding.sol
  • contracts/utils/SignedDecimalMath.sol
  • contracts/intf/IMarkPriceSource.sol
  • contracts/utils/Errors.sol
  • contracts/intf/IDealer.sol
  • contracts/impl/JOJOStorage.sol
  • contracts/adaptor/chainlinkAdaptor.sol
  • contracts/subaccount/SubaccountFactory.sol
  • contracts/intf/IPerpetual.sol
  • contracts/lib/Operation.sol
  • contracts/impl/JOJODealer.sol
  • contracts/impl/JOJOView.sol
  • contracts/adaptor/emergencyOracle.sol
  • contracts/lib/EIP712.sol
  • contracts/lib/Trading.sol
  • contracts/subaccount/Subaccount.sol
  • contracts/adaptor/witnetAdaptor.sol
  • contracts/impl/JOJOExternal.sol

Part of JOJO’s security record

JOJO
Audits1 audit by 1 firmLast audit Dec 2022, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open JOJO’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