Native account abstraction should allow contract accounts to be the tx.origin
#915
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
low quality report
This report is of especially low quality
sponsor disputed
Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
Lines of code
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/bootloader/bootloader.yul#L1322-L1328
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/contracts/ContractDeployer.sol#L40-L52
https://github.com/code-423n4/2023-10-zksync/blob/main/code/system-contracts/scripts/process.ts#L90
Vulnerability details
Impact
ZkSync has native support for account abstraction. However, it only ever sets EOAs as the
tx.origin
for its transactions. Since contract accounts can initiate transactions, it only makes sense thattx.origin
would return the address of the contract account and not the bootloader's. Returning the bootloader as thetx.origin
for transactions initiated by contract accounts breaks expectations. Valid uses fortx.origin
would no longer be possible.For example, a contract account has a sensitive callback function that can be triggered by other contracts. If we want this callback to only be triggered by transactions initiated by the contract account, this can be done with the following code:
If
tx.origin
for contract accounts will always be the bootloader, the above logic can not be implemented for contract accounts in ZkSync.Proof of Concept
Initiating any L2 transaction using a contract account will set the
tx.origin
for that transaction as the bootloader.Tools Used
Manual Review
Recommended Mitigation Steps
Instead of setting the
tx.origin
as the from address only for EOAs, set thetx.origin
as the from address for any account, including contract accounts. Change the following code in bootloader to:Add the following
isAccount()
function to bootloader:RIGHT_PADDED_GET_ACCOUNT_VERSION_SELECTOR
is the selector forContractDeployer.extendedAccountVersion()
. That function will return a value higher than 0 if the address is an EOA or a contract account (a contract that supports account abstraction).Assessed type
Other
The text was updated successfully, but these errors were encountered: