Skip to content

Commit aa36eb6

Browse files
authored
feat: Add relayer repayment address (#653)
* WIP Signed-off-by: chrismaree <christopher.maree@gmail.com> * WIP Signed-off-by: chrismaree <christopher.maree@gmail.com> * WIP Signed-off-by: chrismaree <christopher.maree@gmail.com> * WIP Signed-off-by: chrismaree <christopher.maree@gmail.com> * WIP Signed-off-by: chrismaree <christopher.maree@gmail.com> --------- Signed-off-by: chrismaree <christopher.maree@gmail.com>
1 parent c338c54 commit aa36eb6

File tree

12 files changed

+155
-61
lines changed

12 files changed

+155
-61
lines changed

contracts/SpokePool.sol

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,12 +1030,11 @@ abstract contract SpokePool is
10301030
* @param repaymentChainId Chain of SpokePool where relayer wants to be refunded after the challenge window has
10311031
* passed. Will receive inputAmount of the equivalent token to inputToken on the repayment chain.
10321032
*/
1033-
function fillV3Relay(V3RelayData calldata relayData, uint256 repaymentChainId)
1034-
public
1035-
override
1036-
nonReentrant
1037-
unpausedFills
1038-
{
1033+
function fillV3Relay(
1034+
V3RelayData calldata relayData,
1035+
uint256 repaymentChainId,
1036+
bytes32 repaymentAddress
1037+
) public override nonReentrant unpausedFills {
10391038
// Exclusivity deadline is inclusive and is the latest timestamp that the exclusive relayer has sole right
10401039
// to fill the relay.
10411040
if (
@@ -1055,7 +1054,7 @@ abstract contract SpokePool is
10551054
repaymentChainId: repaymentChainId
10561055
});
10571056

1058-
_fillRelayV3(relayExecution, msg.sender.toBytes32(), false);
1057+
_fillRelayV3(relayExecution, repaymentAddress, false);
10591058
}
10601059

10611060
/**
@@ -1078,6 +1077,7 @@ abstract contract SpokePool is
10781077
function fillV3RelayWithUpdatedDeposit(
10791078
V3RelayData calldata relayData,
10801079
uint256 repaymentChainId,
1080+
bytes32 repaymentAddress,
10811081
uint256 updatedOutputAmount,
10821082
bytes32 updatedRecipient,
10831083
bytes calldata updatedMessage,
@@ -1109,7 +1109,7 @@ abstract contract SpokePool is
11091109
UPDATE_V3_DEPOSIT_DETAILS_HASH
11101110
);
11111111

1112-
_fillRelayV3(relayExecution, msg.sender.toBytes32(), false);
1112+
_fillRelayV3(relayExecution, repaymentAddress, false);
11131113
}
11141114

11151115
/**

contracts/interfaces/V3SpokePoolInterface.sol

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ interface V3SpokePoolInterface {
2323
// to know when to send excess funds from the SpokePool to the HubPool because they can no longer be used
2424
// for a slow fill execution.
2525
SlowFill
26-
// Slow fills are requested via requestSlowFill and executed by executeSlowRelayLeaf after a bundle containing
27-
// the slow fill is validated.
2826
}
27+
// Slow fills are requested via requestSlowFill and executed by executeSlowRelayLeaf after a bundle containing
28+
// the slow fill is validated.
2929

3030
/**************************************
3131
* STRUCTS *
@@ -196,11 +196,16 @@ interface V3SpokePoolInterface {
196196
bytes calldata depositorSignature
197197
) external;
198198

199-
function fillV3Relay(V3RelayData calldata relayData, uint256 repaymentChainId) external;
199+
function fillV3Relay(
200+
V3RelayData calldata relayData,
201+
uint256 repaymentChainId,
202+
bytes32 repaymentAddress
203+
) external;
200204

201205
function fillV3RelayWithUpdatedDeposit(
202206
V3RelayData calldata relayData,
203207
uint256 repaymentChainId,
208+
bytes32 repaymentAddress,
204209
uint256 updatedOutputAmount,
205210
bytes32 updatedRecipient,
206211
bytes calldata updatedMessage,

hardhat.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const LARGE_CONTRACT_COMPILER_SETTINGS = {
4040
settings: {
4141
optimizer: { enabled: true, runs: 1000 },
4242
viaIR: true,
43-
debug: { revertStrings: isTest ? "default" : "strip" },
43+
debug: { revertStrings: isTest ? "debug" : "strip" },
4444
},
4545
};
4646
const DEFAULT_CONTRACT_COMPILER_SETTINGS = {
@@ -49,7 +49,7 @@ const DEFAULT_CONTRACT_COMPILER_SETTINGS = {
4949
optimizer: { enabled: true, runs: 1000000 },
5050
viaIR: true,
5151
// Only strip revert strings if not testing or in ci.
52-
debug: { revertStrings: isTest ? "default" : "strip" },
52+
debug: { revertStrings: isTest ? "debug" : "strip" },
5353
},
5454
};
5555

programs/svm-spoke/src/instructions/fill.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub fn fill_v3_relay(
9999
relay_hash: [u8; 32], // include in props, while not using it, to enable us to access it from the #Instruction Attribute within the accounts. This enables us to pass in the relay_hash PDA.
100100
relay_data: V3RelayData,
101101
repayment_chain_id: u64,
102+
repayment_address: Pubkey,
102103
) -> Result<()> {
103104
let state = &mut ctx.accounts.state;
104105
let current_time = get_current_time(state)?;
@@ -165,7 +166,7 @@ pub fn fill_v3_relay(
165166
fill_deadline: relay_data.fill_deadline,
166167
exclusivity_deadline: relay_data.exclusivity_deadline,
167168
exclusive_relayer: relay_data.exclusive_relayer,
168-
relayer: *ctx.accounts.signer.key,
169+
relayer: repayment_address,
169170
depositor: relay_data.depositor,
170171
recipient: relay_data.recipient,
171172
message: relay_data.message,

programs/svm-spoke/src/instructions/slow_fill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ pub fn execute_v3_slow_relay_leaf(
255255
fill_deadline: relay_data.fill_deadline,
256256
exclusivity_deadline: relay_data.exclusivity_deadline,
257257
exclusive_relayer: relay_data.exclusive_relayer,
258-
relayer: *ctx.accounts.signer.key,
258+
relayer: Pubkey::default(), // There is no repayment address for slow
259259
depositor: relay_data.depositor,
260260
recipient: relay_data.recipient,
261261
message: relay_data.message,

programs/svm-spoke/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,15 @@ pub mod svm_spoke {
132132
relay_hash: [u8; 32],
133133
relay_data: V3RelayData,
134134
repayment_chain_id: u64,
135+
repayment_address: Pubkey,
135136
) -> Result<()> {
136-
instructions::fill_v3_relay(ctx, relay_hash, relay_data, repayment_chain_id)
137+
instructions::fill_v3_relay(
138+
ctx,
139+
relay_hash,
140+
relay_data,
141+
repayment_chain_id,
142+
repayment_address,
143+
)
137144
}
138145

139146
pub fn close_fill_pda(

scripts/svm/simpleFill.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ async function fillV3Relay(): Promise<void> {
121121
}))
122122
);
123123

124-
const tx = await (program.methods.fillV3Relay(Array.from(relayHashUint8Array), relayData, chainId) as any)
124+
const tx = await (program.methods.fillV3Relay(Array.from(relayHashUint8Array), relayData, chainId, signer) as any)
125125
.accounts({
126126
state: statePda,
127127
signer: signer,

test/evm/hardhat/SpokePool.Relay.ts

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -318,14 +318,17 @@ describe("SpokePool Relayer Logic", async function () {
318318
describe("fillV3Relay", function () {
319319
it("fills are not paused", async function () {
320320
await spokePool.pauseFills(true);
321-
await expect(spokePool.connect(relayer).fillV3Relay(relayData, consts.repaymentChainId)).to.be.revertedWith(
322-
"FillsArePaused"
323-
);
321+
await expect(
322+
spokePool
323+
.connect(relayer)
324+
.fillV3Relay(relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address))
325+
).to.be.revertedWith("FillsArePaused");
324326
});
325327
it("reentrancy protected", async function () {
326328
const functionCalldata = spokePool.interface.encodeFunctionData("fillV3Relay", [
327329
relayData,
328330
consts.repaymentChainId,
331+
hexZeroPadAddressLowercase(relayer.address),
329332
]);
330333
await expect(spokePool.connect(relayer).callback(functionCalldata)).to.be.revertedWith(
331334
"ReentrancyGuard: reentrant call"
@@ -338,19 +341,21 @@ describe("SpokePool Relayer Logic", async function () {
338341
exclusiveRelayer: hexZeroPadAddress(recipient.address),
339342
exclusivityDeadline: relayData.fillDeadline,
340343
};
341-
await expect(spokePool.connect(relayer).fillV3Relay(_relayData, consts.repaymentChainId)).to.be.revertedWith(
342-
"NotExclusiveRelayer"
343-
);
344+
await expect(
345+
spokePool
346+
.connect(relayer)
347+
.fillV3Relay(_relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address))
348+
).to.be.revertedWith("NotExclusiveRelayer");
344349

345350
// Can send it after exclusivity deadline
346351
await expect(
347-
spokePool.connect(relayer).fillV3Relay(
348-
{
349-
..._relayData,
350-
exclusivityDeadline: 0,
351-
},
352-
consts.repaymentChainId
353-
)
352+
spokePool
353+
.connect(relayer)
354+
.fillV3Relay(
355+
{ ..._relayData, exclusivityDeadline: 0 },
356+
consts.repaymentChainId,
357+
hexZeroPadAddressLowercase(relayer.address)
358+
)
354359
).to.not.be.reverted;
355360
});
356361
it("if no exclusive relayer is set, exclusivity deadline can be in future", async function () {
@@ -361,7 +366,11 @@ describe("SpokePool Relayer Logic", async function () {
361366
};
362367

363368
// Can send it after exclusivity deadline
364-
await expect(spokePool.connect(relayer).fillV3Relay(_relayData, consts.repaymentChainId)).to.not.be.reverted;
369+
await expect(
370+
spokePool
371+
.connect(relayer)
372+
.fillV3Relay(_relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address))
373+
).to.not.be.reverted;
365374
});
366375
it("can have empty exclusive relayer before exclusivity deadline", async function () {
367376
const _relayData = {
@@ -371,10 +380,18 @@ describe("SpokePool Relayer Logic", async function () {
371380
};
372381

373382
// Can send it before exclusivity deadline if exclusive relayer is empty
374-
await expect(spokePool.connect(relayer).fillV3Relay(_relayData, consts.repaymentChainId)).to.not.be.reverted;
383+
await expect(
384+
spokePool
385+
.connect(relayer)
386+
.fillV3Relay(_relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address))
387+
).to.not.be.reverted;
375388
});
376389
it("calls _fillRelayV3 with expected params", async function () {
377-
await expect(spokePool.connect(relayer).fillV3Relay(relayData, consts.repaymentChainId))
390+
await expect(
391+
spokePool
392+
.connect(relayer)
393+
.fillV3Relay(relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address))
394+
)
378395
.to.emit(spokePool, "FilledV3Relay")
379396
.withArgs(
380397
hexZeroPadAddressLowercase(relayData.inputToken),
@@ -430,6 +447,7 @@ describe("SpokePool Relayer Logic", async function () {
430447
.fillV3RelayWithUpdatedDeposit(
431448
_relayData,
432449
consts.repaymentChainId,
450+
hexZeroPadAddressLowercase(relayer.address),
433451
updatedOutputAmount,
434452
hexZeroPadAddress(updatedRecipient),
435453
updatedMessage,
@@ -445,6 +463,7 @@ describe("SpokePool Relayer Logic", async function () {
445463
exclusivityDeadline: 0,
446464
},
447465
consts.repaymentChainId,
466+
hexZeroPadAddressLowercase(relayer.address),
448467
updatedOutputAmount,
449468
hexZeroPadAddress(updatedRecipient),
450469
updatedMessage,
@@ -464,6 +483,7 @@ describe("SpokePool Relayer Logic", async function () {
464483
.fillV3RelayWithUpdatedDeposit(
465484
relayData,
466485
consts.repaymentChainId,
486+
hexZeroPadAddressLowercase(relayer.address),
467487
updatedOutputAmount,
468488
hexZeroPadAddress(updatedRecipient),
469489
updatedMessage,
@@ -508,6 +528,7 @@ describe("SpokePool Relayer Logic", async function () {
508528
.fillV3RelayWithUpdatedDeposit(
509529
{ ...relayData, depositor: hexZeroPadAddress(relayer.address) },
510530
consts.repaymentChainId,
531+
hexZeroPadAddressLowercase(relayer.address),
511532
updatedOutputAmount,
512533
hexZeroPadAddress(updatedRecipient),
513534
updatedMessage,
@@ -530,6 +551,7 @@ describe("SpokePool Relayer Logic", async function () {
530551
.fillV3RelayWithUpdatedDeposit(
531552
relayData,
532553
consts.repaymentChainId,
554+
hexZeroPadAddressLowercase(relayer.address),
533555
updatedOutputAmount,
534556
hexZeroPadAddress(updatedRecipient),
535557
updatedMessage,
@@ -544,6 +566,7 @@ describe("SpokePool Relayer Logic", async function () {
544566
.fillV3RelayWithUpdatedDeposit(
545567
{ ...relayData, originChainId: relayData.originChainId + 1 },
546568
consts.repaymentChainId,
569+
hexZeroPadAddressLowercase(relayer.address),
547570
updatedOutputAmount,
548571
hexZeroPadAddress(updatedRecipient),
549572
updatedMessage,
@@ -558,6 +581,7 @@ describe("SpokePool Relayer Logic", async function () {
558581
.fillV3RelayWithUpdatedDeposit(
559582
{ ...relayData, depositId: relayData.depositId + 1 },
560583
consts.repaymentChainId,
584+
hexZeroPadAddressLowercase(relayer.address),
561585
updatedOutputAmount,
562586
hexZeroPadAddress(updatedRecipient),
563587
updatedMessage,
@@ -572,6 +596,7 @@ describe("SpokePool Relayer Logic", async function () {
572596
.fillV3RelayWithUpdatedDeposit(
573597
relayData,
574598
consts.repaymentChainId,
599+
hexZeroPadAddressLowercase(relayer.address),
575600
updatedOutputAmount.sub(1),
576601
hexZeroPadAddress(updatedRecipient),
577602
updatedMessage,
@@ -586,6 +611,7 @@ describe("SpokePool Relayer Logic", async function () {
586611
.fillV3RelayWithUpdatedDeposit(
587612
relayData,
588613
consts.repaymentChainId,
614+
hexZeroPadAddressLowercase(relayer.address),
589615
updatedOutputAmount,
590616
hexZeroPadAddress(randomAddress()),
591617
updatedMessage,
@@ -600,6 +626,7 @@ describe("SpokePool Relayer Logic", async function () {
600626
.fillV3RelayWithUpdatedDeposit(
601627
relayData,
602628
consts.repaymentChainId,
629+
hexZeroPadAddressLowercase(relayer.address),
603630
updatedOutputAmount,
604631
hexZeroPadAddress(updatedRecipient),
605632
updatedMessage,
@@ -624,6 +651,7 @@ describe("SpokePool Relayer Logic", async function () {
624651
.fillV3RelayWithUpdatedDeposit(
625652
{ ...relayData, depositor: hexZeroPadAddress(erc1271.address) },
626653
consts.repaymentChainId,
654+
hexZeroPadAddressLowercase(relayer.address),
627655
updatedOutputAmount,
628656
hexZeroPadAddress(updatedRecipient),
629657
updatedMessage,
@@ -636,6 +664,7 @@ describe("SpokePool Relayer Logic", async function () {
636664
.fillV3RelayWithUpdatedDeposit(
637665
{ ...relayData, depositor: hexZeroPadAddress(erc1271.address) },
638666
consts.repaymentChainId,
667+
hexZeroPadAddressLowercase(relayer.address),
639668
updatedOutputAmount,
640669
hexZeroPadAddress(updatedRecipient),
641670
updatedMessage,
@@ -644,13 +673,16 @@ describe("SpokePool Relayer Logic", async function () {
644673
).to.not.be.reverted;
645674
});
646675
it("cannot send updated fill after original fill", async function () {
647-
await spokePool.connect(relayer).fillV3Relay(relayData, consts.repaymentChainId);
676+
await spokePool
677+
.connect(relayer)
678+
.fillV3Relay(relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address));
648679
await expect(
649680
spokePool
650681
.connect(relayer)
651682
.fillV3RelayWithUpdatedDeposit(
652683
relayData,
653684
consts.repaymentChainId,
685+
hexZeroPadAddressLowercase(relayer.address),
654686
updatedOutputAmount,
655687
hexZeroPadAddress(updatedRecipient),
656688
updatedMessage,
@@ -664,14 +696,17 @@ describe("SpokePool Relayer Logic", async function () {
664696
.fillV3RelayWithUpdatedDeposit(
665697
relayData,
666698
consts.repaymentChainId,
699+
hexZeroPadAddressLowercase(relayer.address),
667700
updatedOutputAmount,
668701
hexZeroPadAddress(updatedRecipient),
669702
updatedMessage,
670703
signature
671704
);
672-
await expect(spokePool.connect(relayer).fillV3Relay(relayData, consts.repaymentChainId)).to.be.revertedWith(
673-
"RelayFilled"
674-
);
705+
await expect(
706+
spokePool
707+
.connect(relayer)
708+
.fillV3Relay(relayData, consts.repaymentChainId, hexZeroPadAddressLowercase(relayer.address))
709+
).to.be.revertedWith("RelayFilled");
675710
});
676711
});
677712
});

0 commit comments

Comments
 (0)