Overview

Starfish Finance
Rank #N/A

Skynet Trust Score

0%
  • Project is Relatively Decentralized
  • Large Market Cap (top 25%)
  • Long-running Project
  • Trust Score is #1 amongst all projects
Security Score
0 / 100
Market & Community
88 / 100

Starfish Finance Info

Starfish Finance aims to be a multichain DeFi x NFT-Fi protocol in the Polkadot ecosystem with multi-token stable and weighted swap (based on Balancer v2), cross-chain aggregation for crypto and NFTs, and unlock the opportunity for liquidity in NFTs.

Audits

Onboarded Date

12/Dec/2022

Contracts

0xa71...9de24

How do you feel about this project's security?
Documents
File Name Type Size Upload Date Action
Zip File 4.57 MB 12 Dec 2021
PDF File 8.89 MB 24 Nov 2021
MP4 File 14.62 MB 19 Nov 2021
XSL File 2.38 KB 14 Nov 2021
Floder File 87.24 MB 08 Nov 2021
PNG File 879 KB 02 Nov 2021
Activities
Oliver Phillips New

We talked about a project on linkedin.

Today
N
Nancy Martino In Progress

Create new project Buildng product

Yesterday
Natasha Carey Completed

Adding a new event with attachments

25 Nov
Bethany Johnson

added a new member to velzon dashboard

19 Nov
Your order is placed Out of Delivery

These customers can rest assured their order has been placed.

16 Nov
Lewis Pratt

They all have something to say beyond the words on the page. They can come across as casual or neutral, exotic or graphic.

22 Oct
Monthly sales report

2 days left notification to submit the monthly sales report. Reports Builder

15 Oct
New ticket received Completed

User Erica245 submitted a ticket.

26 Aug
Nancy Martino

Team Leader & HR

225

Projects

197

Tasks

HB
Henry Baird

Full Stack Developer

352

Projects

376

Tasks

Frank Hook

Project Manager

164

Projects

182

Tasks

Jennifer Carter

UI/UX Designer

225

Projects

197

Tasks

ME
Megan Elmore

Team Leader & Web Developer

201

Projects

263

Tasks

Alexis Clarke

Backend Developer

132

Projects

147

Tasks

NC
Nathan Cole

Front-End Developer

352

Projects

376

Tasks

Joseph Parker

Team Leader & HR

64

Projects

93

Tasks

Erica Kernan

Web Designer

345

Projects

298

Tasks

DP
Donald Palmer

Wed Developer

97

Projects

135

Tasks

Showing 1 to 10 of 12 entries

Code Audit History

1 Audit available
Last Audit was delivered on 12 December 2022

Starfish Finance -Audit

View Findings
5

All Findings

0

Acknowledge

0

Partially

5

Resolved

1
Critical privilege
1
Major privilege
1
Medium privilege
1
Minor privilege
0
Optimization none
1
Informational privilege
0
Discussion none

Method

Audited Files/SHA256

Contracts

0xa719cb79af...9de24

Manual Review Static Analysis
Audit Timeline
Requested on
12 December 2022
Revisioned on
12 December 2022

Formal Verification Result

9 / 38 Properties True
80%

Token Standard

ERC-20

Functions

6

Verified Contract

Starfish Finance (MultiBridgeToken.sol) 1

Starfish Finance Smart Contract Code

                        
                        

// SPDX-License-Identifier: GPL-3.0-only


pragma solidity 0.8.9;


import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import "../../safeguard/Ownable.sol";


/**

 * @title Example Multi-Bridge Pegged ERC20 token

 */

contract MultiBridgeToken is ERC20, Ownable {

    struct Supply {

        uint256 cap;

        uint256 total;

    }

    mapping(address => Supply) public bridges; // bridge address -> supply


    uint8 private immutable _decimals;


    event BridgeSupplyCapUpdated(address bridge, uint256 supplyCap);


    constructor(

        string memory name_,

        string memory symbol_,

        uint8 decimals_

    ) ERC20(name_, symbol_) {

        _decimals = decimals_;

    }


    /**

     * @notice Mints tokens to an address. Increases total amount minted by the calling bridge.

     * @param _to The address to mint tokens to.

     * @param _amount The amount to mint.

     */

    function mint(address _to, uint256 _amount) external returns (bool) {

        Supply storage b = bridges[msg.sender];

        require(b.cap > 0, "invalid caller");

        b.total += _amount;

        require(b.total <= b.cap, "exceeds bridge supply cap");

        _mint(_to, _amount);

        return true;

    }


    /**

     * @notice Burns tokens for msg.sender.

     * @param _amount The amount to burn.

     */

    function burn(uint256 _amount) external returns (bool) {

        _burn(msg.sender, _amount);

        return true;

    }


    /**

     * @notice Burns tokens from an address. Decreases total amount minted if called by a bridge.

     * Alternative to {burnFrom} for compatibility with some bridge implementations.

     * See {_burnFrom}.

     * @param _from The address to burn tokens from.

     * @param _amount The amount to burn.

     */

    function burn(address _from, uint256 _amount) external returns (bool) {

        return _burnFrom(_from, _amount);

    }


    /**

     * @notice Burns tokens from an address. Decreases total amount minted if called by a bridge.

     * See {_burnFrom}.

     * @param _from The address to burn tokens from.

     * @param _amount The amount to burn.

     */

    function burnFrom(address _from, uint256 _amount) external returns (bool) {

        return _burnFrom(_from, _amount);

    }


    /**

     * @dev Burns tokens from an address, deducting from the caller's allowance.

     *      Decreases total amount minted if called by a bridge.

     * @param _from The address to burn tokens from.

     * @param _amount The amount to burn.

     */

    function _burnFrom(address _from, uint256 _amount) internal returns (bool) {

        Supply storage b = bridges[msg.sender];

        if (b.cap > 0 || b.total > 0) {

            // set cap to 1 would effectively disable a deprecated bridge's ability to burn

            require(b.total >= _amount, "exceeds bridge minted amount");

            unchecked {

                b.total -= _amount;

            }

        }

        _spendAllowance(_from, msg.sender, _amount);

        _burn(_from, _amount);

        return true;

    }


    /**

     * @notice Returns the decimals of the token.

     */

    function decimals() public view virtual override returns (uint8) {

        return _decimals;

    }


    /**

     * @notice Updates the supply cap for a bridge.

     * @param _bridge The bridge address.

     * @param _cap The new supply cap.

     */

    function updateBridgeSupplyCap(address _bridge, uint256 _cap) external onlyOwner {

        // cap == 0 means revoking bridge role

        bridges[_bridge].cap = _cap;

        emit BridgeSupplyCapUpdated(_bridge, _cap);

    }


    /**

     * @notice Returns the owner address. Required by BEP20.

     */

    function getOwner() external view returns (address) {

        return owner();

    }

}

Code Audit Findings

Audits Overview

Context
Project Name
Starfish Finance
Platform
Language
Codebase
Commit
About Xamer Audits
Delivery Date
Audit Methodology
Core Components
Vulnerability Summary
VULNERABILITY LEVEL PENDING DECLINED ACKNOWLEDGED PARTIALLY RESOLVED MITIGATED RESOLVED TOTAL
Critical 0 0 0 0 0 1 1
Major 0 0 0 0 0 1 1
Medium 0 0 0 0 0 1 1
Minor 0 0 0 0 0 1 1
Optimization 0 0 0 0 0 0 0
Informational 0 0 0 0 0 1 1
Discussion 0 0 0 0 0 0 0
Review Notes

Overview

The "MultiBridgeToken" Solidity smart contract is an ERC-20 token implementation that extends functionality for bridge interactions. It features minting and burning functions, allowing token creation and destruction. The contract maintains a mapping of bridge addresses to supply data, including caps and totals. The owner can update bridge supply caps, and the contract ensures cap adherence during minting.

It inherits from OpenZeppelin's ERC-20 and includes an "Ownable" component for ownership control. With compatibility for various bridge implementations, this contract facilitates token management and interaction within a multi-bridge ecosystem.

Privileged Roles

In the provided Solidity smart contract, the following privileged roles and their associated capabilities can be identified:

Owner Role:

  • The contract inherits from the `Ownable` contract, indicating an owner role.
  • The owner has exclusive access to the `onlyOwner` modifier, restricting certain functions to be callable only by the contract owner.
  • The owner can update the supply cap for specific bridges using the `updateBridgeSupplyCap` function.

Bridge Roles:

  • Addresses that call the `mint` function are considered bridges.
  • Bridges have the privilege to mint new tokens to a specified address, subject to supply cap checks for the respective bridge.
  • Bridges are also allowed to burn tokens from a specific address, with a reduction in the total minted amount if the bridge enforces a supply cap.

These roles define the access control within the contract, with the owner having overarching control, and specific addresses designated as bridges having the ability to mint and burn tokens within the specified constraints. The contract aims to facilitate controlled token management, particularly in a multi-bridge environment.

Audits Scope

ID FILE SHA256 CHECKSUM
STF MultiBridgeToken.sol ea43925ac94f5c1b67656c9ff7b0191546527f7b8f8d90a53c8d3cb24467161c

STF-01 | Reentrancy Attack Vulnerability

CATEGORY SEVERITY LOCATIONS STATUS
privilege Major

 function _burnFrom(address _from, uint256 _amount) internal returns (bool) {
   Supply storage b = bridges[msg.sender];
     if (b.cap > 0 || b.total > 0) {
 // set cap to 1 would effectively disable a deprecated bridge's ability to burn
   require(b.total >= _amount, "exceeds bridge minted amount");
         unchecked {
     b.total -= _amount;
               }
           }
 _spendAllowance(_from, msg.sender, _amount);
      _burn(_from, _amount);
       return true;
   }

RESOLVED
Description

Location in code: Inside the _burnFrom function
Line number: 152-176
Description:
The _burnFrom function does not utilize the ReentrancyGuard mechanism to prevent reentrancy attacks. An attacker might exploit this vulnerability to manipulate the contract state during execution.

STF-02 | Input Validation Issue

CATEGORY SEVERITY LOCATIONS STATUS
privilege Medium

 function updateBridgeSupplyCap(address _bridge, uint256 _cap) external onlyOwner {

        // cap == 0 means revoking bridge role

        bridges[_bridge].cap = _cap;

        emit BridgeSupplyCapUpdated(_bridge, _cap);

    }

RESOLVED
Description

Location in code: Inside the updateBridgeSupplyCap function
Line number: 202-210
Description:
The updateBridgeSupplyCap function lacks input validation for the bridge address. Without proper validation, an incorrect input may lead to unintended changes in the supply cap.

STF-03 | Event Emittance Issue

CATEGORY SEVERITY LOCATIONS STATUS
privilege Minor

 function burn(uint256 _amount) external returns (bool) {

        _burn(msg.sender, _amount);

        return true;

    }//97

 function burn(address _from, uint256 _amount) external returns (bool) {

        return _burnFrom(_from, _amount);

    }//118

RESOLVED
Description

Location in code: Inside the  burn and burn(address _from, uint256 _amount) functions
Line number: 97 and 118
Description:
The burn functions do not emit events upon successful execution, making it challenging for external systems to track token burns.

STF-04 | Potential Integer Overflow

CATEGORY SEVERITY LOCATIONS STATUS
privilege Critical

function mint(address _to, uint256 _amount) external returns (bool) {

        Supply storage b = bridges[msg.sender];

        require(b.cap > 0, "invalid caller");

        b.total += _amount;

        require(b.total <= b.cap, "exceeds bridge supply cap");

        _mint(_to, _amount);

        return true;

    }

RESOLVED
Description

Location in code: Inside the function mint(address _to, uint256 _amount) external returns (bool)
Line number: 66-80
Description:
The minting function does not perform a proper overflow check when updating the total supply. An attacker could potentially exploit this vulnerability to mint an excessively large amount of tokens, causing an overflow.

STF-05 | Redundant Function

CATEGORY SEVERITY LOCATIONS STATUS
privilege Informational

 function getOwner() external view returns (address) {

        return owner();

    }

RESOLVED
Description

Location in code: Inside the getOwner function
Line number: 219-223
Description:
The function getOwner duplicates functionality provided by the inherited owner() function. Consider removing redundant functions to simplify the contract.