CertiK reviewed OneDEX Website (OneDex Audit) on 12 Jan 2024: 12 findings, 0 critical; 6 marked fixed, 6 acknowledged.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 2 | 0 |
| Medium | 0 | 0 | 1 |
| Low | 0 | 4 | 5 |
In program `bridge`, the role `admin_authority` has privilege over the following instructions: - `pause`: pause the program from `execute_transfer`. - `unpause`: unpause the program. - `transfer_admin`: transfer admin to the new authority. - `renounce_admin`: transfer admin to `Pubkey::default()`. - `set_quorum`: update quorum value, which will be used to verify the signatures while transferring. - `add_relayer`: add new relayer account. - `remove_relayer`: remove a relayer account. the role `relayer` has privilege over the following instructions: - `renounce_relayer`: remove self from the relayer list. - `execute_transfer`: execute the token transfer. In program `tokens_safe`, the role `admin_authority` has privilege over the following instructions: - `pause`: pause the program from `deposit`. - `unpause`: unpause the program. - `transfer_admin`: transfer admin to the new authority. - `renounce_admin`: transfer admin to `Pubkey::default()`. - `transfer_bridge`: update the bridge authority. - `whitelist_token`: create/update the whitelisted token setting. - `remove_token_from_whitelist`: update the whitelisted token setting. - `set_batch_slot_limit`: update the slot setting for the batch. - `set_batch_size`: update batch size setting for the batch. - `set_token_min_limit`: update minimum token for deposit. - `set_token_max_limit`: update maximum token for deposit. - `init_supply`: do initial deposit for the given token. - `recover_lost_funds`: move extra token when the token is whitelisted or move all non-whitelisted token. the role `bridge` has privilege over the following instructions: - `bridge_transfer`: transfer funds from `safe_settings` ATA account to recipients. Any compromise to the privileged roles may allow the hacker to take advantage of this authority. The hackers may manipulate the cross-chain transfers. Such actions could result in financial losses for both the project and its users. Also, the Solana platform allows for the possibility of upgrading its programs, with the default upgrade authority being the entity responsible for deployment. In situations where the program has upgradability features and the account of the upgrade authority becomes compromised, there is the potential for an unauthorized and malicious update to the program. Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. Based on the collected information and further conducted investigation, the project failed to pass the criteria with a certain amount of negative signals. Thus the case analysis concluded that there is potential high risk to the project. We strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.
The function `tokens_safe::recover_lost_funds()` allows the admin to transfer tokens from any account owned by the token safe to the admin's token account. The amount transferred is dependent on whether or not the token is whitelisted. ```rust=73 pub fn recover_lost_funds(ctx: Context<RecoverLostFunds>) -> Result<()> { let whitelisted_token_details = &ctx.accounts.whitelisted_token; let available_balance = ctx.accounts.send_from.amount; let available_to_withdraw = if whitelisted_token_details.is_whitelisted { available_balance - whitelisted_token_details.balance } else { available_balance }; ``` In the situation where the token is not whitelisted, then the admin is able to transfer all tokens within the token account. Since the admin is able to freely decide if a token should be whitelisted or not, this allows the admin to be able to take all user deposited tokens. ```rust=23 pub fn remove_token_from_whitelist(&mut self) -> Result<()> { self.is_whitelisted = false; Ok(()) } ``` Important Note: Certain identification and KYC procedures were attempted to be applied to the project team in order to better understand the centralization situation and potential risks of the project. Based on the collected information and further conducted investigation, the project failed to pass the criteria with a certain amount of negative signals. Thus the case analysis concluded that there is potential high risk to the project. We strongly advise end users to conduct further research and exercise due diligence before engaging with the project. It is crucial for end users to independently verify and assess all available information to make informed decisions.
According to the code logic of this project, we know that the `admin` role can directly call the `init_supply()` function to lock assets in Bridge. **tokens-safe/src/lib.rs** ```rust=141 pub fn init_supply(ctx: Context<InitSupply>, amount: u64) -> Result<()> { require!( ctx.accounts.safe_settings.is_admin(&ctx.accounts.admin_authority), AdminError::NotAdmin ); instructions::whitelisted_token::init_supply(ctx, amount) } ``` However, the following scenario may happen which will result in `executed_transfer` failed due to insufficient funds: 1. `admin` calls the `init_supply()` function to directly lock 200 USDT in the Bridge on Solana 2. Alice on Solana locked 100 USDT into Bridge ( now, Bridge holds 300 USDT ) and get 100 USDT on Ethereum. 3. Bob on Ethereum locked 300 USDT into Bridge and get 300 USDT on Solana. 4. Now, there is no USDT locked in Bridge on Solana. 5. Alice plans to transfer her 100 USDT on Ethereum back to Solana, this cross-chain transaction is executed successfully until `admin` or other users deposits 100 USDT into Bridge on Solana. We would like to check with the team about the plan for the initial supply and the workflow to handle insufficient assets on the target chain.
The program `bridge` and `token-safe` can be initialized via `initialize_settings` instruction and set up accounts with sensitive information for the corresponding program. However, a malicious party can invoke both `initialize_settings` instructions, which will affect both programs.
The current transfer hash will include the following information: ```text ------------------------------------ | "\x19Ethereum Signed Message:\n32" | | recipient | | token_mint | | transfer amount | | deposit nonce | | batch nonce | | "executeTransferAction" | ------------------------------------ ``` However, there is limited information related to the chain if multiple chain exists. As a result, the following circumstances may exceed: 1. The relayer may be able to redeem the same transaction on a different chain. 2. Collision when different chains issue the same deposit nonce and batch nonce.
The transfer status during `executed_transfer` is determined by the following code: ```rust=41 let transfer_status = if do_token_safe_bridge_transfer(&ctx, transfer_request.amount).is_ok() { TransferStatus::EXECUTED } else { TransferStatus::REJECTED }; ``` However, the Solana chain is not support try-catch error handling, as a result, the whole transaction will fail when the CPI call fails. Reference: https://docs.solana.com/proposals/return-data#note-on-returning-errors
The report names a repository or files. Open the report to see its scope.
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething 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