Skip to main content

Deposit and Withdraw

Background Knowledge

  • What is ERC20

    ERC-20 is the technical standard for creating fungible tokens on the Ethereum blockchain. It defines a common set of rules that must be followed for a token to function properly within the Ethereum ecosystem. For further information, please refer to the official guidance available at

  • ERC20 decimal

    Decimals indicate the divisibility of a token, ranging from 0 (non-divisible) to 18 (highly divisible) or even higher if needed.

  • Approve

    Approve is an ERC20 token contract function. It grants permission for a spender (such as an exchange or EOA) to withdraw from your token contract up to a specified value multiple times.

Primary Asset & Secondary Asset

  • Primary asset is the system settlement token used for settling all PNL. It may vary across different chains, but commonly used stablecoins often serve as primary assets. Users can trade on the JOJO Exchange by depositing primary assets as margin. To find the primary asset address, call IDealer#primaryAsset().

  • Secondary asset is designed to solve the liquidity issue of primary assets. It is utilized for trading margin and the multi-collateral system (to be introduced in V1.1). Within the JOJO Exchange, secondary assets are considered equal in value to primary assets. To find the secondary asset address, call IDealer#secondaryAsset().

  • JUSD is a stablecoin issued by JOJO and serves as a secondary asset. It functions similarly to DAI, allowing users to mint JUSD by staking other ERC20 tokens as collateral. While JUSD can be freely traded, its price is not guaranteed to match the primary asset in the open market.


Smart Contract Function

Users deposit primary or secondary assets as margin for trading by calling IDealer#deposit.

/// @notice Deposit fund to get credit for trading
/// @param primaryAmount is the amount of primary asset you want to withdraw.
/// @param secondaryAmount is the amount of secondary asset you want to withdraw.
/// @param to is the account you want to deposit to.
function deposit(
uint256 primaryAmount,
uint256 secondaryAmount,
address to
) external;


Withdrawal Pending Period

  • The withdrawal process consists of two steps: submitting a withdrawal request and executing the withdrawal. The time between these two steps must exceed the timelock value. This design improves the settlement success rate by immediately reducing the user's available balance upon receiving the withdrawal request, preventing invalid matches.

  • The timelock value is in seconds and can be found by calling IDealer#withdrawTimeLock. After submitting a request, users can find the executable timestamp by calling IDealer#withdrawExecutionTimestamp. Pending amount requests can be found by calling IDealer#pendingSecondaryWithdraw and IDealer#pendingPrimaryWithdraw.

  • Prior to withdrawal, the system assesses the safety of the account's positions by checking:

    netPositionValue+primaryCredit+secondaryCreditmaintenanceMarginnetPositionValue +primaryCredit + secondaryCredit \geq maintenanceMargin
  • If a trader attempts to withdraw any amount of the primary asset, an additional check is performed:

netPositionValue+primaryCredit0netPositionValue + primaryCredit \geq 0
  • This check prevents users from depositing secondary assets and withdrawing primary assets, which would infringe on the liquidity of primary assets and violate the multi-collateral protocol's intent.

  • For internal transfers, only internal credit changes occur, and no ERC20 transfers take place.

Smart Contract Function

function requestWithdraw(uint256 primaryAmount, uint256 secondaryAmount) external;

/// @notice Execute the withdrawal request.
/// @param to is the address receiving assets.
/// @param isInternal Only internal credit transfers will be made,
/// and ERC20 transfers will not happen.
function executeWithdraw(address to, bool isInternal) external;