Skip to content

Commit

Permalink
Closes safe-global#246: Send along msg.sender to fallback handler (sa…
Browse files Browse the repository at this point in the history
  • Loading branch information
rmeissner authored Mar 2, 2021
1 parent 5d5f71d commit 752c167
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
6 changes: 5 additions & 1 deletion base/FallbackManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ contract FallbackManager is SelfAuthorized {
// solium-disable-next-line security/no-inline-assembly
assembly {
calldatacopy(0, 0, calldatasize())
let success := call(gas, handler, 0, 0, calldatasize(), 0, 0)
// The msg.sender address is shifted to the left by 12 bytes to remove the padding
// Then the address without padding is stored right after the calldata
mstore(calldatasize(), shl(96, caller()))
// Add 20 bytes for the address appended add the end
let success := call(gas, handler, 0, 0, add(calldatasize(), 20), 0, 0)
returndatacopy(0, 0, returndatasize())
if eq(success, 0) { revert(0, returndatasize()) }
return(0, returndatasize())
Expand Down
19 changes: 19 additions & 0 deletions handler/HandlerContext.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pragma solidity >=0.5.0 <0.6.0;

/// @title Handler Context - allows to extract calling context
/// @author Richard Meissner - <richard@gnosis.pm>
/// @notice based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/f8cc8b844a9f92f63dc55aa581f7d643a1bc5ac1/contracts/metatx/ERC2771Context.sol
contract HandlerContext {

// This function does not rely on a trusted forwarder. Use the returned value only to check information against the calling manager.
function _msgSender() internal pure returns (address sender) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) }
}

// Function do differentiate more clearly between msg.sender and the calling manager
function _manager() internal view returns (address) {
return msg.sender;
}

}
7 changes: 7 additions & 0 deletions test/TestHandler.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pragma solidity >=0.5.0 <0.6.0;
import "../handler/HandlerContext.sol";
contract TestHandler is HandlerContext {
function dudududu() external returns (address sender, address manager) {
return (_msgSender(), _manager());
}
}

0 comments on commit 752c167

Please sign in to comment.