remove unstructured storage from GSNContext (#1881)

pull/1886/head
Francisco Giordano 6 years ago committed by Nicolás Venturo
parent 2b3aa0d220
commit b2b31b2551
  1. 26
      contracts/GSN/GSNContext.sol
  2. 4
      contracts/GSN/GSNRecipient.sol
  3. 4
      contracts/mocks/GSNContextMock.sol

@ -11,36 +11,22 @@ import "./Context.sol";
* recipient contract: end users should use `GSNRecipient` instead. * recipient contract: end users should use `GSNRecipient` instead.
*/ */
contract GSNContext is Context { contract GSNContext is Context {
// We use a random storage slot to allow proxy contracts to enable GSN support in an upgrade without changing their address internal _relayHub = 0xD216153c06E857cD7f72665E0aF1d7D82172F494;
// storage layout. This value is calculated as: keccak256('gsn.relayhub.address'), minus 1.
bytes32 private constant RELAY_HUB_ADDRESS_STORAGE_SLOT = 0x06b7792c761dcc05af1761f0315ce8b01ac39c16cc934eb0b2f7a8e71414f262;
event RelayHubChanged(address indexed oldRelayHub, address indexed newRelayHub); event RelayHubChanged(address indexed oldRelayHub, address indexed newRelayHub);
constructor() internal { constructor() internal {
_upgradeRelayHub(0xD216153c06E857cD7f72665E0aF1d7D82172F494); // solhint-disable-previous-line no-empty-blocks
}
function _getRelayHub() internal view returns (address relayHub) {
bytes32 slot = RELAY_HUB_ADDRESS_STORAGE_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
relayHub := sload(slot)
}
} }
function _upgradeRelayHub(address newRelayHub) internal { function _upgradeRelayHub(address newRelayHub) internal {
address currentRelayHub = _getRelayHub(); address currentRelayHub = _relayHub;
require(newRelayHub != address(0), "GSNContext: new RelayHub is the zero address"); require(newRelayHub != address(0), "GSNContext: new RelayHub is the zero address");
require(newRelayHub != currentRelayHub, "GSNContext: new RelayHub is the current one"); require(newRelayHub != currentRelayHub, "GSNContext: new RelayHub is the current one");
emit RelayHubChanged(currentRelayHub, newRelayHub); emit RelayHubChanged(currentRelayHub, newRelayHub);
bytes32 slot = RELAY_HUB_ADDRESS_STORAGE_SLOT; _relayHub = newRelayHub;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newRelayHub)
}
} }
// Overrides for Context's functions: when called from RelayHub, sender and // Overrides for Context's functions: when called from RelayHub, sender and
@ -49,7 +35,7 @@ contract GSNContext is Context {
// when handling said data. // when handling said data.
function _msgSender() internal view returns (address) { function _msgSender() internal view returns (address) {
if (msg.sender != _getRelayHub()) { if (msg.sender != _relayHub) {
return msg.sender; return msg.sender;
} else { } else {
return _getRelayedCallSender(); return _getRelayedCallSender();
@ -57,7 +43,7 @@ contract GSNContext is Context {
} }
function _msgData() internal view returns (bytes memory) { function _msgData() internal view returns (bytes memory) {
if (msg.sender != _getRelayHub()) { if (msg.sender != _relayHub) {
return msg.data; return msg.data;
} else { } else {
return _getRelayedCallData(); return _getRelayedCallData();

@ -12,7 +12,7 @@ import "./IRelayHub.sol";
*/ */
contract GSNRecipient is IRelayRecipient, GSNContext, GSNBouncerBase { contract GSNRecipient is IRelayRecipient, GSNContext, GSNBouncerBase {
function getHubAddr() public view returns (address) { function getHubAddr() public view returns (address) {
return _getRelayHub(); return _relayHub;
} }
// This function is view for future-proofing, it may require reading from // This function is view for future-proofing, it may require reading from
@ -23,6 +23,6 @@ contract GSNRecipient is IRelayRecipient, GSNContext, GSNBouncerBase {
} }
function _withdrawDeposits(uint256 amount, address payable payee) internal { function _withdrawDeposits(uint256 amount, address payable payee) internal {
IRelayHub(_getRelayHub()).withdraw(amount, payee); IRelayHub(_relayHub).withdraw(amount, payee);
} }
} }

@ -7,7 +7,7 @@ import "../GSN/IRelayRecipient.sol";
// By inheriting from GSNContext, Context's internal functions are overridden automatically // By inheriting from GSNContext, Context's internal functions are overridden automatically
contract GSNContextMock is ContextMock, GSNContext, IRelayRecipient { contract GSNContextMock is ContextMock, GSNContext, IRelayRecipient {
function getHubAddr() public view returns (address) { function getHubAddr() public view returns (address) {
return _getRelayHub(); return _relayHub;
} }
function acceptRelayedCall( function acceptRelayedCall(
@ -37,7 +37,7 @@ contract GSNContextMock is ContextMock, GSNContext, IRelayRecipient {
} }
function getRelayHub() public view returns (address) { function getRelayHub() public view returns (address) {
return _getRelayHub(); return _relayHub;
} }
function upgradeRelayHub(address newRelayHub) public { function upgradeRelayHub(address newRelayHub) public {

Loading…
Cancel
Save