-
Notifications
You must be signed in to change notification settings - Fork 357
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: make StarknetTokenBridge ERC2771 compliant
- Loading branch information
Showing
4 changed files
with
120 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// SPDX-License-Identifier: MIT | ||
// solhint-disable no-inline-assembly | ||
pragma solidity >=0.6.9; | ||
|
||
import "./IERC2771Recipient.sol"; | ||
|
||
/** | ||
* @title The ERC-2771 Recipient Base Abstract Class - Implementation | ||
* | ||
* @notice Note that this contract was called `BaseRelayRecipient` in the previous revision of the GSN. | ||
* | ||
* @notice A base contract to be inherited by any contract that want to receive relayed transactions. | ||
* | ||
* @notice A subclass must use `_msgSender()` instead of `msg.sender`. | ||
*/ | ||
abstract contract ERC2771Recipient is IERC2771Recipient { | ||
|
||
/* | ||
* Forwarder singleton we accept calls from | ||
*/ | ||
address private _trustedForwarder; | ||
|
||
/** | ||
* :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder. | ||
* @notice Method is not a required method to allow Recipients to trust multiple Forwarders. Not recommended yet. | ||
* @return forwarder The address of the Forwarder contract that is being used. | ||
*/ | ||
function getTrustedForwarder() public virtual view returns (address forwarder){ | ||
return _trustedForwarder; | ||
} | ||
|
||
function _setTrustedForwarder(address _forwarder) internal { | ||
_trustedForwarder = _forwarder; | ||
} | ||
|
||
/// @inheritdoc IERC2771Recipient | ||
function isTrustedForwarder(address forwarder) public virtual override view returns(bool) { | ||
return forwarder == _trustedForwarder; | ||
} | ||
|
||
/// @inheritdoc IERC2771Recipient | ||
function _msgSender() internal override virtual view returns (address ret) { | ||
if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { | ||
// At this point we know that the sender is a trusted forwarder, | ||
// so we trust that the last bytes of msg.data are the verified sender address. | ||
// extract sender address from the end of msg.data | ||
assembly { | ||
ret := shr(96,calldataload(sub(calldatasize(),20))) | ||
} | ||
} else { | ||
ret = msg.sender; | ||
} | ||
} | ||
|
||
/// @inheritdoc IERC2771Recipient | ||
function _msgData() internal override virtual view returns (bytes calldata ret) { | ||
if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) { | ||
return msg.data[0:msg.data.length-20]; | ||
} else { | ||
return msg.data; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.6.0; | ||
|
||
/** | ||
* @title The ERC-2771 Recipient Base Abstract Class - Declarations | ||
* | ||
* @notice A contract must implement this interface in order to support relayed transaction. | ||
* | ||
* @notice It is recommended that your contract inherits from the ERC2771Recipient contract. | ||
*/ | ||
abstract contract IERC2771Recipient { | ||
|
||
/** | ||
* :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder. | ||
* @param forwarder The address of the Forwarder contract that is being used. | ||
* @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient. | ||
*/ | ||
function isTrustedForwarder(address forwarder) public virtual view returns(bool); | ||
|
||
/** | ||
* @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions. | ||
* @return sender The real sender of this call. | ||
* For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`. | ||
* Otherwise simply returns `msg.sender`. | ||
*/ | ||
function _msgSender() internal virtual view returns (address); | ||
|
||
/** | ||
* @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.) | ||
* @return data The real `msg.data` of this call. | ||
* For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes | ||
* of the `msg.data` - so this method will strip those 20 bytes off. | ||
* Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`. | ||
*/ | ||
function _msgData() internal virtual view returns (bytes calldata); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters