The executeMetaTransaction()
function exists to allow relayers or those with privileged roles to execute functions in OWPIdentity.sol
or MembershpiFactory.sol
on behalf of users.
For example, a relayer might call that function with a signature for OWPIdentity.mint(Alice, 1, 1)
to mint Alice 1 token of ID 1. This is a call that expects to succeed, but reverts because the access control modifier in the mint function checks if the user Alice has the minter role, which she should of course not have.
Relayer calls NativeMetaTransaction.executeMetaTransaction(Alice, ...)
This calls OWPIdentity.mint()
where the msg.sender
is the contract itself.
The onlyRole() modifier is executed, this calls _checkRole() which looks at _msgSender(), which is overridden in OWPIdentity.sol
.
Because msg.sender == address(this)
, we extract the userAddress
, which is Alice, from the assembly, and return it.
Therefore, the onlyRole(MINTER_ROLE)
is checking if Alice has the MINTER_ROLE
, which makes no sense.
It reverts because Alice, as an end user, of course does not have the minter role. The minter role should be assigned to the relayer.
This disallows executeMetaTransaction()
function from working as intended.
Passing the relayer as the userAddress
also doesn't work because the verification for the signature would then fail.
executeMetaTransaction()
calls revert for relayers trying to operate normal functions.
Manual review
Rework the structure so that the onlyRole(MINTER_ROLE)
is properly checking against the relayer who calls executeMetaTransaction()
instead of the userAddress
.
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.