The function is responsible for forwarding specific (enabled/installed) function selectors to their specific handler.
We'll focus on the assembly code, as that's the important part. Both call types have almost the same code, so we'll just use one of them for this issue.
Let's imagine we want to call this function:
The selector is 0x4a68832d. As msg.sender we'll use ab8483f64d9c6d1ecf9b849ae677dd3315835cb2
Let's go line by line and examine the assembly code:
calldatacopy(0, 0, calldatasize())-> Copies calldatasize() 4 bytes in our case bytes to memory at pointer 0
shl(96, caller() -> caller() is msg.sender in assembly and is always padded with 12 bytes in front: 000000000000000000000000ab8483f64d9c6d1ecf9b849ae677dd3315835cb2
This will shift the data 12 bytes to the left, which will look like this: 0xab8483f64d9c6d1ecf9b849ae677dd3315835cb2000000000000000000000000
mstore(calldatasize(), shl(96, caller())) -> This will store the shifted caller right after the copied calldata.
staticcall(gas(), handler, 0, add(calldatasize(), 20), 0, 0)-> This will make a call to handler with the data that starts from:
So our data will look like this: 0x4a68832dab8483f64d9c6d1ecf9b849ae677dd3315835cb2
This will not work as it's not valid calldata. Valid calldata will be: 0x4a68832d000000000000000000000000ab8483f64d9c6d1ecf9b849ae677dd3315835cb2
You'll notice that it's 4 + 32 = 36 bytes long and the address isn't shifted.
This is how the calldata is supposed to look like, currently both CALLTYPE_STATIC and CALLTYPE_SINGLE won't work because of this, making fallback completely useless.
Functionality DoS
Manual Review
Apply the following changes:
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.