Open Dollar - 0xAadi's results

A floating $1.00 pegged stablecoin backed by Liquid Staking Tokens with NFT controlled vaults.

General Information

Platform: Code4rena

Start Date: 18/10/2023

Pot Size: $36,500 USDC

Total HM: 17

Participants: 77

Period: 7 days

Judge: MiloTruck

Total Solo HM: 5

Id: 297

League: ETH

Open Dollar

Findings Distribution

Researcher Performance

Rank: 59/77

Findings: 1

Award: $28.60

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: 0xAadi

Also found by: 0xDemon, 0xlemon, 0xprinc, Arz, Giorgio, Greed, MrPotatoMagic, T1MOH, btk, ge6a, m4k2, nmirchev8, perseus, xAriextz, yashar

Awards

28.5994 USDC - $28.60

Labels

bug
2 (Med Risk)
downgraded by judge
primary issue
satisfactory
selected for report
sufficient quality report
M-01

External Links

Lines of code

https://github.com/open-dollar/od-contracts/blob/f4f0246bb26277249c1d5afe6201d4d9096e52e6/src/contracts/proxies/ODSafeManager.sol#L105-L109

Vulnerability details

Impact

"According to the GEB framework, the proxy contracts (ODProxy) are designed to interact with the Safe Manager (ODSafeManager) through the Proxy Action contract (BasicActions). The pivotal function, allowSAFE(), is responsible for granting an address the capability to manage the Safe. Unfortunately, the BasicActions contract lacks the implementation of the allowSAFE() function. Consequently, the proxy contract is unable to execute allowSAFE(), leading to the inaccessibility of several critical functions for authorized users.

The functionality of essential operations such as modifySAFECollateralization(), transferCollateral(), transferInternalCoins(), quitSystem(), enterSystem(), moveSAFE(), removeSAFE(), and protectSAFE() is currently halted due to the inability to allow users to manage the Safe.

In addition to the absent allowSAFE() implementation, the following functions are also not yet implemented in the BasicActions contract and these functions are not directly executable by proxy contract: allowHandler(), modifySAFECollateralization(), transferCollateral(), transferInternalCoins(), quitSystem(), enterSystem(), moveSAFE(), removeSAFE(), and protectSAFE()."

Proof of Concept

Place the following test file in test/nft/anvil/ and run forge t --fork-url http://127.0.0.1:8545 --match-path test/nft/anvil/NFTTestAnvil.t.sol -vvv

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

import 'forge-std/console.sol';
import {AnvilFork} from '@test/nft/anvil/AnvilFork.t.sol';
import {Vault721} from '@contracts/proxies/Vault721.sol';
import {IODSafeManager} from '@interfaces/proxies/IODSafeManager.sol';
import {ODProxy} from '@contracts/proxies/ODProxy.sol';

contract NFTTestAnvil is AnvilFork {

  function test_setup() public {
    assertEq(totalVaults, vault721.totalSupply());
    checkProxyAddress();
    checkVaultIds();
  }

// Function to test open safe and allow safe with direct call
  function test_allowSafeDirectCall() public {
    address _proxy = proxies[0];
    bytes32 cType = cTypes[0];
    address user = users[0];

    vm.startPrank(user);  

    uint256 safeId = safeManager.openSAFE(cType,_proxy);
    IODSafeManager.SAFEData memory sData = safeManager.safeData(safeId);
    assertEq(_proxy,sData.owner);

    // allowSAFE call will fail
    vm.expectRevert(IODSafeManager.SafeNotAllowed.selector);
    safeManager.allowSAFE(safeId, user, 1);

    vm.stopPrank();
  }

  // Function to test open safe and allow safe with proxy delegation call
  function test_allowSafeWithProxyExecute() public {
    address _proxy = proxies[0];
    bytes32 cType = cTypes[0];
    address user = users[0];

    vm.startPrank(user);  

    uint256 safeId = openSafe2(cType,_proxy);
    IODSafeManager.SAFEData memory sData = safeManager.safeData(safeId);
    assertEq(_proxy,sData.owner);

    // allowSAFE call will fail
    vm.expectRevert();
    allowSafe(_proxy, safeId, user, 1);

    vm.stopPrank();
  }

  function openSafe2(bytes32 _cType, address _proxy) public returns (uint256 _safeId) {
    bytes memory payload = abi.encodeWithSelector(basicActions.openSAFE.selector, address(safeManager), _cType, _proxy);
    bytes memory safeData = ODProxy(_proxy).execute(address(basicActions), payload);
    _safeId = abi.decode(safeData, (uint256));
  }

  function allowSafe(address _proxy, uint256 _safe, address _usr, uint256 _ok) public  {
    bytes memory payload = abi.encodeWithSelector(safeManager.allowSAFE.selector,_safe, _usr, _ok);
    ODProxy(_proxy).execute(address(safeManager), payload);
  }  
}

Here you can see, both call to the allowSAFE() are failing, ie proxy contract cannot able to allow an address to manage the safe.

See the second test case, when we are calling the allowSAFE() with delegatecall the context of the target(ODSafeManager) has changed and the call get failed.

Tools Used

Manual Review and Foundry

Implement necessary functions in the BasicActions contract to execute necessary functions in the ODSafeManager contract.

Assessed type

call/delegatecall

#0 - c4-pre-sort

2023-10-26T19:38:33Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-10-26T19:38:46Z

raymondfam marked the issue as duplicate of #380

#2 - c4-judge

2023-11-02T18:17:42Z

MiloTruck marked the issue as not a duplicate

#3 - c4-judge

2023-11-02T18:18:20Z

MiloTruck marked the issue as duplicate of #294

#4 - c4-judge

2023-11-08T00:21:48Z

MiloTruck changed the severity to 2 (Med Risk)

#5 - c4-judge

2023-11-08T00:21:53Z

MiloTruck marked the issue as satisfactory

#6 - c4-judge

2023-11-08T00:22:02Z

MiloTruck marked the issue as selected for report

#7 - MiloTruck

2023-11-08T00:23:28Z

Since BasicActions.sol does not have a function to call allowSafe(), users will not be able to interact with ODSafeManager through their proxies.

However, since this can be addressed operationally by deploying another implementation contract, there isn't any permanent DOS of the protocol's functionality. Therefore, medium severity is appropriate.

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter