* Add base Context contract
* Add GSNContext and tests
* Add RelayHub deployment to tests
* Add RelayProvider integration, complete GSNContext tests
* Switch dependency to openzeppelin-gsn-provider
* Add default txfee to provider
* Add basic signing recipient
* Sign more values
* Add comment clarifying RelayHub's msg.data
* Make context constructors internal
* Rename SigningRecipient to GSNRecipientSignedData
* Add ERC20Charge recipients
* Harcode RelayHub address into GSNContext
* Fix Solidity linter errors
* Run server from binary, use gsn-helpers to fund it
* Migrate to published @openzeppelin/gsn-helpers
* Silence false-positive compiler warning
* Use GSN helper assertions
* Rename meta-tx to gsn, take out of drafts
* Merge ERC20 charge recipients into a single one
* Rename GSNRecipients to Bouncers
* Add GSNBouncerUtils to decouple the bouncers from GSNRecipient
* Add _upgradeRelayHub
* Store RelayHub address using unstructored storage
* Add IRelayHub
* Add _withdrawDeposits to GSNRecipient
* Add relayHub version to recipient
* Make _acceptRelayedCall and _declineRelayedCall easier to use
* Rename GSNBouncerUtils to GSNBouncerBase, make it IRelayRecipient
* Improve GSNBouncerBase, make pre and post sender-protected and optional
* Fix GSNBouncerERC20Fee, add tests
* Add missing GSNBouncerSignature test
* Override transferFrom in __unstable__ERC20PrimaryAdmin
* Fix gsn dependencies in package.json
* Rhub address slot reduced by 1
* Rename relay hub changed event
* Use released gsn-provider
* Run relayer with short sleep of 1s instead of 100ms
* update package-lock.json
* clear circle cache
* use optimized gsn-provider
* update to latest @openzeppelin/gsn-provider
* replace with gsn dev provider
* remove relay server
* rename arguments in approveFunction
* fix GSNBouncerSignature test
* change gsn txfee
* initialize development provider only once
* update RelayHub interface
* adapt to new IRelayHub.withdraw
* update @openzeppelin/gsn-helpers
* update relayhub singleton address
* fix helper name
* set up gsn provider for coverage too
* lint
* Revert "set up gsn provider for coverage too"
This reverts commit 8a7b5be5f9.
* remove unused code
* add gsn provider to coverage
* move truffle contract options back out
* increase gas limit for coverage
* remove unreachable code
* add more gas for GSNContext test
* fix test suite name
* rename GSNBouncerBase internal API
* remove onlyRelayHub modifier
* add explicit inheritance
* remove redundant event
* update name of bouncers error codes enums
* add basic docs page for gsn contracts
* make gsn directory all caps
* add changelog entry
* lint
* enable test run to fail in coverage
70 lines
2.6 KiB
JavaScript
70 lines
2.6 KiB
JavaScript
const { BN, ether, expectEvent } = require('openzeppelin-test-helpers');
|
|
const gsn = require('@openzeppelin/gsn-helpers');
|
|
|
|
const { expect } = require('chai');
|
|
|
|
const GSNBouncerERC20FeeMock = artifacts.require('GSNBouncerERC20FeeMock');
|
|
const ERC20Detailed = artifacts.require('ERC20Detailed');
|
|
const IRelayHub = artifacts.require('IRelayHub');
|
|
|
|
contract('GSNBouncerERC20Fee', function ([_, sender, other]) {
|
|
const name = 'FeeToken';
|
|
const symbol = 'FTKN';
|
|
const decimals = new BN('18');
|
|
|
|
beforeEach(async function () {
|
|
this.recipient = await GSNBouncerERC20FeeMock.new(name, symbol, decimals);
|
|
this.token = await ERC20Detailed.at(await this.recipient.token());
|
|
});
|
|
|
|
describe('token', function () {
|
|
it('has a name', async function () {
|
|
expect(await this.token.name()).to.equal(name);
|
|
});
|
|
|
|
it('has a symbol', async function () {
|
|
expect(await this.token.symbol()).to.equal(symbol);
|
|
});
|
|
|
|
it('has decimals', async function () {
|
|
expect(await this.token.decimals()).to.be.bignumber.equal(decimals);
|
|
});
|
|
});
|
|
|
|
context('when called directly', function () {
|
|
it('mock function can be called', async function () {
|
|
const { logs } = await this.recipient.mockFunction();
|
|
expectEvent.inLogs(logs, 'MockFunctionCalled');
|
|
});
|
|
});
|
|
|
|
context('when relay-called', function () {
|
|
beforeEach(async function () {
|
|
await gsn.fundRecipient(web3, { recipient: this.recipient.address });
|
|
this.relayHub = await IRelayHub.at('0xD216153c06E857cD7f72665E0aF1d7D82172F494');
|
|
});
|
|
|
|
it('charges the sender for GSN fees in tokens', async function () {
|
|
// The recipient will be charged from its RelayHub balance, and in turn charge the sender from its sender balance.
|
|
// Both amounts should be roughly equal.
|
|
|
|
// The sender has a balance in tokens, not ether, but since the exchange rate is 1:1, this works fine.
|
|
const senderPreBalance = ether('2');
|
|
await this.recipient.mint(sender, senderPreBalance);
|
|
|
|
const recipientPreBalance = await this.relayHub.balanceOf(this.recipient.address);
|
|
|
|
const { tx } = await this.recipient.mockFunction({ from: sender, useGSN: true });
|
|
await expectEvent.inTransaction(tx, IRelayHub, 'TransactionRelayed', { status: '0' });
|
|
|
|
const senderPostBalance = await this.token.balanceOf(sender);
|
|
const recipientPostBalance = await this.relayHub.balanceOf(this.recipient.address);
|
|
|
|
const senderCharge = senderPreBalance.sub(senderPostBalance);
|
|
const recipientCharge = recipientPreBalance.sub(recipientPostBalance);
|
|
|
|
expect(senderCharge).to.be.bignumber.closeTo(recipientCharge, recipientCharge.divn(10));
|
|
});
|
|
});
|
|
});
|