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
17 changes: 8 additions & 9 deletions contracts/SpokePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1148,20 +1148,19 @@ abstract contract SpokePool is

// If user's specified max amount to send is greater than the amount of the relay remaining pre-fees,
// we'll pull exactly enough tokens to complete the relay.
uint256 amountToSend = relayExecution.maxTokensToSend;
uint256 amountRemainingInRelay = relayData.amount - relayFills[relayExecution.relayHash];
if (amountRemainingInRelay < fillAmountPreFees) {
fillAmountPreFees = amountRemainingInRelay;

// The user will fulfill the remainder of the relay, so we need to compute exactly how many tokens post-fees
// that they need to send to the recipient. Note that if the relayer is filled using contract funds then
// this is a slow relay.
amountToSend = _computeAmountPostFees(
fillAmountPreFees,
relayData.realizedLpFeePct + relayExecution.updatedRelayerFeePct
);
}

// Apply post-fees computation to amount that relayer will send to user. Rounding errors are possible
// when computing fillAmountPreFees and then amountToSend, and we just want to enforce that
// the error added to amountToSend is consistently applied to partial and full fills.
uint256 amountToSend = _computeAmountPostFees(
fillAmountPreFees,
relayData.realizedLpFeePct + relayExecution.updatedRelayerFeePct
);

// This can only happen in a slow fill, where the contract is funding the relay.
if (relayExecution.payoutAdjustmentPct != 0) {
// If payoutAdjustmentPct is positive, then the recipient will receive more than the amount they
Expand Down
13 changes: 11 additions & 2 deletions test/SpokePool.Relay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,17 @@ async function testfillRelayWithUpdatedDeposit(depositorAddress: string) {
);

// The collateral should have transferred from relayer to recipient.
expect(await destErc20.balanceOf(relayer.address)).to.equal(consts.amountToSeedWallets.sub(consts.amountToRelay));
expect(await destErc20.balanceOf(recipient.address)).to.equal(consts.amountToRelay);
const relayerBalance = await destErc20.balanceOf(relayer.address);
const expectedRelayerBalance = consts.amountToSeedWallets.sub(consts.amountToRelay);

// Note: We need to add an error bound of 1 wei to the expected balance because of the possibility
// of rounding errors with the modified fees. The unmodified fees result in clean numbers but the modified fee does not.
expect(relayerBalance.gte(expectedRelayerBalance.sub(1)) || relayerBalance.lte(expectedRelayerBalance.add(1))).to.be
.true;
const recipientBalance = await destErc20.balanceOf(recipient.address);
const expectedRecipientBalance = consts.amountToRelay;
expect(recipientBalance.gte(expectedRecipientBalance.sub(1)) || recipientBalance.lte(expectedRecipientBalance.add(1)))
.to.be.true;

// Fill amount should be be set taking into account modified fees.
expect(await spokePool.relayFills(relayHash)).to.equal(consts.amountToRelayPreModifiedFees);
Expand Down