Open Dollar - merlin'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: 56/77

Findings: 1

Award: $37.14

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Labels

bug
2 (Med Risk)
satisfactory
sufficient quality report
edited-by-warden
duplicate-171

Awards

37.1417 USDC - $37.14

External Links

Lines of code

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

Vulnerability details

Bug Description

In the ODSafeManager smart contract, there exists an allowSAFE function that permits or restricts a user's ability to manage the safe. If the owner of the SAFE attempts to revoke access from a user with permission, there is a potential vulnerability where the allowed user could front-run the transaction to add another user. Subsequently, after the removal operation is executed, the initially removed user can leverage the newly added user to regain their authority.

Proof-of-Concept

The following test case illustrates the scenario:

Alice grants permission for Bob to manage the SAFE using the function: allowSAFE(1, Bob, 1). Subsequently, Bob's intentions turn malicious, and Alice decides to revoke his access. As Alice initiates a transaction to disallow Bob, he detects this and front-runs her tx by authorizing a new user with permission with the function: allowSAFE(1, Erin, 1). When Alice's transaction is executed, it successfully disallows Bob using the function: allowSAFE(1, Bob, 0). Now, Erin authorizes Bob to manage the SAFE once again with the function: allowSAFE(1, Bob, 1).

function allowSAFE(
        uint256 _safe,
        address _usr,
        uint256 _ok
    ) external safeAllowed(_safe) {
        address _owner = _safeData[_safe].owner;
        safeCan[_owner][_safe][_usr] = _ok;
        emit AllowSAFE(msg.sender, _safe, _usr, _ok);
    }

Impact

This would allow the malicious user with permission to keep executing txs on behalf of the owner of the SAFE.

Tools Used

Manual review

Prevent users who have permission from invoking the allowSAFE() function on behalf of the SAFE owner:

function allowSAFE(
        uint256 _safe,
        address _usr,
        uint256 _ok
-    ) external safeAllowed(_safe) {
+    ) external {
				 address _owner = _safeData[_safe].owner;
+       if (msg.sender != _owner)
+           revert HandlerNotAllowed();
        safeCan[_owner][_safe][_usr] = _ok;
        emit AllowSAFE(msg.sender, _safe, _usr, _ok);
    }

Assessed type

Access Control

#0 - c4-pre-sort

2023-10-26T06:16:22Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2023-10-26T06:16:44Z

raymondfam marked the issue as duplicate of #171

#2 - c4-judge

2023-11-02T08:44:20Z

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