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 standard set of rules that must be followed for a token to function correctly within the Ethereum ecosystem. Please refer to the official guidance at https://docs.openzeppelin.com/contracts/4.x/erc20 for further information.
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 up to a specified value multiple times from your token contract.
Primary Asset & Secondary Asset
The 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. Call
IDealer#primaryAsset()
to find the primary asset address.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. Call
IDealer#secondaryAsset()
to find the secondary asset address.JUSD is a stablecoin that has been issued by JOJO as a secondary asset. It operates in a manner similar to DAI, which means that users can mint JUSD by staking other ERC20 tokens as collateral. While JUSD can be traded freely, it's important to note that its price is not guaranteed to match the primary asset in the open market.
Deposit
Smart Contract Function
Users deposit primary or secondary assets as margin for trading by calling IDealer#deposit
.
/// @notice deposit function: user deposit their collateral.
/// @param from: deposit from which account
/// @param collateral: deposit collateral type.
/// @param amount: collateral amount
/// @param to: account that user want to deposit to
function deposit(address from, address collateral, uint256 amount, address to) external;
Withdraw
Withdrawal Pending Period Mode
To withdraw funds, you need to follow two steps: first, submit a request for withdrawal, and second, execute the withdrawal. Note that the time between these two steps must exceed the
timelock
. This is designed to increase the success rate of settlements by reducing the user's available balance immediately upon receiving the withdrawal request. This step prevents any invalid matches from happening.The
timelock
value, in seconds, can be found by callingIDealer#withdrawTimeLock
. After submitting a withdrawal request, users can find the executable timestamp by callingIDealer#withdrawExecutionTimestamp
. Pending withdrawal amounts can be found by callingIDealer#pendingSecondaryWithdraw
andIDealer#pendingPrimaryWithdraw
.
/// @notice Submit withdrawal request, which can be executed after
/// the timelock. The main purpose of this function is to avoid the
/// failure of counterparty caused by withdrawal.
/// @param from The deducted account.
/// @param primaryAmount is the amount of primary asset you want to withdraw.
/// @param secondaryAmount is the amount of secondary asset you want to withdraw.
function requestWithdraw(
address from,
uint256 primaryAmount,
uint256 secondaryAmount
) external;
/// @notice Execute the withdrawal request.
/// @param from The deducted account.
/// @param to is the address receiving assets.
/// @param isInternal Only internal credit transfers will be made,
/// and ERC20 transfers will not happen.
/// @param param call "to" with param if not null.
function executeWithdraw(
address from,
address to,
bool isInternal,
bytes memory param
) external;
Fast Withdrawal Mode
- In Fast Withdraw mode, the
fastWithdrawDisabled
is turned off. This allows for quick withdrawals without any waiting period when users wish to withdraw funds.
/// @notice Withdraw without waiting.
/// @param from The deducted account.
/// @param to is the address receiving assets.
/// @param primaryAmount is the amount of primary asset you want to withdraw.
/// @param secondaryAmount is the amount of secondary asset you want to
/// @param isInternal Only internal credit transfers will be made,
/// and ERC20 transfers will not happen.
/// @param param call "to" with param if not null.
function fastWithdraw(
address from,
address to,
uint256 primaryAmount,
uint256 secondaryAmount,
bool isInternal,
bytes memory param
) external;
Safe Check
Prior to withdrawal, the system assesses the safety of the account's positions by checking:
If a trader attempts to withdraw any amount of the primary asset, an additional check is performed:
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.
Only internal credit changes occur for internal transfers, and no ERC20 transfers occur.