Skip to content

Commit

Permalink
feat: change npm package name to @gelatonetwork/relay-context and sta…
Browse files Browse the repository at this point in the history
…rt fresh
  • Loading branch information
gitpusha committed Sep 7, 2022
1 parent 71b40a6 commit e39a479
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 53 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# relayer-context-contracts
# relay-context-contracts
23 changes: 13 additions & 10 deletions contracts/GelatoRelayContext.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {TokenUtils} from "./lib/TokenUtils.sol";
import {GELATO_RELAY} from "./constants/GelatoRelay.sol";

/**
* @dev Context variant with Gelato Relayer Fee support.
* @dev Context variant with Gelato Relay Fee support.
* Expects calldata encoding:
* abi.encodePacked(bytes fnArgs, address feeCollectorAddress, address feeToken, uint256 fee)
* Therefore, we're expecting 3 * 32bytes to be appended to normal msgData
Expand All @@ -22,17 +22,20 @@ abstract contract GelatoRelayContext {
uint256 internal constant _FEE_TOKEN_START = 2 * 32;
uint256 internal constant _FEE_START = 32;

modifier onlyRelayer() {
require(_isRelayer(msg.sender), "GelatoRelayContext.onlyRelayer");
modifier onlyGelatoRelay() {
require(
_isGelatoRelay(msg.sender),
"GelatoRelayContext.onlyGelatoRelay"
);
_;
}

// DANGER! Only use with onlyRelayer `_isRelayer` before transferring
// DANGER! Only use with onlyGelatoRelay `_isGelatoRelay` before transferring
function _transferRelayFee() internal {
_getFeeToken().transfer(_getFeeCollector(), _getFee());
}

// DANGER! Only use with onlyRelayer `_isRelayer` before transferring
// DANGER! Only use with onlyGelatoRelay `_isGelatoRelay` before transferring
function _transferRelayFeeCapped(uint256 _maxFee) internal {
uint256 fee = _getFee();
require(
Expand All @@ -42,7 +45,7 @@ abstract contract GelatoRelayContext {
_getFeeToken().transfer(_getFeeCollector(), fee);
}

function _isRelayer(address _forwarder)
function _isGelatoRelay(address _forwarder)
internal
view
virtual
Expand All @@ -53,12 +56,12 @@ abstract contract GelatoRelayContext {

function _msgData() internal view returns (bytes calldata) {
return
_isRelayer(msg.sender)
_isGelatoRelay(msg.sender)
? msg.data[:msg.data.length - _FEE_COLLECTOR_START]
: msg.data;
}

// Only use with previous onlyRelayer or `_isRelayer` checks
// Only use with previous onlyGelatoRelay or `_isGelatoRelay` checks
function _getFeeCollector() internal pure returns (address) {
return
abi.decode(
Expand All @@ -67,7 +70,7 @@ abstract contract GelatoRelayContext {
);
}

// Only use with previous onlyRelayer or `_isRelayer` checks
// Only use with previous onlyGelatoRelay or `_isGelatoRelay` checks
function _getFeeToken() internal pure returns (address) {
return
abi.decode(
Expand All @@ -76,7 +79,7 @@ abstract contract GelatoRelayContext {
);
}

// Only use with previous onlyRelayer or `_isRelayer` checks
// Only use with previous onlyGelatoRelay or `_isGelatoRelay` checks
function _getFee() internal pure returns (uint256) {
return abi.decode(msg.data[msg.data.length - _FEE_START:], (uint256));
}
Expand Down
5 changes: 1 addition & 4 deletions contracts/__mocks__/MockGelatoRelayContext.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

// import {
// GelatoRelayContext
// } from "@gelatonetwork/relayer-context/contracts/GelatoRelayContext.sol";
import {GelatoRelayContext} from "../GelatoRelayContext.sol";

contract MockGelatoRelayContext is GelatoRelayContext {
Expand All @@ -26,5 +23,5 @@ contract MockGelatoRelayContext is GelatoRelayContext {
}

// solhint-disable-next-line no-empty-blocks
function testOnlyRelayer() external onlyRelayer {}
function testOnlyGelatoRelay() external onlyGelatoRelay {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@
pragma solidity ^0.8.1;

import {GelatoBytes} from "../lib/GelatoBytes.sol";
// import {
// _encodeRelayerContext
// } from "@gelatonetwork/relayer-context/contracts/functions/RelayerUtils.sol";
import {_encodeRelayerContext} from "../functions/RelayerUtils.sol";
import {_encodeGelatoRelayContext} from "../functions/GelatoRelayUtils.sol";

/// @dev Mock contracts for testing - UNSAFE CODE - do not copy
contract MockRelayer {
contract MockRelay {
using GelatoBytes for bytes;

function forwardCall(
Expand All @@ -19,8 +16,8 @@ contract MockRelayer {
uint256 _fee
) external {
(bool success, bytes memory returndata) = _target.call(
_encodeRelayerContext(_data, _feeCollector, _feeToken, _fee)
_encodeGelatoRelayContext(_data, _feeCollector, _feeToken, _fee)
);
if (!success) returndata.revertWithError("MockRelayer.forwardCall:");
if (!success) returndata.revertWithError("MockRelay.forwardCall:");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

function _encodeRelayerContext(
function _encodeGelatoRelayContext(
bytes calldata _fnArgs,
address _feeCollector,
address _feeToken,
Expand Down
4 changes: 2 additions & 2 deletions deploy/MockRelayer.deploy.ts → deploy/MockRelay.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
process.exit(1);
}

await deploy("MockRelayer", {
await deploy("MockRelay", {
from: deployer,
});
};
Expand All @@ -20,6 +20,6 @@ func.skip = async (hre: HardhatRuntimeEnvironment) => {
return hre.network.name !== "hardhat";
};

func.tags = ["MockRelayer"];
func.tags = ["MockRelay"];

export default func;
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@gelatonetwork/relayer-context",
"version": "1.0.3",
"description": "Contains solidity helpers for implementing the Relayer Fee Context",
"name": "@gelatonetwork/relay-context",
"version": "0.0.0",
"description": "Solidity and test helpers for implementing GelatoRelayContext",
"files": [
"contracts/GelatoRelayContext.sol",
"contracts/constants",
Expand All @@ -25,7 +25,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/gelatodigital/relayer-context-contracts.git"
"url": "git+https://github.com/gelatodigital/relay-context-contracts.git"
},
"license": "MIT",
"dependencies": {
Expand Down
48 changes: 24 additions & 24 deletions test/MockRelayerContext.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import hre = require("hardhat");
import { expect } from "chai";
import { MockRelayer, MockGelatoRelayContext, MockERC20 } from "../typechain";
import { MockRelay, MockGelatoRelayContext, MockERC20 } from "../typechain";
import { INIT_TOKEN_BALANCE as FEE } from "./constants";
import { ethers } from "hardhat";

const FEE_COLLECTOR = "0x3CACa7b48D0573D793d3b0279b5F0029180E83b6";

describe("Test MockGelatoRelayContext Smart Contract", function () {
let mockRelayer: MockRelayer;
let mockRelayerContext: MockGelatoRelayContext;
let mockRelay: MockRelay;
let mockRelayContext: MockGelatoRelayContext;
let mockERC20: MockERC20;

let target: string;
Expand All @@ -22,18 +22,18 @@ describe("Test MockGelatoRelayContext Smart Contract", function () {

await hre.deployments.fixture();

mockRelayer = await hre.ethers.getContract("MockRelayer");
mockRelayerContext = await hre.ethers.getContract("MockGelatoRelayContext");
mockRelay = await hre.ethers.getContract("MockRelay");
mockRelayContext = await hre.ethers.getContract("MockGelatoRelayContext");
mockERC20 = await hre.ethers.getContract("MockERC20");

target = mockRelayerContext.address;
target = mockRelayContext.address;
feeToken = mockERC20.address;
});

it("#1: emitContext", async () => {
const data = mockRelayerContext.interface.encodeFunctionData("emitContext");
const data = mockRelayContext.interface.encodeFunctionData("emitContext");

// Mimic RelayerUtils _encodeRelayerContext used on-chain by MockRelayer
// Mimic GelatoRelayUtils _encodeGelatoRelayContext used on-chain by MockRelay
const encodedContextData = new ethers.utils.AbiCoder().encode(
["address", "address", "uint256"],
[FEE_COLLECTOR, feeToken, FEE]
Expand All @@ -44,78 +44,78 @@ describe("Test MockGelatoRelayContext Smart Contract", function () {
);

await expect(
mockRelayer.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE)
mockRelay.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE)
)
.to.emit(mockRelayerContext, "LogMsgData")
.to.emit(mockRelayContext, "LogMsgData")
.withArgs(encodedData)
.and.to.emit(mockRelayerContext, "LogFnArgs")
.and.to.emit(mockRelayContext, "LogFnArgs")
.withArgs(data)
.and.to.emit(mockRelayerContext, "LogContext")
.and.to.emit(mockRelayContext, "LogContext")
.withArgs(FEE_COLLECTOR, feeToken, FEE);
});

it("#2: testTransferRelayFee", async () => {
const data = mockRelayerContext.interface.encodeFunctionData(
const data = mockRelayContext.interface.encodeFunctionData(
"testTransferRelayFee"
);

await mockERC20.transfer(target, FEE);

await mockRelayer.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE);
await mockRelay.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE);

expect(await mockERC20.balanceOf(FEE_COLLECTOR)).to.be.eq(FEE);
});

it("#3: testTransferRelayFeeCapped: works if at maxFee", async () => {
const maxFee = FEE;

const data = mockRelayerContext.interface.encodeFunctionData(
const data = mockRelayContext.interface.encodeFunctionData(
"testTransferRelayFeeCapped",
[maxFee]
);

await mockERC20.transfer(target, FEE);

await mockRelayer.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE);
await mockRelay.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE);

expect(await mockERC20.balanceOf(FEE_COLLECTOR)).to.be.eq(FEE);
});

it("#4: testTransferRelayFeeCapped: works if below maxFee", async () => {
const maxFee = FEE.add(1);

const data = mockRelayerContext.interface.encodeFunctionData(
const data = mockRelayContext.interface.encodeFunctionData(
"testTransferRelayFeeCapped",
[maxFee]
);

await mockERC20.transfer(target, FEE);

await mockRelayer.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE);
await mockRelay.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE);

expect(await mockERC20.balanceOf(FEE_COLLECTOR)).to.be.eq(FEE);
});

it("#5: testTransferRelayFeeCapped: reverts if above maxFee", async () => {
const maxFee = FEE.sub(1);

const data = mockRelayerContext.interface.encodeFunctionData(
const data = mockRelayContext.interface.encodeFunctionData(
"testTransferRelayFeeCapped",
[maxFee]
);

await mockERC20.transfer(target, FEE);

await expect(
mockRelayer.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE)
mockRelay.forwardCall(target, data, FEE_COLLECTOR, feeToken, FEE)
).to.be.revertedWith(
"MockRelayer.forwardCall:GelatoRelayContext._transferRelayFeeCapped: maxFee"
"MockRelay.forwardCall:GelatoRelayContext._transferRelayFeeCapped: maxFee"
);
});

it("#6: testOnlyRelayer reverts if not relayer", async () => {
await expect(mockRelayerContext.testOnlyRelayer()).to.be.revertedWith(
"GelatoRelayContext.onlyRelayer"
it("#6: testOnlyGelatoRelay reverts if not GelatoRelay", async () => {
await expect(mockRelayContext.testOnlyGelatoRelay()).to.be.revertedWith(
"GelatoRelayContext.onlyGelatoRelay"
);
});
});

0 comments on commit e39a479

Please sign in to comment.