Lightlink Bridge - Audit Report

Table Of Content

Share:

Introduction

BlockApex (Auditor) was contracted by LightLink (Client) for the purpose of conducting a Smart Contract Audit/ Code Review. This document presents the findings of our analysis, which started on 12th June ‘2023.

Name
LightLink Bridge
Audited by
Moazzam Arif | Muhammad Jarir Uddin
Platform
Ethereum and EVM Compatible Chains | Solidity
Type of review
Manual Code Review | Automated Tools Analysis
Methods
Architecture Review | Functional Testing | Computer-Aided Verification | Manual Review
Git repository/ Commit Hash
Private Repo | b8eab88ce573a7b6150c36afd62590fe21f171d0
White paper/ Documentation
Whitepaper for LightLink Network
Document log
Initial Audit Completed: June 22nd ‘2023
Final Audit Completed: July 3rd ‘2023

Scope

The shared git-repository was checked for common code violations and vulnerability-specific probing to detect major issues/vulnerabilities. Some specific checks are as follows:

Code reviewCode review Functional review
ReentrancyUnchecked external callBusiness Logics Review
Ownership Takeover ERC20 API violationFunctionality Checks
Timestamp DependenceUnchecked mathAccess Control & Authorization
Gas Limit and LoopsUnsafe type inferenceEscrow manipulation
DoS with (Unexpected)
Throw
Implicit visibility levelToken Supply manipulation
DoS with Block Gas LimitDeployment ConsistencyAsset’s integrity
Transaction-Ordering
Dependence
Repository ConsistencyUser Balances manipulation
Style guide violationData ConsistencyKill-Switch Mechanism
Costly LoopOperation Trails & Event
Generation

Project Overview

LightLink Bridge is a core component of the LightLink network, a high-performance, secure, and scalable solution built on Ethereum. The bridge serves as a conduit for assets between Ethereum's Layer 1 (L1) and Layer 2 (L2), enabling fast and low-cost transactions. It is designed to unlock the power of Layer 2 scaling solutions, thereby enhancing the efficiency and scalability of the Ethereum network.

LightLink Bridge

The LightLink Bridge supports a wide range of token standards, including ERC20, ERC721, ERC1155, and native tokens, making it highly versatile and adaptable for various applications. It is built to onboard new users, offering both Enterprise mode and standard transacting. This flexibility, combined with the optionality to pay fees in either ETH or its native token, LL, makes LightLink Bridge a powerful tool for asset management on the Ethereum network.

With its highly composable nature, LightLink Bridge is suitable for a wide range of applications, including enterprise ecosystems, gaming and metaverse projects, ticketing, and identity management. It represents a significant advancement in Layer 2 scaling solutions, contributing to the ongoing development and evolution of the Ethereum ecosystem. 

System Architecture

The LightLink Bridge system architecture is based on a Proof-of-Authority mechanism with an external validator set that stakes its individual reputation in order to earn incentives for the trades on the LightLink bridge. This ensures a robust and interconnected framework enabling seamless asset transfers between Ethereum's Layer 1 and Layer 2. The bridge architecture consists of several key components, each playing a crucial role in the overall operation of the bridge. 

These components include Bridge Registries, Predicates Proxies, Token Proxies, and some helper libraries.

Bridge Registries:

Bridge Registries are the core of the LightLink Bridge, maintaining the mapping information for each token. The registries are divided into L1 and L2 Bridge Registries, each responsible for operations on their respective Ethereum layers. 

  • The L1BridgeRegistry contract manages the mapping of L1 tokens to their corresponding L2 tokens, 
  • while the L2BridgeRegistry contract manages the mapping of L2 tokens to their corresponding L1 tokens. 

These registries ensure the accurate representation and tracking of assets across layers.

Predicates Proxies:

Token Predicates Proxies handle the deposit and withdrawal operations for different token standards. They include L1 and L2 Predicate contracts for ERC20, ERC721, ERC1155, and native tokens. 

  • The L1 Predicate contracts are responsible for locking &and unlocking tokens on L1 and emitting events that the L2 contracts listen for. 
  • Conversely, the L2 Predicate contracts listen for these events and mint & burn the corresponding tokens on L2. 

These proxies ensure the secure and accurate transfer of assets between layers.

Token Proxies:

Token Proxies are responsible for creating and operating L2 tokens. They include templates for ERC20, ERC721, ERC1155, and native tokens. These templates are used to create new L2 tokens that represent the L1 assets. The Token Proxies interact with the Bridge Registries and the Predicate Proxies to ensure the accurate representation of L1 assets on L2.

Prerequisites:

The Prerequisite include Multisig contracts on both L1 and L2. These contracts provide the necessary security measures for the management of assets and the execution of transactions. The Multisig contracts require multiple signatures for certain operations, adding an extra layer of security. They are crucial for the operation of the Bridge Registries and the Predicate Proxies.

Libraries:

Libraries in the ecosystem provide additional functionalities that enhance the operation of the LightLink Bridge. They include Create2, MemberSet, and ValidatorSet libraries. 

  • The Create2 library is used for deterministic contract creation, specifically targeting contracts on L2 and ensuring that the same address is generated every time a contract is created with the same parameters. 
  • The MemberSet library manages the members of a set, providing functions for adding, removing, and checking members of the multi-sig contracts on both chains. 
  • The ValidatorSet library handles all the external validators in a set, providing functionality to manage the validators in order to modify the details of validators or even remove certain validators once approved by the multi-sig. 

These libraries provide essential tools for the efficient operation of the LightLink Bridge.

Methodology & Scope

The codebase was audited using a filtered audit technique. A band of two (2) auditors scanned the codebase in an iterative process for a time spanning ten (10) days. 

Starting with the recon phase, a basic understanding was developed, and the auditors worked on developing presumptions for the developed codebase and the relevant documentation/whitepaper. Furthermore, the audit moved on with the manual code reviews to find logical flaws in the codebase complemented with code optimizations, software, and security design patterns, code styles, best practices, and identifying false positives detected by automated analysis tools.

Focus of Security Audit

LightLink, being a POA bridge, relies on a set of trust assumptions considering its external validators. The smart contracts' technical interpretation of this trust is reflected in the validity of off-chain signed messages, watched events, and signatures.

The focus of this audit revolved around a targeted niche of attack vectors which further expanded to a spectrum of vulnerabilities that present themselves in the scope of smart contracts and hence arise in the following cases; 

  • Securely managing the validators set and recording legitimate signatures.
    • Ensuring vulnerabilities relevant to signatures, e.g., Signature malleability, Signature replay, etc. are always taken care of.
  • Securely managing the multi-sig members’ and validators’ records with the least censorship to handle malicious ones.
    • In any case of leaked keys of the above members, a pause/ revoke functionality along with recovery of funds be utilized in the LightLink Bridge smart contracts complex.
  • Event emission is always up to mark.
    • In no case, the validators should receive sub-standard data to validate and verify.

Security Gaps:

Listed below is a set of security assumptions that are ensured to only work with the respective security controls if the smart contracts are implemented correctly.

  1. There is no risk of complete loss if the threshold of validators’ private keys is secured.
    1. We assume that all validators’ private keys should be protected following the highest mode of security (e.g., hardware wallets, etc.)
    2. We assume that the threshold of validators’ voting should justify the risk of a complete loss.
  2. There is no risk of complete loss if the multi-sig private key is secured.
    1. We assume that the multi-sig private keys should be protected following the highest mode of security (e.g., hardware wallets, etc.)
    2. While it is a fairly low risk that all validators plus the members’ private keys are compromised, the role of the multi-sig balances out the total loss.
  3. The maximum impact of leak validator private keys should be calculated.
    1. Building up to the assumption in 1.a., in the worst of cases, enough validators compromised could allow attackers to perform as many withdrawals as they want.
  4. Censorship is unlikely.
    1. We assume that all validators’ private keys are available in case to vote out the malicious validators.

Audit Report

Executive Summary

Our team performed a technique called Filtered Audit, where two individuals separately audited the LightLink Bridge.

After a thorough and rigorous manual testing process involving line-by-line code review for bugs, an automated tool-based review was carried out using Slither for static analysis and Foundry for fuzzing invariants. 

All the flags raised were manually reviewed and re-tested to identify the false positives

lightlink - meter

Our Team Found

# of issuesSeverity Of the Risk
0Critical Risk Issues(s)
1High Risk Issues(s)
1Medium Risk Issues(s)
4Low Risk Issues(s)
4Informatory Risk Issues(s)

Key Findings

#FindingsRiskStatus
1Centralization Risk Due to Majority Power SaturationHighFixed
2Violation of Checks-Effects-Interactions PatternMedium Fixed
3Missing Pause FunctionalityLowFixed
4Absence of Recovery FunctionalityLowFixed
5Missing Input Validations in Multisigable ContractLowFixed
6Length Check for Input Array ArgumentsLowFixed
7Lack of Events in Crucial FunctionsInfoFixed
8Use Calldata for Function ArgumentsGas-OptFixed
9Use Custom Error Messages for Revert StatementsGas-OptResolved
10Substandard Order of Layout Incurs Higher Gas CostsGas-OptFixed

Detailed Overview

High-risk issues

1. Centralization Risk Due to Majority Power Saturation

Path:

contracts/bridge/core/L1/L1BridgeRegistry.sol contracts/bridge/core/L2/L2BridgeRegistry.sol

Status: Fixed

Function Name:

__L1BridgeRegistry_init
__L2BridgeRegistry_init

Description: 

The __L1BridgeRegistry_init and __L2BridgeRegistry_init functions in the respective contracts initialize two validators with different powers. One of the validators is assigned a majority power (50 out of 70), which poses a centralization risk. This validator has the ability to influence the rest of the validators and control the overall protocol direction.

Code Affected:

The entire protocol is potentially vulnerable due to this centralization risk. 
function __L1BridgeRegistry_init() internal {
  validators.add(0x574f879160252895a4b15fF9316bf9e9ADc46423, 50); // Majority power
  validators.add(0x2681682d1197131D339a169dF10940470D602806, 20);
  consensusPowerThreshold = 70;
}

Note: The same function is initialized in the L2BridgeRegistry contract as well.

Impact:

The validator with an influential powerThreshold can control the protocol's decisions, leading to a centralized system. This is contrary to the decentralized nature of blockchain systems and could lead to misuse or manipulation of the protocol.

Recommendation:

It is recommended to distribute the power among multiple validators to reduce the centralization risk. This can be achieved by breaking down the validator power saturation into multiple validators right from the beginning. The updated code could look like this:

function __L1BridgeRegistry_init() internal {
  validators.add(0x574f879160252895a4b15fF9316bf9e9ADc46423, 35); // Reduced power
  validators.add(0x2681682d1197131D339a169dF10940470D602806, 35); // Increased power
  consensusPowerThreshold = 70;
}

Another option to prevent the consensusPowerThreshold from being saturated is to increase the number of validators in the registry contract.

High-risk issues

2. Violation of Checks-Effects-Interactions Pattern

Path:

contracts/bridge/core/L1/predicates/**

contracts/bridge/core/L2/predicates/**

Status: Fixed

Description:

The mapToken function in the Predicate contracts violates the Checks-Effects-Interactions pattern, potentially opening a door to reentrancy attacks. The function first interacts with the childToken contract by calling its initialize function. Only after this interaction is done, it updates its own state (l1ToL2Gateway[l1Token]=childToken) and emits an event (TokenMapped). 

This coding pattern is against the best practices where during reentrancy the check for mapping require(l1ToL2Gateway[l1Token] == _l2Token, "Token not mapped"); can be bypassed easily.  

Code-Affected: 

// call initialize using call
(bool success, bytes memory data) = childToken.call(
  abi.encodeWithSignature(
    "initialize(address,bytes)", //
    implTemplate,
    // encode function data for initialize
    abi.encodeWithSignature("initialize(address,address,address)", multisig, address(this), l1Token)
  )
);

require(success, string(data));

// map the token
l1ToL2Gateway[l1Token] = childToken; // State changes violating CEI pattern
emit TokenMapped(messageHash);

Impact: 

This pattern violation could potentially allow a malicious childToken contract to reenter the Predicate contract before it has a chance to update its state, leading to possible reentrancy attacks. Although in the current implementation of the smart contract complex, the pattern does not directly impact the flow of mapping tokens, in cases of malicious tokens or scenarios this practice could come in handy to an adversary.

Recommendation: 

To mitigate this risk, the Predicate contracts should adhere to the Checks-Effects-Interactions pattern. This means they should perform all state changes such as  (l1ToL2Gateway[l1Token] = childToken) before interacting with external contracts (childToken.call()). This, combined with a non-reentrant modifier, can eliminate the reentrancy attack window to a large extent, if not completely.

Low-risk Issues

3. Missing Pause Functionality

Path:

contracts/bridge/core/L1/predicates/**

contracts/bridge/core/L2/predicates/**

contracts/bridge/core/L1/L1BridgeRegistry.sol

contracts/bridge/core/L2/L2BridgeRegistry.sol

Status: Fixed

Description:

The BridgeRegistry and associated predicate contracts do not implement a pause or revoke functionality. This could potentially lead to a situation where, in the event of a detected vulnerability or an ongoing attack, there is no way to immediately halt the execution of the contracts to prevent further damage or loss of funds.

Code-Affected: 

The entire contract is potentially vulnerable due to the lack of a pause or revoke functionality. 

Impact: 

Without a pause or revoke function, the contract is vulnerable to continued exploitation in the event of a detected vulnerability or an ongoing attack. This could lead to a significant loss of funds and could potentially undermine trust in the contract.

Recommendation: 

It is highly recommended to implement a pause or revoke function in the L1BridgeRegistry contract and its associated predicate contracts. This function should only be accessible by the contract owner or a designated emergency account. This would allow for immediate action in the event of a detected vulnerability or an ongoing attack, potentially saving significant amounts of funds and preserving the integrity of the contract.

4. Absence of Recovery Functionality

Path:

contracts/bridge/core/L1/predicates/**

contracts/bridge/core/L2/predicates/**

contracts/bridge/core/L1/L1BridgeRegistry.sol

contracts/bridge/core/L2/L2BridgeRegistry.sol

Status: Fixed

Description:

The BridgeRegistry and associated predicate contracts do not implement a recovery functionality. This could potentially lead to a situation where, in the event of an accidental transfer or a bug causing the tokens to be stuck in a contract, there is no way to recover the funds.

Code-Affected: 

The entire contract is potentially vulnerable due to the lack of a recovery functionality. 

Impact: 

Without a recovery function, the contract is vulnerable to permanent loss of funds in the event of an accidental transfer or a bug causing the tokens to be stuck. This could lead to significant loss of funds and could potentially undermine trust in the contract.

Recommendation: 

It is recommended to implement a recovery function in the L2NativeTokenPredicate contract and its associated contracts. This function should only be accessible by the contract owner or a designated emergency account. This would allow for immediate action in the event of accidental transfers or bugs causing tokens to be stuck, potentially saving significant amounts of funds and preserving the integrity of the contract.

5. Missing Input Validations in Multisigable Contract

Path: contracts/bridge/prerequisite/Multisigable.sol

Status: Fixed

Description:

The Multisigable contract does not perform input validation in the __Multisigable_init and modifyMultisig functions. Specifically, it does not check if the input address is a zero address.

Code-Affected: 

function __Multisigable_init(address _multisig) internal {
  multisig = _multisig;
}

function modifyMultisig(address _multisig) public requireMultisig {
  multisig = _multisig;
}

Impact: 

Without input validation, the contract is susceptible to accidental or malicious misuse. If a zero address is passed to these functions, it could lead to loss of control over the state variables as no valid Ethereum account corresponds to the zero address.

Recommendation: 

Adding input validation checks in these functions is recommended to prevent the assignment of a zero address. This could be done by adding the following checks on top of both functions.

require(_multisig != address(0), "Multisig address cannot be zero") 

6. Length Check for Input Array Arguments

Path:

contracts/bridge/core/L1/L1BridgeRegistry.sol

contracts/bridge/core/L2/L2BridgeRegistry.sol

Status: Fixed

Description:

The functions modifyValidators, removeValidators, and modifyServiceImplementations function in the Registry contracts do not perform a length check for its input array arguments. This could lead to unexpected behavior if the lengths of the _keys and _implementations arrays are not equal.

Code-Affected: 

Following is one of the instances in the codebase under the scope of audit that is to be considered while applying such constraint.

function modifyServiceImplementations(bytes32[] memory _keys, address[] memory _implementations) public requireMultisig {
  for (uint256 i = 0; i < _keys.length; i++) {
    implementations[_keys[i]] = _implementations[i];
  }
}

Impact: 

If the lengths of the _keys and _implementations arrays are not equal, the function could either skip some _keys or attempt to access an out-of-bounds index in the _implementations array, leading to a revert.

Recommendation: 

Add a length check at the beginning of the function to ensure that the lengths of the _keys and _implementations arrays are equal. The updated code would look like this:

  require(_keys.length == _implementations.length, "Input arrays must have the same length");

on both instances.

Informatory Issues and Optimizations

7. Lack of Events in Crucial Functions

Path:

contracts/bridge/core/L1/L1BridgeRegistry.sol

contracts/bridge/core/L2/L2BridgeRegistry.sol

contracts/bridge/prerequisite/Multisig.sol

contracts/bridge/prerequisite/Multisigable.sol

Status: Fixed

Description:

The Registry, Multisig, and Multisigable contracts do not emit events in the above-mentioned crucial functions; 

Events are crucial in smart contracts as they provide a way to track changes and updates in the contract state. Without them, monitoring and auditing the contract's activities becomes challenging.

Code-Affected: 

// verified
function addMember(address _account) public virtual requireMultisig {
  members.add(_account);
}

Impact: 

The lack of events in these functions makes it difficult to track when a member is added or removed from the multisig and multisigable contracts. This could lead to unnoticed unauthorized changes in the contract's member set and validators being unaware of any ongoing attack.

Recommendation: Emitting events in these functions is recommended to provide an audit trail of when members are added or removed. This could be done by adding emitted events at the end of each state-altering function listed above e.g. emit MemberAdded(_account) in the addMember function.

8. Use Calldata for Function Arguments

File:

contracts/bridge/core/L1/predicates/**

contracts/bridge/core/L2/predicates/**

contracts/bridge/core/L1/L1BridgeRegistry.sol

contracts/bridge/core/L2/L2BridgeRegistry.sol

Status: Fixed

Description:

The user-facing external and public functions in the Predicate contracts use memory modifiers for function arguments. However, these arguments could be declared as calldata to save gas, ultimately restricting any manipulation of the inputs, as calldata is cheaper than memory.

Code-Affected: 

Following is one of the instances in the codebase under the scope of audit that is to be considered while applying such optimization.

function mapToken(address[] memory _currentValidators, bytes[] memory _signatures, bytes memory _message) public { ... }

Recommendation: 

Consider using calldata instead of memory for function arguments. This could save gas costs. The updated code would look like this:

function mapToken(address[] calldata _currentValidators, bytes[] calldata _signatures, bytes calldata _message) public { ... }

9. Use Custom Error Messages for Revert Statements

Path: contracts/bridge/core/**

Status: Resolved

Description:

Throughout the codebase under the scope of the audit, the smart contracts use require statements to enforce constraints of the system. Since the release of the Solidity 0.8.4 version, it is now supported that the require statement be translated to an if block with a custom revert error message incurring lower gas costs and improving the readability.

Code-Affected: 

Following are a few of many instances in the codebase under the scope of audit that are to be considered while applying such optimization.

modifier requireOwner() {
  require(members.contains(msg.sender), "Owner required");
  _;
}

function add(Record storage _record, address _value) internal {
  if (contains(_record, _value)) return;
  _record.values.push(_value);
  _record.indexes[_value] = _record.values.length;
}

Impact: 

Without a recovery function, the contract is vulnerable to permanent loss of funds in the event of an accidental transfer or a bug causing the tokens to be stuck. This could lead to a significant loss of funds and could potentially undermine trust in the contract.

Recommendation: 

It is highly suggested that all the instances in the user-facing functions that are assumed to handle most of the traffic utilize the below-recommended approach which during the bull markets, the gas cost is controlled by design, and users may not need to think twice before interacting with their favorite protocols.

modifier requireOwner() {
  if(!members.contains(msg.sender)     revert OwnerRequired();
  _;
}

function add(Record storage _record, address _value) internal {
  if (contains(_record, _value))      revert RecordExists();
  _record.values.push(_value);
  _record.indexes[_value] = _record.values.length;
}

Developer Response: 

“I believe change error format can reduce deployment cost but will not affect to function cost cause a successful transaction will not run into revert segment and of course in application level, we will not allow users to send a reverted transaction”

Auditor Response: 

Acknowledged with no further action required.

10. Substandard Order of Layout in Registry Contracts Leading to Higher Gas Costs

Path:

contracts/bridge/core/L1/L1BridgeRegistry.sol

contracts/bridge/core/L2/L2BridgeRegistry.sol

Status: Fixed

Description:

The current order of layout in the registry contracts does not follow the best practices suggested by the Solidity style guide. The external functions, which are frequently accessed by users, are discovered later in the bytecode traversal during each function call. This leads to higher gas costs for each transaction.

Code-Affected: 

The entire contract layout is relevant to this issue. The specific code is not included here due to its size.

Impact: 

The current layout order results in higher gas costs for each transaction, making the contract less efficient and more expensive for users to interact with.

Recommendation: 

Following the Solidity style guide's order of layout best practices is recommended. This includes placing the contract's external functions before internal and private ones. By doing so, the external functions will be discovered earlier in the bytecode traversal, reducing the gas costs for each transaction.

Disclaimer

The smart contracts provided by the client for audit purposes have been thoroughly analyzed in compliance with the global best practices to date w.r.t cybersecurity vulnerabilities and issues in smart contract code, the details of which are enclosed in this report.

This report is not an endorsement or indictment of the project or team, and they do not in any way guarantee the security of the particular object in context. This report is not considered and should not be interpreted as an influence on the potential economics of the token, its sale, or any other aspect of the project.

Crypto assets/tokens are the results of emerging blockchain technology in the domain of decentralized finance, and they carry with them high levels of technical risk and uncertainty. No report provides any warranty or representation to any third-Party in any respect, including regarding the bug-free nature of code, the business model or proprietors of any such business model, and the legal compliance of any such business. No third party should rely on the reports in any way, including for the purpose of making any decisions to buy or sell any token, product, service, or another asset. Specifically, for the avoidance of doubt, this report does not constitute investment advice, is not intended to be relied upon as investment advice, is not an endorsement of this project or team, and is not a guarantee as to the absolute security of the project.

Smart contracts are deployed and executed on a blockchain. The platform, its programming language, and other software related to the smart contract can have vulnerabilities that can lead to hacks. The scope of our review is limited to a review of the Solidity code and only the Solidity code we note as being within the scope of our review within this report. The Solidity language itself remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer or any other areas beyond Solidity that could present security risks.

This audit cannot be considered a sufficient assessment regarding the utility and safety of the code, bug-free status, or any other statements of the contract. While we have done our best in conducting the analysis and producing this report, it is important to note that you should not rely on this report only - we recommend proceeding with several independent audits and a public bug bounty program to ensure the security of smart contracts.

More Audits

Vaccify - Building a Resilient Digital Trust Ecosystem

Vaccify is an open-source COVID-19 Initiative of TrustNet. The idea behind it is to issue digital certificates to people who are vaccinated (once the vaccine is available) for COVID-19. It is a Blockchain-based digital identity eco-system for all hospitals, healthcare centers, laboratories, and testing facilities across Pakistan.

Beyond Buzzwords: Exploring the Real Potential of AI and Blockchain Integration

The AI and blockchain integration can help overcome some of the limitations of each technology and create a more secure, transparent, and efficient Web3 ecosystem. This article explores the differences between AI and blockchain, ways to integrate them, use cases, and challenges that need to be addressed.

Blockchain Trilemma: The Three Fighting Factors

Blockchain Trilemma - coined by Vitalik Buterin himself, is a condition in which the blockchain undergoes a compromising stage. It is truly believed that a fully decentralized network can never be scalable and secured at the same time.

Infiltrating the EVM-I: Demystifying Smart Contracts & Auditing

Infiltrating the EVM-I: Demystifying Smart Contracts & Auditing comprises of information about compilation breakdown of solidity code, the vulnerable components of blockchain ecosystem and how Smart contract auditing is crucial.

DEUS DAO - May 6, 2023

The Deus DAO hack had significant financial consequences, with users collectively losing around $6.5 million across Arbitrum, BSC, and Ethereum chains. Furthermore, the hack caused the DEI stablecoin to depeg by more than 80%, destabilizing its value and potentially shaking investor confidence.

Infiltrating the EVM-III: Unravel the Impact Of Blockchain On Bug Fixing!

Fixing a bug in traditional software development is often likened to solving a difficult puzzle, each presenting its own challenges. This task has always been complex and time-consuming. However, resolving bugs in a blockchain system is even more demanding due to its transparent & permissionless nature and the high stakes involved with users' funds.

Rari Capital Hack Analysis & POC

Rari capital got hacked for around $79M through a classic re-entrancy attack. Rari is a fork of compound finance which had this bug fixed earlier. It is not the first time Rari has been a victim of a hack.

Harvest Finance Hack Analysis & POC

Harvest finance got hacked for around $34M due to a flashloan attack which manipulated the price in the Curve pool to retrieve more USDT tokens than originally deposited USDT amount in fUSDT pool.

Rain Protocol Audit Report

Rain Protocol lets you build web3 economies at any scale.Rain scripts are a combination of low level functions (opcodes) like addition and subtraction and very high level functions like fetching an ERC20 balance at a given snapshot ID (Open Zeppelin), or fetching a chainlink oracle price.

1 2 3 11
Designed & Developed by: 
All rights reserved. Copyright 2023