Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions contracts/SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,12 @@ abstract contract SpokePool is
// fill any relay up to 100 tokens, and partial fill with 100 tokens for larger relays).
relayFills[relayHash] += fillAmountPreFees;

// If relayer and receiver are the same address, there is no need to do any transfer, as it would result in no
// net movement of funds.
// Note: this is important because it means that relayers can intentionally self-relay in a capital efficient
// way (no need to have funds on the destination).
if (msg.sender == relayData.recipient) return fillAmountPreFees;

// If relay token is wrappedNativeToken then unwrap and send native token.
if (relayData.destinationToken == address(wrappedNativeToken)) {
// Note: useContractFunds is True if we want to send funds to the recipient directly out of this contract,
Expand Down
21 changes: 21 additions & 0 deletions test/SpokePool.Relay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,27 @@ describe("SpokePool Relayer Logic", async function () {
// Fill amount should be set.
expect(await spokePool.relayFills(relayHash)).to.equal(consts.amountToRelayPreFees);
});
it("Self-relay transfers no tokens", async function () {
const largeRelayAmount = consts.amountToSeedWallets.mul(100);
const { relayHash, relayData } = getRelayHash(
depositor.address,
relayer.address,
consts.firstDepositId,
consts.originChainId,
consts.destinationChainId,
weth.address,
largeRelayAmount
);

// This should work, despite the amount being quite large.
await spokePool.connect(relayer).fillRelay(...getFillRelayParams(relayData, largeRelayAmount));

// Balance should be the same as before.
expect(await weth.balanceOf(relayer.address)).to.equal(consts.amountToSeedWallets);

// Fill amount should be set.
expect(await spokePool.relayFills(relayHash)).to.equal(largeRelayAmount);
});
it("General failure cases", async function () {
// Fees set too high.
await expect(
Expand Down