Overview

SEEDx
Rank #N/A

Profile Summary

Skynet Trust Score

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

Built on the Binance Smart Chain, SEEDx is an AMM that uses a limit and Market order book to provide instantaneous trades, pooled liquidity, and innovative yield-generating features.

Audits

Onboarded Date

22/May/2023

Contracts

0x0cB...7C605

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 23 May 2023

SEEDx -Audit

View Findings
6

All Findings

0

Acknowledge

1

Partially

5

Resolved

0
Critical none
1
Major Privilege
0
Medium none
1
Minor Logical-issue
2
Optimization Gas-optimization
2
Informational Coding-style
0
Discussion none

Method

Audited Files/SHA256

Contracts

0x0cBfDea4F4...7C605

Manual Review Static Analysis
Audit Timeline
Requested on
23 May 2023
Revisioned on
23 May 2023

Formal Verification Result

9 / 38 Properties True
80%

Token Standard

ERC-20

Functions

6

Verified Contract

SEEDx (INRxToken.sol) 1

SEEDx Smart Contract Code

                        
                        

/**

 *Submitted for verification at BscScan.com on 2023-02-16

*/


/**

 *Submitted for verification at Etherscan.io on 2021-05-23

*/


/*

    SPDX-License-Identifier: Apache-2.0

*/

pragma solidity 0.6.9;

pragma experimental ABIEncoderV2;


library SafeMath {

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {

        if (a == 0) {

            return 0;

        }


        uint256 c = a * b;

        require(c / a == b, "MUL_ERROR");


        return c;

    }


    function div(uint256 a, uint256 b) internal pure returns (uint256) {

        require(b > 0, "DIVIDING_ERROR");

        return a / b;

    }


    function divCeil(uint256 a, uint256 b) internal pure returns (uint256) {

        uint256 quotient = div(a, b);

        uint256 remainder = a - quotient * b;

        if (remainder > 0) {

            return quotient + 1;

        } else {

            return quotient;

        }

    }


    function sub(uint256 a, uint256 b) internal pure returns (uint256) {

        require(b <= a, "SUB_ERROR");

        return a - b;

    }


    function add(uint256 a, uint256 b) internal pure returns (uint256) {

        uint256 c = a + b;

        require(c >= a, "ADD_ERROR");

        return c;

    }


    function sqrt(uint256 x) internal pure returns (uint256 y) {

        uint256 z = x / 2 + 1;

        y = x;

        while (z < y) {

            y = z;

            z = (x / z + z) / 2;

        }

    }

}


contract Ownable {

    address public _OWNER_;

    address public _Future_OWNER_;


    // ============ Events ============


    event OwnershipTransferPrepared(address indexed previousOwner, address indexed newOwner);


    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);


    // ============ Modifiers ============


    modifier onlyOwner() {

        require(msg.sender == _OWNER_, "NOT_OWNER");

        _;

    }


    // ============ Functions ============


    constructor() internal {

        _OWNER_ = msg.sender;

        emit OwnershipTransferred(address(0), _OWNER_);

    }


    function transferOwnership(address futureOwner) external onlyOwner {

        require(futureOwner != address(0), "INVALID_OWNER");

        emit OwnershipTransferPrepared(_OWNER_, futureOwner);

        _Future_OWNER_ = futureOwner;

    }


    function claimOwnership() external {

        require(msg.sender == _Future_OWNER_, "INVALID_CLAIM");

        emit OwnershipTransferred(_OWNER_, _Future_OWNER_);

        _OWNER_ = _Future_OWNER_;

        _Future_OWNER_ = address(0);

    }

}


contract SEEDx is Ownable {

    using SafeMath for uint256;


    string public name = "SEEDx";

    uint256 public decimals = 18;

    string public symbol = "SEEDx";

    uint256 public totalSupply;

    uint256 public maxSupply = 25e25;


    mapping(address => uint256) balances;

    mapping(address => mapping(address => uint256)) internal allowed;



    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    event Mint(address indexed user, uint256 value);

    event Burn(address indexed user, uint256 value);

    event Redeem(address indexed sender, address indexed redeemToEthAccount, uint256 value);


    function transfer(address to, uint256 amount) public returns (bool) {

        require(to != address(0), "TO_ADDRESS_IS_EMPTY");

        require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH");


        balances[msg.sender] = balances[msg.sender].sub(amount);

        balances[to] = balances[to].add(amount);

        emit Transfer(msg.sender, to, amount);

        return true;

    }


    function balanceOf(address owner) public view returns (uint256 balance) {

        return balances[owner];

    }


    function transferFrom(

        address from,

        address to,

        uint256 amount

    ) public returns (bool) {

        require(to != address(0), "TO_ADDRESS_IS_EMPTY");

        require(amount <= balances[from], "BALANCE_NOT_ENOUGH");

        require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH");


        balances[from] = balances[from].sub(amount);

        balances[to] = balances[to].add(amount);

        allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount);

        emit Transfer(from, to, amount);

        return true;

    }


    function approve(address spender, uint256 amount) public returns (bool) {

        allowed[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;

    }


    function allowance(address owner, address spender) public view returns (uint256) {

        return allowed[owner][spender];

    }


    function redeem(uint256 value, address redeemToEthAccount) external {

        require(balances[msg.sender] >= value, "Seedx: NOT_ENOUGH");

        balances[msg.sender] = balances[msg.sender].sub(value);

        totalSupply = totalSupply.sub(value);

        emit Redeem(msg.sender, redeemToEthAccount, value);

    }


    function mint(address user, uint256 value) external onlyOwner {

        require(maxSupply >= totalSupply.add(value), "Seedx: MINT_OVERLOAD");

        balances[user] = balances[user].add(value);

        totalSupply = totalSupply.add(value);

        emit Mint(user, value);

        emit Transfer(address(0), user, value);

    }


    function burn(uint256 value) external {

        require(balances[msg.sender] >= value, "Seedx: NOT_ENOUGH");

        balances[msg.sender] = balances[msg.sender].sub(value);

        totalSupply = totalSupply.sub(value);

        emit Burn(msg.sender, value);

        emit Transfer(msg.sender, address(0), value);

    }

}

Code Audit Findings

Audits Overview

Context
Project Name
SEEDx
Platform
Language
Solidity
Codebase
https://github.com/inrxstablecoin/inrxtoken/tree/main/contracts
Commit

55efgwe623bte2563e23sgh23e6d28356egd82ghty

4yetgwtg7236723teyg7et623et2y3eg23et2378ete2

About Xamer Audits
Delivery Date
Audit Methodology
Manual Review, Static Analysis
Core Components
Vulnerability Summary
VULNERABILITY LEVEL PENDING DECLINED ACKNOWLEDGED PARTIALLY RESOLVED MITIGATED RESOLVED TOTAL
Critical 0 0 0 0 0 0 0
Major 0 0 0 0 1 0 1
Medium 0 0 0 0 0 0 0
Minor 0 0 0 0 0 1 1
Optimization 0 0 0 0 0 2 2
Informational 0 0 0 0 0 2 2
Discussion 0 0 0 0 0 0 0
Review Notes

Overview

The INRx contract is an ERC20 token INRx, whose owner has the ability to configure the minters, and pause/unpause the contract.

The contract has been deployed at address following addresses:

Privileged Roles

In the INRx contract, the owner and the minters are adopted to ensure a good runtime behavior in the contract, which was specified in the finding Centralization Risks in INRxToken.sol.

The advantage of those privileged roles in the codebase is that the client reserves the ability to configure the minters, and pause/unpause the contract according to the runtime. It is also worth noting the potential drawbacks of these functions, which should be clearly stated through the client's action/plan. Additionally, if the private keys of the privileged accounts are compromised, the project could have devastating consequences.

Audits Scope

ID FILE SHA256 CHECKSUM
INT INRxToken.sol 316193ff46ad552a0dac0bc14889b084ec7f45ad93efdb152d05f6142e7bc1b5

INT-01 | Centralization Risks

CATEGORY SEVERITY LOCATIONS STATUS
Privilege Major
INRxToken.sol#L280-L280: 280
INRxToken.sol#L300-L300: 300
INRxToken.sol#L306-L306: 306
INRxToken.sol#L331-L331: 331
INRxToken.sol#L336-L336: 336
INRxToken.sol#L709-L709: 709
INRxToken.sol#L713-L713: 713
INRxToken.sol#L784-L784: 784
INRxToken.sol#L791-L791: 791
MITIGATED
Description

In the contract  Black listable _owner authority over the functions shown in the diagram below.

Any compromise to the _owner account may allow the hacker to take advantage of this authority.hacker to take advantage of this authority.

In the contract INRxToken _owner has authority over the functions shown in the diagram below. Any compromise to the_owner  account may allow the hacker  to take advantage of this authority. hacker to take advantage of this authority.

In the contract Ownable _owner has authority over the functions shown in the diagram below. Any compromise to the _owner account may allow the hacker to take advantage of this authority.
Any compromise to the _owner account may allow the hacker to take advantage of this authority.


In the contract Pausable the role _owner has authority over the functions shown in the diagram below.
Any compromise to the _owneraccount may allow the hacker to take advantage of this authority.


Recommendation:

The risk describes the current project design and potentially makes iterations to improve in the security operation and level of decentralization, which in most cases cannot be resolved entirely at the present stage. We advise the client to carefully manage the privileged account's private key to avoid any potential risks of being hacked. In general, we strongly recommend centralized privileges or roles in the protocol be improved via a decentralized mechanism or smart-contract-based accounts with enhanced security practices, e.g., multisignature wallets. Indicatively, here are some feasible suggestions that would also mitigate the potential risk at a different level in terms of short-term, long-term and permanent.

Short Term:

Timelock and Multi sign (⅔, ⅗) combination  mitigate by delaying the sensitive operation and avoiding a single point of key management failure.

  • Time-lock with reasonable latency, e.g., 48 hours, for awareness on privileged operations;
    AND
  • Assignment of privileged roles to multi-signature wallets to prevent a single point of failure due to the private key compromised;
    AND
  • A medium/blog link for sharing the timelock contract and multi-signers addresses information with the public audience.

Long Term:

Timelock and DAO, the combination,  mitigate by applying decentralization and transparency.

  • Time-lock with reasonable latency, e.g., 48 hours, for awareness on privileged operations;
    AND
  • Introduction of a DAO/governance/voting module to increase transparency and user involvement.
    AND
  • A medium/blog link for sharing the timelock contract, multi-signers addresses, and DAO information with the public audience.

Permanent:

Renouncing the ownership or removing the function can be considered  fully resolved.

  • Renounce the ownership and never claim back the privileged roles.
    OR
  • Remove the risky functionality.


Alleviation:

[INRx]: The contract  Blacklistable and its corresponding code is removed in the commit  1579f9db009a9e6c1cc604e542a7db2275aa524e.

Furthermore, for the deployed contract  0xcD6970d5211EfDF2516A4fc73163db7bA812B212 | BSC the ownership was transferred to the gnosis-safe contract( 0xbf5dbafdd31a487129fdb94057f84a0979838055) in the transaction  0xf0c3a8c114039010464d91effdb8fe8fdf665b8a0424a43b46f16c007a54d368.

The gnosis-safe contract requires 3 of 5 owners to confirm the transaction. Here are the 5 owners:

  • 0x25AE640f362AeC6b105cD069dB1e09b25cFc5c31
  • 0x710973C65277AFD47aC354F5f29E82135Ed19739
  • 0x8e4A89e494d7d66046171eD234B1d6211EaD1434
  • 0x90Aa066B6c101Bbb5C5585b88C3B35EDC3dc2593
  • 0xce0b9307cE30Fe0e98Cf6Fc4fb147eb59310b6E4
For the deployed contract  0x8003e379cf1f9f5c5f6781f4549910b2c164c162 | Polygon, the owner is  0x2e4107072b438041e7f9b7e575ce2c501647cf21.
For the deployed contract  0x9c88330c8ab3cf53eef61f4b2e7b2ec8c1e7e164 | Ethereum, the owner is  0x90Aa066B6c101Bbb5C5585b88C3B35EDC3dc2593.

INT-02 | Double-spending allowance to mint token

CATEGORY SEVERITY LOCATIONS STATUS
Logical-issue Minor

INRxToken.sol#L784-L784: 784

RESOLVED
Description

A minter may double-spending his/her allowance being authorized by the owner.

Example:

  • The owner, Alice, configures the minter, Bob, 100 allowances to mint tokens.
  • One day, Alice decides to decrease the allowance to Bob from 100 to 50.
  • Before Alice decreases the allowance, Bob spends the 100 allowances by front-running.
  • Alice continues to configure the minter, Bob, 50 allowances to mint tokens.
  • Bob spends another 50 allowances to mint tokens.

From the above example, we noticed that Bob spends a total of 150 allowances, instead of 50 allowances, even though Alice changed her mind to only give Bob 50 allowances.

Recommendation:

Consider adding a check, in the configureMinter() function, to ensure that the minter is not a minter before.

Example:

  • require(!minters[minter],"should not be a minter before");

Alleviation:

[INRx]: The team resolved this issue by adding a check on the minter parameter in commit 55e7b159832d5c870fd14c209253cd9976b27772.

INT-03 | Dead Code

CATEGORY SEVERITY LOCATIONS STATUS
Coding-style Informational
INRxToken.sol#L104-L104: 104
INRxToken.sol#L243-L243: 243
INRxToken.sol#L252-L252: 252
INRxToken.sol#L257-L257: 257
INRxToken.sol#L373-L373: 373
INRxToken.sol#L387-L387: 387
INRxToken.sol#L400-L400: 400
INRxToken.sol#L446-L446: 446
INRxToken.sol#L479-L479: 479
INRxToken.sol#L492-L492: 492
INRxToken.sol#L507-L507: 507
INRxToken.sol#L574-L574: 574
INRxToken.sol#L588-L588: 588
RESOLVED
Description

One or more internal functions are not used.

    function reset(Counter storage counter) internal {

    function _disableInitializers() internal virtual {

    function _getInitializedVersion() internal view returns (uint8) {

    function _isInitializing() internal view returns (bool) {

    function toHexString(uint256 value) internal pure returns (string memory) {

    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {

    function toHexString(address addr) internal pure returns (string memory) {

    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {

    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {

    function tryRecover(

    function recover(

    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {

    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {

Recommendation:

We recommend removing those unused functions.

Alleviation:

[INRx]: The team resolved this issue by removing the unused functions in commit 55e7b159832d5c870fd14c209253cd9976b27772.

INT-04 | Unused Event

CATEGORY SEVERITY LOCATIONS STATUS
Coding-style Informational
INRxToken.sol#L290-L290: 290
INRxToken.sol#L319-L319: 319
RESOLVED
Description

event PauserChanged(address indexed newAddress);

    PauserChanged is declared in Pausable but never emitted.

    event BlacklisterChanged(address indexed newBlacklister);

    BlacklisterChanged is declared in Blacklistable but never emitted.

Recommendation:

We advise removing the unused events or emitting them in the intended functions.

Alleviation:

[INRx]: The team resolved this issue by removing the unused events in commit 55e7b159832d5c870fd14c209253cd9976b27772.

 

INT-05 | Unnecessary Use of SafeMath

CATEGORY SEVERITY LOCATIONS STATUS
Gas-optimization Optimization
INRxToken.sol#L5-L5: 5
INRxToken.sol#L720-L720: 720
INRxToken.sol#L721-L721: 721
INRxToken.sol#L722-L722: 722
INRxToken.sol#L765-L765: 765
INRxToken.sol#L779-L779: 779
INRxToken.sol#L780-L780: 780
INRxToken.sol#L803-L803: 803
INRxToken.sol#L804-L804: 804
INRxToken.sol#L820-L820: 820
INRxToken.sol#L824-L824: 824
RESOLVED
Description

The SafeMath library is used unnecessarily. With Solidity compiler versions 0.8.0 or newer, arithmetic operations will automatically revert in case of integer overflow or underflow.

library SafeMath {

  • An implementation of SafeMath library is found.

        using SafeMath for uint256;
  • SafeMath library is used for uint256 type in INRxToken contract.

            totalSupply_ = totalSupply_.add(_amount);
  • SafeMath.add is called in mint function of INRxToken contract.
     

Note: Only a sample of 2 SafeMath library usage in this contract (out of 11) are shown above.

Recommendation:

We advise removing the usage of SafeMath library and using the built-in arithmetic operations provided by the Solidity programming language.

Alleviation:

[INRx]: The team resolved this issue by removing the usage of SafeMath library in commit 55e7b159832d5c870fd14c209253cd9976b27772.

INT-06 | Unused State Variable

CATEGORY SEVERITY LOCATIONS STATUS
Gas-optimization Optimization

INRxToken.sol#L688-L688: 688

RESOLVED
Description

One or more state variables are never used in the codebase.

Variable _PERMIT_TYPEHASH_DEPRECATED_SLOT in INRxToken is never used in INRxToken.

bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

contract INRxToken is  Ownable, Pausable, Blacklistable,Initializable, IERC20Permit, EIP712  {

Recommendation:

We advise removing the unused variables.

Alleviation:

[INRx]: The team resolved this issue by removing the unused variables in commit 55e7b159832d5c870fd14c209253cd9976b27772.