Secure Smart Contract library for Solidity with upgradeable implementations of standards like ERC20 and ERC721, flexible role-based permissioning schemes, and reusable components for building custom contracts and complex decentralized systems.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
ERC-2771 meta-transaction support enabling gasless transactions through trusted forwarders and context-aware message handling.
Context-aware contract that can handle meta-transactions from trusted forwarders.
/**
* @dev Context variant with ERC-2771 support
*/
abstract contract ERC2771ContextUpgradeable {
function __ERC2771Context_init(address trustedForwarder) internal onlyInitializing;
/**
* @dev Returns whether forwarder is a trusted forwarder
*/
function isTrustedForwarder(address forwarder) external view returns (bool);
/**
* @dev Returns the original sender of the transaction
*/
function _msgSender() internal view override returns (address);
/**
* @dev Returns the original call data
*/
function _msgData() internal view override returns (bytes calldata);
/**
* @dev Returns the length of the context suffix
*/
function _contextSuffixLength() internal view override returns (uint256);
}Forwarder contract that executes meta-transactions on behalf of users.
/**
* @dev Simple forwarder to be used together with an ERC-2771 compatible contract
*/
contract ERC2771ForwarderUpgradeable {
function __ERC2771Forwarder_init(string memory name) internal onlyInitializing;
/**
* @dev Structure of a forwarding request
*/
struct ForwardRequestData {
address from;
address to;
uint256 value;
uint256 gas;
uint48 deadline;
bytes data;
bytes signature;
}
/**
* @dev Returns the current nonce for a signer
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Verify the validity of a forward request
*/
function verify(ForwardRequestData calldata request) external view returns (bool);
/**
* @dev Execute a forward request
*/
function execute(ForwardRequestData calldata request) external payable returns (bool success, bytes memory returndata);
/**
* @dev Batch execute multiple forward requests
*/
function executeBatch(
ForwardRequestData[] calldata requests,
address payable refundReceiver
) external payable returns (bool[] memory successes, bytes[] memory returndatas);
}import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {ERC2771ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol";
contract MetaToken is ERC20Upgradeable, ERC2771ContextUpgradeable {
function initialize(
string memory name,
string memory symbol,
address trustedForwarder
) initializer public {
__ERC20_init(name, symbol);
__ERC2771Context_init(trustedForwarder);
}
// Override _msgSender and _msgData to use ERC2771 context
function _msgSender() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address) {
return ERC2771ContextUpgradeable._msgSender();
}
function _msgData() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) {
return ERC2771ContextUpgradeable._msgData();
}
function _contextSuffixLength() internal view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (uint256) {
return ERC2771ContextUpgradeable._contextSuffixLength();
}
}import {ERC2771ForwarderUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ForwarderUpgradeable.sol";
contract MyForwarder is ERC2771ForwarderUpgradeable {
function initialize() initializer public {
__ERC2771Forwarder_init("MyForwarder");
}
}Install with Tessl CLI
npx tessl i tessl/npm-openzeppelin--contracts-upgradeable