Open Dollar - 0xprinc'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: 15/77

Findings: 3

Award: $414.58

🌟 Selected for report: 0

🚀 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

21.9995 USDC - $22.00

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
sufficient quality report
edited-by-warden
duplicate-429

External Links

Lines of code

https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODProxy.sol#L26-L35 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODSafeManager.sol#L49-L53

Vulnerability details

Impact

ODProxy which is also the _safeOwner will not be able to call any relevant function in ODSafeManager.sol.

Proof of Concept

The _safeOwner in ODSafeManager.sol refers to the proxy contract address related to the original user. This is confirmed in the function openSAFE() where vault721.mint(_usr, _safeId) is called. Here _usr is the address of the ODProxy. Now the issue is that ODProxy.sol, which is the proxy contract of the original holder of NFT/safe. It doesn't have a function that does normal low-level call and instead have an Execute() function which only does a delegatecall which forces this contract to never become msg.sender of any call it does.

Now consider the initial stages of the contract when a new NFT/safe has been minted and is mapped under an ODProxy/_safeOwner. The ODProxy/_safeOwner will not be able to call any function that has the _safeAllowed() modifier. Because _safeOwner is a contract and will only do a delegate call and hence can not call the function allowSAFE()

msg.sender == _safeData[_safe].owner 

will never be satisfied because the msg.sender will never be _safeOwner but the original owner of the Proxy and NFT/Safe.

This will lead to the _safeOwner stuck in the contract and not able to call any of these functions even if these are meant to be called by it

allowSAFE() -> this will not even let proxy to let any other use those functions modifySAFECollateralization() transferCollateral() transferCollateral() transferInternalCoins() quitSystem() enterSystem() moveSAFE() addSAFE() removeSAFE() protectSAFE()

which is almost all functions that are relevant to the SAFE.

Tools Used

Manual Review

Some mitigations can be

  1. Consider _safeOwner to be the real owner of the NFT which is also the ODProxy.OWNER. Change the mapping to contain this real owner as this will resolve this issue.
  2. Add another function in the ODProxy.sol which include a normal low-level call. This will introduce another issue that since the proxy will become msg.sender and then it will have another proxy of itself while minting or transfering NFT/safe, since the protocol will treat it as another address without a proxy attached to it. This can be mitigated introducing a mapping in Vault721.sol
mapping (address Proxy => bool) isProxy

This will be true for the addresses that are proxies and will be made true when the proxy is deployed for a contract and will check that if a contract is proxy then another proxy is not deployed for it.

Assessed type

DoS

#0 - c4-pre-sort

2023-10-26T17:29:52Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-10-26T17:30:03Z

raymondfam marked the issue as duplicate of #76

#2 - c4-pre-sort

2023-10-26T19:05:12Z

raymondfam marked the issue as duplicate of #380

#3 - c4-judge

2023-11-02T18:29:37Z

MiloTruck marked the issue as not a duplicate

#4 - c4-judge

2023-11-02T18:29:50Z

MiloTruck marked the issue as duplicate of #294

#5 - c4-judge

2023-11-08T00:21:46Z

MiloTruck changed the severity to 2 (Med Risk)

#6 - c4-judge

2023-11-08T00:24:54Z

MiloTruck marked the issue as unsatisfactory: Insufficient proof

#7 - MiloTruck

2023-11-08T00:25:53Z

This report assumes that ODProxy delegate call directly into the ODSafeManager contract, and doesn't highlight the key issue which is that BasicActions.sol has missing functions.

#8 - c4-judge

2023-11-11T08:18:37Z

MiloTruck removed the grade

#9 - c4-judge

2023-11-11T08:18:59Z

MiloTruck marked the issue as satisfactory

Findings Information

🌟 Selected for report: hals

Also found by: 0xprinc, nmirchev8, perseus, yashar

Labels

bug
2 (Med Risk)
downgraded by judge
low quality report
satisfactory
edited-by-warden
duplicate-381

Awards

224.3342 USDC - $224.33

External Links

Lines of code

https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/Vault721.sol#L94-L99

Vulnerability details

Impact

Minting of the New Safes/NFTs from Vault721.sol will revert, leading to a temporary DOS.

Proof of Concept

The function Vault721.sol is used to mint the new safes. This function is only called by the safeManager. The current implementation of the ODSafeManager.sol is such that variable _safeId keeps check of the number of Safes that have been deployed. And this variable starts from 0 whenever a new ODSafeManager is deployed. So when the governor of Vault721.sol update the address of SafeManager, and a new ODSafeManager.sol contract is assigned to it, _safeId will initialize from 0 (as the ODSafeManager.sol have a fixed address of Vault721). So, when a new safe is minted its tokenId/safeId will be 0, which will revert the _safeMint function that is present in Vault721.sol/mint(), because the tokenId is already minted earlier.

This can be escalated when a malicious user front-runs the Vault721.sol/initiaizeManager() function at the early stages of the contract and non-zero safes/NFTs, making a DOS situation when the governor changes the manager contract manually to ODManager.sol, because the mint will now always revert with this implementation of ODSafeManager.sol.

Tools Used

Manual Review

There should present a function to directly change the value of ODSafeManager.sol/_safeId state variable or the function to sync the tokens minted and _safeId. Access given to Vault721.sol.

Function present in ODSafeManager.sol

    function sync(uint _newSafeId) external {
        require(msg.sender == address(vault721), 'SafeMngr: Only Vault721');
        _safeId = _newSafeId;
    }

Function present in Vault721.sol,

       
    uint internal totalMinted;

    function syncSend() external onlyGovernor{
        IODSafeManager(safeManager).sync(totalMinted);
    }

and should also include the code inside the mint function to update the totalMinted.

Assessed type

DoS

#0 - c4-pre-sort

2023-10-26T05:48:36Z

raymondfam marked the issue as low quality report

#1 - c4-pre-sort

2023-10-26T05:49:04Z

raymondfam marked the issue as duplicate of #37

#2 - c4-judge

2023-11-01T20:28:21Z

MiloTruck marked the issue as not a duplicate

#3 - c4-judge

2023-11-01T20:31:55Z

MiloTruck marked the issue as primary issue

#4 - c4-judge

2023-11-08T00:07:37Z

MiloTruck changed the severity to 2 (Med Risk)

#5 - c4-judge

2023-11-08T00:08:05Z

MiloTruck marked issue #381 as primary and marked this issue as a duplicate of 381

#6 - c4-judge

2023-11-08T00:12:16Z

MiloTruck marked the issue as satisfactory

Findings Information

🌟 Selected for report: tnquanghuy0512

Also found by: 0xprinc, Baki, COSMIC-BEE-REACH, MrPotatoMagic, Tendency

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
sufficient quality report
edited-by-warden
duplicate-297

Awards

168.2507 USDC - $168.25

External Links

Lines of code

https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/SAFEHandler.sol#L11 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODSafeManager.sol#L59-L62 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODSafeManager.sol#L112-L115 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODSafeManager.sol#L118 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODSafeManager.sol#L189 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/proxies/ODSafeManager.sol#L205

Vulnerability details

Impact

All the functions with handlerAllowed modifier are unusable and can never be called.

Proof of Concept

Handler is deployed and assigned to the Safe/NFT when ODSafeManager.sol/openSAFE() function is called. The SafeHandler.sol have only a constructor and not any function so it can not do any external call and hence can not become a msg.sender for any transaction.

Now, the function ODSafeManager.sol/allowHandler() can not be called by the SafeHandler.sol because it don't have a function to do external call. This means it can not approve any other address also.

mapping(address _safeHandler => mapping(address _caller => uint256 _ok)) public handlerCan;

function allowHandler(address _usr, uint256 _ok) external {
    handlerCan[msg.sender][_usr] = _ok;

So, the modifier handlerAllowed() will always fail as there is no one allowed by safeHandler and safeHandler can not do an external call by itself.

  modifier handlerAllowed(address _handler) {
    if (msg.sender != _handler && handlerCan[_handler][msg.sender] == 0) revert HandlerNotAllowed();
    _;
  }

And hence every function containing this modifier will not execute making them non-functional.

Functions include: quitSystem() enterSystem()

Tools Used

Manual Review

  1. The safeHandler should contain an OWNER variable which is changed after the NFT/safe is transferred to some other user. There should also be present a function(only be called by the OWNER) to do an external call to other contracts so that the following issue can be mitigated.

Assessed type

DoS

#0 - c4-pre-sort

2023-10-26T19:26:41Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-10-26T19:26:56Z

raymondfam marked the issue as duplicate of #380

#2 - c4-judge

2023-11-02T18:24:09Z

MiloTruck marked the issue as not a duplicate

#3 - c4-judge

2023-11-02T18:24:16Z

MiloTruck marked the issue as duplicate of #297

#4 - c4-judge

2023-11-02T18:53:30Z

MiloTruck changed the severity to 2 (Med Risk)

#5 - c4-judge

2023-11-02T18:53:36Z

MiloTruck marked the issue as satisfactory

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