📄

Report #22405

Report Date
July 20, 2023
Status
Closed
Payout

Direct theft of users funds due to incorrect Owner address assigned in Smart Contract

‣
Report Info

Report ID

#22405

Report type

Smart Contract

Has PoC?

Yes

Target

Impacts

  • Permanent freezing of funds

Summary

I Would like to share an issue in smart contract ( Fertilizer Implementation ) in which some function functionality will be disrupted due to incorrect owner address defined in Read Contract part due to which the Modifier will not work correctly

Here Owner address = 0x0000000000000000000000000000000000000000

Practically , This address is not owned by any user, is often associated with token burn & mint/genesis events and used as a generic null address

At File 1 , you see a functions who use onlyOwner() modifier for security reason means only real owner is allowed to access this functionality

function beanstalkUpdate(

    address account,
    uint256[] memory ids,
    uint128 bpf
) external onlyOwner returns (uint256) {
    return __update(account, ids, uint256(bpf));
}

    function beanstalkMint(address account, uint256 id, uint128 amount, uint128 bpf) external onlyOwner {
    if (_balances[id][account].amount > 0) {
        uint256[] memory ids = new uint256[](1);
        ids[0] = id;
        _update(account, ids, bpf);
    }
    _balances[id][account].lastBpf = bpf;
    _safeMint(
        account,
        id,
        amount,
        bytes('0')
    );
}

All these Function Depends on Modifier onlyOwner()

  modifier onlyOwner() {
    require(owner() == _msgSender(), "Ownable: caller is not the owner");
    _;
}

Exact Issue

Step 2 : Now Go to Read Contract Part, you will see Owner it assigned to Null address ( 0x0000000000000000000000000000000000000000 )

PIC = P_1

Practically , This address is not owned by any user, is often associated with token burn & mint/genesis events and used as a generic null address

The null address in crypto is specifically generated to allow Proof of Burn. Coin burning happens when a token is intentionally sent to an unusable wallet to remove it from circulation. The address is called a burn address or eater address. It can’t be accessed or assigned to anyone.

Step 3 : In Smart Contract there is an import of OwnerUpgradable.sol ( Means here we make a change from Old Owner to New Owner )

But Here also there is some Glitch , Inorder to make successful Ownership transfer user must be the old owner and here old owner = 0x0000000000000000000000000000000000000000

    function transferOwnership(address newOwner) public virtual onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
}

Here onlyOwner() modifier is still used means without the permission of old Owner we are not allowed to make change to New Owner address

Impact

  1. Permanent Freezing of assets because No one is the Owner of Null address and our Modifier function will not work due to missing correct owner address
  2. Direct Theft of user funds since some functionality will not work correctly without the OnlyOwner() modifier
  3.  function beanstalkUpdate(
     address account,
     uint256[] memory ids,
     uint128 bpf
     ) external onlyOwner returns (uint256) {
     return __update(account, ids, uint256(bpf));

     function beanstalkMint(address account, uint256 id, uint128 amount, uint128 bpf) external onlyOwner {
     if (_balances[id][account].amount > 0) {
         uint256[] memory ids = new uint256[](1);
         ids[0] = id;
         _update(account, ids, bpf);
     }
     _balances[id][account].lastBpf = bpf;
     _safeMint(
         account,
         id,
         amount,
         bytes('0')
     );

Recommendation

I will Suggest Developer to Correct address other then Null address

Thank You

Proof of concept

Step 2 : Now Go to Read Contract Part, you will see Owner it assigned to Null address ( 0x0000000000000000000000000000000000000000 )

PIC = P_1

Practically , This address is not owned by any user, is often associated with token burn & mint/genesis events and used as a generic null address

The null address in crypto is specifically generated to allow Proof of Burn. Coin burning happens when a token is intentionally sent to an unusable wallet to remove it from circulation. The address is called a burn address or eater address. It can’t be accessed or assigned to anyone.

Step 3 : In Smart Contract there is an import of OwnerUpgradable.sol ( Means here we make a change from Old Owner to New Owner )

But Here also there is some Glitch , Inorder to make successful Ownership transfer user must be the old owner and here old owner = 0x0000000000000000000000000000000000000000

    function transferOwnership(address newOwner) public virtual onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
}

Here onlyOwner() modifier is still used means without the permission of old Owner we are not allowed to make change to New Owner address

BIC Response

This is not a valid bug report because the state of the implementation address is meaningless. The report also does not describe how any funds can be frozen as a result of the reported issue.

Due to these reasons, we are closing the submission and no reward will be issued.