Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d30c62f
fix(hardhat-config): add solidity 0.8.15 compiler
Sep 9, 2022
0e9eb0d
fix(utils): meta-tx sign util
Sep 9, 2022
60e0b18
feat(meta-vault): add meta vault contract
Sep 9, 2022
ee3bd43
feat(meta-vault-test): add meta vault test
Sep 9, 2022
a79f25c
Merge branch 'feat/harvest' into feat/meta-transaction
Sep 26, 2022
c8ef4fb
fix(meta-vault): remove codes proof add expected output
Sep 26, 2022
2482749
fix(test): refactor tests
Sep 26, 2022
5e88fd7
feat(packages): add @opengsn/contracs
Sep 26, 2022
dbe870a
style(meta-vault): fix import style
Sep 28, 2022
3f2f78e
feat(packages): add solidstate contracts
Sep 28, 2022
8cf5660
feat(packages): add solidstate contracts
Sep 28, 2022
7d78071
feat(opengsn): base paymaster and open gsn libraries and interfaces
Sep 28, 2022
0dd0501
feat(interfaces): vault interface
Sep 28, 2022
48ef024
fix(interface): fix ivault
Sep 28, 2022
df83402
feat(paymaster): token paymaster contract
Sep 28, 2022
46b13a1
feat(yarn lock): add opengsn
Sep 28, 2022
15f4258
Merge branch 'feat/harvest' into feat/meta-transaction
Oct 5, 2022
42ce936
feat(gsn): gsn contracts
Oct 12, 2022
342d71e
feat(gsn): gsn contracts
Oct 12, 2022
618eced
fix(vault-gateway): change name
Oct 12, 2022
9943fec
fix(gsn): import
Oct 12, 2022
d1a247c
feat(forwarder): add contract
Oct 12, 2022
5c41efe
refactor(paymaster): remove opty swapper
Oct 12, 2022
d28ae53
fix(utils): gsn utils
Oct 12, 2022
e39c669
feat(interface): ierc20 permit interface
Oct 12, 2022
c8b798b
feat(packages): add gsn
Oct 12, 2022
435a19c
feat(meta-tx-test): wip
Oct 12, 2022
e5c0f99
Merge branch 'master' into feat/meta-transaction
Oct 12, 2022
78d98c5
fix(vault-gateway-test): wip -test forwarder
Oct 12, 2022
f3cb046
fix(paymaster): fix gas and approvals
Oct 13, 2022
b53a127
fix(utils): remove console log
Oct 13, 2022
b509a15
fix(tests): wip tests
Oct 13, 2022
90e347e
fix(test): test
Oct 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions contracts/interfaces/opty/IERC20PermitLegacy-0.8.x.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
* @title Legacy ERC20Permit interface
* @author OptyFi
*/
interface IERC20PermitLegacy {
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
55 changes: 55 additions & 0 deletions contracts/mocks/contracts/TestHub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

import "../../protocol/meta-tx/GSN/libraries/GsnTypes.sol";
import "../../protocol/meta-tx/GSN/interfaces/IPaymaster.sol";

import "../../protocol/meta-tx/GSN/RelayHub.sol";

import "../utils/AllEvents.sol";

/**
* This mock relay hub contract is only used to test the paymaster's 'pre-' and 'postRelayedCall' in isolation.
*/
contract TestHub is RelayHub, AllEvents {
constructor(
IStakeManager _stakeManager,
address _penalizer,
address _batchGateway,
address _relayRegistrar,
RelayHubConfig memory _config
)
RelayHub(_stakeManager, _penalizer, _batchGateway, _relayRegistrar, _config)
// solhint-disable-next-line no-empty-blocks
{

}

function callPreRC(
GsnTypes.RelayRequest calldata relayRequest,
bytes calldata signature,
bytes calldata approvalData,
uint256 maxPossibleGas
) external returns (bytes memory context, bool revertOnRecipientRevert) {
IPaymaster paymaster = IPaymaster(relayRequest.relayData.paymaster);
IPaymaster.GasAndDataLimits memory limits = paymaster.getGasAndDataLimits();
return
paymaster.preRelayedCall{ gas: limits.preRelayedCallGasLimit }(
relayRequest,
signature,
approvalData,
maxPossibleGas
);
}

function callPostRC(
IPaymaster paymaster,
bytes calldata context,
uint256 gasUseWithoutPost,
GsnTypes.RelayData calldata relayData
) external {
IPaymaster.GasAndDataLimits memory limits = paymaster.getGasAndDataLimits();
paymaster.postRelayedCall{ gas: limits.postRelayedCallGasLimit }(context, true, gasUseWithoutPost, relayData);
}
}
14 changes: 14 additions & 0 deletions contracts/mocks/contracts/TestToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.12;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract TestToken is ERC20 {
/* solhint-disable no-empty-blocks */
constructor(string memory name, string memory symbol) public ERC20(name, symbol) {}

function mint(address account, uint256 amount) public {
_mint(account, amount);
}
}
32 changes: 32 additions & 0 deletions contracts/mocks/utils/AllEvents.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier:MIT
pragma solidity ^0.8.7;

/**
* In order to help the Truffle tests to decode events in the transactions' results,
* the events must be declared in a top-level contract.
* Implement this empty interface in order to add event signatures to any contract.
*
*/
interface AllEvents {
event Received(address indexed sender, uint256 eth);
event Withdrawal(address indexed src, uint256 wad);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event TokensCharged(
uint256 gasUseWithoutPost,
uint256 gasJustPost,
uint256 tokenActualCharge,
uint256 ethActualCharge
);
event UniswapReverted(address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin);

event Swap(
address indexed sender,
address indexed recipient,
int256 amount0,
int256 amount1,
uint160 sqrtPriceX96,
uint128 liquidity,
int24 tick
);
}
143 changes: 143 additions & 0 deletions contracts/mocks/utils/RelayRegistrar.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// solhint-disable not-rely-on-time
//SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.6;
/* solhint-disable no-inline-assembly */

// #if ENABLE_CONSOLE_LOG
import "hardhat/console.sol";
// #endif

import "@openzeppelin/contracts-0.8.x/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts-0.8.x/access/Ownable.sol";

import "../../protocol/meta-tx/GSN/libraries/MinLibBytes.sol";
import "../../protocol/meta-tx/GSN/interfaces/IRelayHub.sol";
import "../../protocol/meta-tx/GSN/interfaces/IRelayRegistrar.sol";

/**
* @title The RelayRegistrar Implementation
* @notice Keeps a list of registered relayers.
*
* @notice Provides view functions to read the list of registered relayers and filters out invalid ones.
*
* @notice Protects the list from spamming entries: only staked relayers are added.
*/
contract RelayRegistrar is IRelayRegistrar, Ownable, ERC165 {
using MinLibBytes for bytes;

uint256 private constant MAX_RELAYS_RETURNED_COUNT = 1000;

/// @notice Mapping from `RelayHub` address to a mapping from a Relay Manager address to its registration details.
mapping(address => mapping(address => RelayInfo)) internal values;

/// @notice Mapping from `RelayHub` address to an array of Relay Managers that are registered on that `RelayHub`.
mapping(address => address[]) internal indexedValues;

uint256 private immutable creationBlock;

uint256 private relayRegistrationMaxAge;

constructor(uint256 _relayRegistrationMaxAge) {
setRelayRegistrationMaxAge(_relayRegistrationMaxAge);
creationBlock = block.number;
}

/// @inheritdoc IRelayRegistrar
function getCreationBlock() external view override returns (uint256) {
return creationBlock;
}

/// @inheritdoc IRelayRegistrar
function getRelayRegistrationMaxAge() external view override returns (uint256) {
return relayRegistrationMaxAge;
}

/// @inheritdoc IRelayRegistrar
function setRelayRegistrationMaxAge(uint256 _relayRegistrationMaxAge) public override onlyOwner {
relayRegistrationMaxAge = _relayRegistrationMaxAge;
}

/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IRelayRegistrar).interfaceId || super.supportsInterface(interfaceId);
}

/// @inheritdoc IRelayRegistrar
function registerRelayServer(address relayHub, bytes32[3] calldata url) external override {
address relayManager = msg.sender;
IRelayHub(relayHub).onRelayServerRegistered(relayManager);
emit RelayServerRegistered(relayManager, relayHub, url);
storeRelayServerRegistration(relayManager, relayHub, url);
}

function addItem(address relayHub, address relayManager) internal returns (RelayInfo storage) {
RelayInfo storage storageInfo = values[relayHub][relayManager];
if (storageInfo.lastSeenBlockNumber == 0) {
indexedValues[relayHub].push(relayManager);
}
return storageInfo;
}

function storeRelayServerRegistration(
address relayManager,
address relayHub,
bytes32[3] calldata url
) internal {
RelayInfo storage storageInfo = addItem(relayHub, relayManager);
if (storageInfo.firstSeenBlockNumber == 0) {
storageInfo.firstSeenBlockNumber = uint32(block.number);
storageInfo.firstSeenTimestamp = uint40(block.timestamp);
}
storageInfo.lastSeenBlockNumber = uint32(block.number);
storageInfo.lastSeenTimestamp = uint40(block.timestamp);
storageInfo.relayManager = relayManager;
storageInfo.urlParts = url;
}

/// @inheritdoc IRelayRegistrar
function getRelayInfo(address relayHub, address relayManager) public view override returns (RelayInfo memory) {
RelayInfo memory info = values[relayHub][relayManager];
require(info.lastSeenBlockNumber != 0, "relayManager not found");
return info;
}

/// @inheritdoc IRelayRegistrar
function readRelayInfos(address relayHub) public view override returns (RelayInfo[] memory info) {
uint256 blockTimestamp = block.timestamp;
uint256 oldestBlockTimestamp =
blockTimestamp >= relayRegistrationMaxAge ? blockTimestamp - relayRegistrationMaxAge : 0;
return readRelayInfosInRange(relayHub, 0, oldestBlockTimestamp, MAX_RELAYS_RETURNED_COUNT);
}

/// @inheritdoc IRelayRegistrar
function readRelayInfosInRange(
address relayHub,
uint256 oldestBlockNumber,
uint256 oldestBlockTimestamp,
uint256 maxCount
) public view override returns (RelayInfo[] memory info) {
address[] storage items = indexedValues[relayHub];
uint256 filled = 0;
info = new RelayInfo[](items.length < maxCount ? items.length : maxCount);
for (uint256 i = 0; i < items.length; i++) {
address relayManager = items[i];
RelayInfo memory relayInfo = getRelayInfo(relayHub, relayManager);
if (
relayInfo.lastSeenBlockNumber < oldestBlockNumber || relayInfo.lastSeenTimestamp < oldestBlockTimestamp
) {
continue;
}
// solhint-disable-next-line no-empty-blocks
try IRelayHub(relayHub).verifyRelayManagerStaked(relayManager) {} catch (
bytes memory /*lowLevelData*/
) {
continue;
}
info[filled++] = relayInfo;
if (filled >= maxCount) break;
}
assembly {
mstore(info, filled)
}
}
}
Loading