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.