Dandy Caramel Tortoise
Medium
The last 20 bytes could be used to identify both the market forwarder and also the market user in case the market forwarder uses the base forwarder themselves
_msgSenderForMarket
decodes the last 20 bytes as message sender in case the current sender is a trusted forwarder for the market
function _msgSenderForMarket(uint256 _marketId)
internal
view
virtual
returns (address)
{
if (
msg.data.length >= 20 &&
isTrustedMarketForwarder(_marketId, _msgSender())
) {
address sender;
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
// Ensure the appended sender address approved the forwarder
require(
_approvedForwarderSenders[_msgSender()].contains(sender),
"Sender must approve market forwarder"
);
return sender;
}
return _msgSender();
}
But in case the trusted forwarder themselves is using the base trusted forwarder ie. _trustedForwarder
, the last 20 bytes will be the address of the market's trusted forwarder
https://github.com/sherlock-audit/2024-11-teller-finance-update/blob/0c8535728f97d37a4052d2a25909d28db886a422/teller-protocol-v2-audit-2024/packages/contracts/contracts/ERC2771ContextUpgradeable.sol#L34-L50
function _msgSender()
internal
view
virtual
override
returns (address sender)
{
if (isTrustedForwarder(msg.sender)) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20)))
}
} else {
return super._msgSender();
}
}
Hence in such a scenario the decoding will be incorrect
A market's trusted forwarder should use the base trusted forwarder themselves
No response
No response
Incorrect decoding of the message sender causing fund transfer etc. to happen from the incorrect account
No response
Avoid using base trusted forwarder by market trusted providers