During initialization, the Swan
contract assigns both the owner
and operator
roles to the caller
. However, transferring ownership via the transferOwnership()
function only updates the contract owner
address, leaving the previous owner
’s operator privileges intact. The new owner
on the other hand therefore is denied this status when in reality he is the acting contract owner.
During the contract’s initialization in Swan
contract, the caller
is assigned both the owner
and operator
roles.
This allows them to execute functions gated by the onlyAuthorized()
modifier, which requires the caller to be either the BuyerAgent
owner or an operator
.
However, when Swan contract ownership is transferred using the inherited transferOwnership()
function from OwnableUpgradeable
, the operator
status will not be revoked from the original contract owner
and neither will it be granted to the new owner
.
This creates a situation where the previous Swan contract owner retains operator
access even after ownership is transferred, potentially leading to unauthorized access
if that previous owner
acts on the retained privileges.
Clarification:
There are two owners
I am reffering to here:
The Swan owner (Trusted) - This is the wallet that deploys Swan by default (The one given operator status)
BuyerAgent
Owner: A user that created a buyer agent with createBuyer()
function in Swan
Now according to Contest Details (Actors), Swan Owner is trusted
. However, once he transfers this ownership to a new entity, he is nolonger the owner and as such, should not act on previous privileges.
This oversight could allow a former owner
to interact with functions restricted
to BuyerAgent
owner or
designated operators
. Since the onlyAuthorized()
modifier allows access to both operators
and the BuyerAgent
owner, a previous contract owner retaining operator
privileges could invoke critical functions, potentially disrupting expected contract functionality or enabling unintended actions.
Manual Review
Override the transferOwnership()
function to correctly revoke operator
status from the previous owner
and assign it to the new owner
. This ensures that the privileges managed by the onlyAuthorized()
modifier are aligned with the current Swan contract ownership.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.