Platform: Code4rena
Start Date: 24/02/2022
Pot Size: $30,000 USDC
Total HM: 0
Participants: 28
Period: 3 days
Judge: Jack the Pug
Id: 95
League: ETH
Rank: 24/28
Findings: 1
Award: $603.43
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: hickuphh3
Also found by: 0x1f8b, 0xwags, Dravee, IllIllI, Omik, Rhynorater, Ruhum, TerrierLover, cccz, cmichel, csanuragjain, defsec, gzeon, jayjonah8, kenta, kirk-baird, kyliek, leastwood, minhquanym, pedroais, peritoflores, robee, securerodd
603.4318 USDC - $603.43
https://github.com/code-423n4/2022-02-jpyc/blob/main/contracts/v1/Ownable.sol#L51-L54
The transferOwnership(address newOwner)
function does not use a safe ownership transfer pattern. The impact of this is that if an invalid newOwner
(that is not zero) is passed to the function then all onlyOwner
functionality will be lost.
Losing onlyOwner
functionality will prevent changing the masterMinter
and the whitelister
as well losing the ability to update the proxy's implementations.
This applies to both FiatTokenV1.sol
and FiatTokenV2.sol
.
function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); }
Consider adding a two stage ownership transfer model where the current owner first selects a pending owner. Second, the pending owner accepts the ownership which will then transfer the ownership to the pending owner.
public address pendingOwner; function transferOwnershipToPending(address _pendingOwner) public virtual onlyOwner { pendingOwner = _pendingOwner; // Allow _pendingOwner == address(0) } function acceptOwnership() public { require(pendingOwner != address(0), "Ownable: new owner is the zero address"); pendingOwner = newOwner; }
Note we allow _pendingOwner == address(0)
as we may want to cancel a pendingOwner
transfer and retain the current owner. To do this we do transferOwnershipToPending(address(0)
.
#0 - retocrooman
2022-02-28T09:53:11Z
USDC had to make the contract owner when upgrading, so I want to keep the owner area simple. Also, it's okay if the operation is correct.
#1 - jack-the-pug
2022-03-05T08:30:56Z
Best practice, not an issue.
I can not accept this as a low
or med
because there is no "proof of work" in this issue, a script can be made to submit an issue with exact same description to all the projects that use Ownable
, it will be unfair for other wardens who actually read and understands the code in the context.
This should be in a QA report, and it can be a valuable finding within the QA report.
#2 - CloudEllie
2022-03-24T14:11:55Z
Since this issue was downgraded to a QA level, and the warden did not submit a separate QA report, we've renamed this one to "QA report" for consistency.
The original title, for the record, was "Safe Transfer Ownership Pattern is Not Used."