Skip to content

Commit c143127

Browse files
authored
Update the SwapRequestReceipt parameters to include the tokenIn and tokenOut instead of only a token parameter representing the tokenOut (#77)
* update the SwapRequestReceipt parameters to include the tokenIn and tokenOut instead of only a token parameter representing the tokenOut * update swapRequestReceipt verification in unit tests * remove onlyAdmin from setMinimumContractUpgradeDelay since it's BLS committee-gated
1 parent 9c05726 commit c143127

File tree

5 files changed

+66
-57
lines changed

5 files changed

+66
-57
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,3 @@ flat/
170170

171171
# Soldeer
172172
dependencies/
173-
174-
# Audit
175-
audit/audit-response.md

src/Router.sol

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ contract Router is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessControl
229229
requestId: requestId,
230230
srcChainId: srcChainId,
231231
dstChainId: getChainID(),
232-
token: tokenOut, // tokenOut is the token being received on the destination chain
232+
tokenIn: tokenIn,
233+
tokenOut: tokenOut, // tokenOut is the token being received on the destination chain
233234
fulfilled: true, // indicates the transfer was fulfilled, prevents double fulfillment
234235
solver: solverRefundAddress,
235236
recipient: recipient,
@@ -456,7 +457,8 @@ contract Router is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessControl
456457
/// @return requestId The unique ID of the swap request
457458
/// @return srcChainId The source chain ID from which the request originated
458459
/// @return dstChainId The destination chain ID where the tokens were delivered
459-
/// @return token The address of the token involved in the transfer
460+
/// @return tokenIn The token being sent on the source chain
461+
/// @return tokenOut The token being received on the destination chain
460462
/// @return fulfilled Indicates if the transfer was fulfilled
461463
/// @return solver The address of the solver who fulfilled the transfer
462464
/// @return recipient The address that received the tokens on the destination chain
@@ -469,7 +471,8 @@ contract Router is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessControl
469471
bytes32 requestId,
470472
uint256 srcChainId,
471473
uint256 dstChainId,
472-
address token,
474+
address tokenIn,
475+
address tokenOut,
473476
bool fulfilled,
474477
address solver,
475478
address recipient,
@@ -481,7 +484,8 @@ contract Router is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessControl
481484
requestId = receipt.requestId;
482485
srcChainId = receipt.srcChainId;
483486
dstChainId = receipt.dstChainId;
484-
token = receipt.token;
487+
tokenIn = receipt.tokenIn;
488+
tokenOut = receipt.tokenOut;
485489
fulfilled = receipt.fulfilled;
486490
solver = receipt.solver;
487491
recipient = receipt.recipient;

src/interfaces/IRouter.sol

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ interface IRouter {
3636
bytes32 requestId; // Reference to the original request on the source chain
3737
uint256 srcChainId; // Source chain ID from which the request originated
3838
uint256 dstChainId; // Destination chain ID where the request was fulfilled
39-
address token; // Token being transferred
39+
address tokenIn; // Token being sent on the source chain
40+
address tokenOut; // Token being received on the destination chain
4041
bool fulfilled; // Whether the transfer has been delivered
4142
address solver; // Address that fulfilled the request
4243
address recipient; // Recipient of the tokens on the destination chain
@@ -232,7 +233,8 @@ interface IRouter {
232233
/// @return requestId The unique ID of the swap request
233234
/// @return srcChainId The source chain ID from which the request originated
234235
/// @return dstChainId The destination chain ID where the tokens were delivered
235-
/// @return token The address of the token involved in the transfer
236+
/// @return tokenIn The token being sent on the source chain
237+
/// @return tokenOut The token being received on the destination chain
236238
/// @return fulfilled Indicates if the transfer was fulfilled
237239
/// @return solver The address of the solver who fulfilled the transfer
238240
/// @return recipient The address that received the tokens on the destination chain
@@ -245,7 +247,8 @@ interface IRouter {
245247
bytes32 requestId,
246248
uint256 srcChainId,
247249
uint256 dstChainId,
248-
address token,
250+
address tokenIn,
251+
address tokenOut,
249252
bool fulfilled,
250253
address solver,
251254
address recipient,

src/mocks/MockRouterV2.sol

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ contract MockRouterV2 is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessC
227227
requestId: requestId,
228228
srcChainId: srcChainId,
229229
dstChainId: getChainID(),
230-
token: tokenOut, // tokenOut is the token being received on the destination chain
230+
tokenIn: tokenIn,
231+
tokenOut: tokenOut, // tokenOut is the token being received on the destination chain
231232
fulfilled: true, // indicates the transfer was fulfilled, prevents double fulfillment
232233
solver: solverRefundAddress,
233234
recipient: recipient,
@@ -449,7 +450,8 @@ contract MockRouterV2 is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessC
449450
/// @return requestId The unique ID of the swap request
450451
/// @return srcChainId The source chain ID from which the request originated
451452
/// @return dstChainId The destination chain ID where the tokens were delivered
452-
/// @return token The address of the token involved in the transfer
453+
/// @return tokenIn The token being sent on the source chain
454+
/// @return tokenOut The token being received on the destination chain
453455
/// @return fulfilled Indicates if the transfer was fulfilled
454456
/// @return solver The address of the solver who fulfilled the transfer
455457
/// @return recipient The address that received the tokens on the destination chain
@@ -462,7 +464,8 @@ contract MockRouterV2 is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessC
462464
bytes32 requestId,
463465
uint256 srcChainId,
464466
uint256 dstChainId,
465-
address token,
467+
address tokenIn,
468+
address tokenOut,
466469
bool fulfilled,
467470
address solver,
468471
address recipient,
@@ -474,7 +477,8 @@ contract MockRouterV2 is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessC
474477
requestId = receipt.requestId;
475478
srcChainId = receipt.srcChainId;
476479
dstChainId = receipt.dstChainId;
477-
token = receipt.token;
480+
tokenIn = receipt.tokenIn;
481+
tokenOut = receipt.tokenOut;
478482
fulfilled = receipt.fulfilled;
479483
solver = receipt.solver;
480484
recipient = receipt.recipient;
@@ -508,7 +512,6 @@ contract MockRouterV2 is ReentrancyGuard, IRouter, ScheduledUpgradeable, AccessC
508512
function setMinimumContractUpgradeDelay(uint256 _minimumContractUpgradeDelay, bytes calldata signature)
509513
public
510514
override (IRouter, ScheduledUpgradeable)
511-
onlyAdmin
512515
{
513516
super.setMinimumContractUpgradeDelay(_minimumContractUpgradeDelay, signature);
514517
}

test/hardhat/Router.test.ts

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import {
77
BLSBN254SignatureScheme,
88
BLSBN254SignatureScheme__factory,
99
UUPSProxy__factory,
10-
BLS__factory,
1110
} from "../../typechain-types";
1211
import { bn254 } from "@kevincharm/noble-bn254-drand";
1312
import { randomBytes } from "@noble/hashes/utils";
1413
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
15-
import { expect, use } from "chai";
14+
import { expect } from "chai";
1615
import {
1716
AbiCoder,
1817
parseEther,
@@ -23,10 +22,8 @@ import {
2322
keccak256,
2423
toUtf8Bytes,
2524
ZeroAddress,
26-
hexlify,
2725
} from "ethers";
2826
import { ethers } from "hardhat";
29-
import { parse } from "path";
3027

3128
const DST_CHAIN_ID = 137;
3229

@@ -344,7 +341,7 @@ describe("Router", function () {
344341
}
345342

346343
const routerInterface = Router__factory.createInterface();
347-
const [requestId, message] = extractSingleLog(
344+
const [requestId] = extractSingleLog(
348345
routerInterface,
349346
receipt,
350347
await router.getAddress(),
@@ -410,7 +407,7 @@ describe("Router", function () {
410407
}
411408

412409
const routerInterface = Router__factory.createInterface();
413-
const [requestId, message] = extractSingleLog(
410+
const [requestId] = extractSingleLog(
414411
routerInterface,
415412
receipt,
416413
await router.getAddress(),
@@ -573,10 +570,14 @@ describe("Router", function () {
573570
expect(await dstToken.balanceOf(recipientAddr)).to.equal(amount);
574571

575572
// Check receipt
576-
const receipt = await router.swapRequestReceipts(requestId);
577-
expect(receipt.fulfilled).to.be.true;
578-
expect(receipt.amountOut).to.equal(amount);
579-
expect(receipt.solver).to.equal(solverRefundAddr);
573+
const swapRequestReceipt = await router.getSwapRequestReceipt(requestId);
574+
const [, , , , , fulfilled, solverFromReceipt, , amountOut] = swapRequestReceipt;
575+
576+
expect(fulfilled).to.be.true;
577+
expect(amountOut).to.equal(amount);
578+
// solver address in the receipt should match the solver who called relayTokens
579+
expect(solverFromReceipt).to.equal(solverRefundAddr);
580+
expect(solverAddr).to.not.equal(solverRefundAddr);
580581

581582
expect((await router.getFulfilledTransfers()).includes(requestId)).to.be.equal(true);
582583
expect((await router.getFulfilledTransfers()).length).to.be.equal(1);
@@ -626,29 +627,27 @@ describe("Router", function () {
626627

627628
// Relay tokens
628629
await expect(
629-
router
630-
.connect(solver)
631-
.relayTokens(
632-
ZeroAddress,
633-
requestId,
634-
userAddr,
635-
recipientAddr,
636-
await srcToken.getAddress(),
637-
await dstToken.getAddress(),
638-
amount,
639-
srcChainId,
640-
nonce,
641-
),
630+
router.connect(solver).relayTokens(
631+
ZeroAddress, // zero address in place of solverRefundAddress should revert
632+
requestId,
633+
userAddr,
634+
recipientAddr,
635+
await srcToken.getAddress(),
636+
await dstToken.getAddress(),
637+
amount,
638+
srcChainId,
639+
nonce,
640+
),
642641
).to.revertedWithCustomError(router, "ZeroAddress()");
643642

644643
// Check recipient balance after transfer
645644
expect(await dstToken.balanceOf(recipientAddr)).to.equal(0n);
646645

647646
// Check receipt
648-
const receipt = await router.swapRequestReceipts(requestId);
649-
expect(receipt.fulfilled).to.be.false;
650-
expect(receipt.amountOut).to.equal(0n);
651-
expect(receipt.solver).to.equal(ZeroAddress);
647+
const [, , , , , fulfilled, solverFromReceipt, , amountOut] = await router.swapRequestReceipts(requestId);
648+
expect(fulfilled).to.be.false;
649+
expect(amountOut).to.equal(0n);
650+
expect(solverFromReceipt).to.equal(ZeroAddress);
652651

653652
expect((await router.getFulfilledTransfers()).includes(requestId)).to.be.equal(false);
654653
expect((await router.getFulfilledTransfers()).length).to.be.equal(0n);
@@ -664,7 +663,7 @@ describe("Router", function () {
664663
router
665664
.connect(solver)
666665
.relayTokens(
667-
userAddr,
666+
solverRefundAddr,
668667
requestId,
669668
userAddr,
670669
recipientAddr,
@@ -676,7 +675,11 @@ describe("Router", function () {
676675
),
677676
).to.emit(router, "SwapRequestFulfilled");
678677

678+
// Check fulfilled transfers
679679
expect((await router.getFulfilledTransfers()).length).to.be.equal(1);
680+
681+
// Check recipient balance after transfer
682+
expect(await dstToken.balanceOf(recipientAddr)).to.equal(amount);
680683
});
681684

682685
it("should revert if source chain id is the same as the destination chain id", async () => {
@@ -952,20 +955,18 @@ describe("Router", function () {
952955
expect((await router.getFulfilledTransfers()).length).to.be.equal(1);
953956

954957
const swapRequestReceipt = await router.getSwapRequestReceipt(requestId);
958+
const [, , , srcTokenAddr, dstTokenAddr, fulfilled, sender, recipient, amountOut] = swapRequestReceipt;
959+
955960
// Check receipt values
956-
expect(swapRequestReceipt[0]).to.equal(requestId);
957-
expect(swapRequestReceipt[1]).to.equal(srcChainId);
958-
expect(swapRequestReceipt[2]).to.equal(await router.getChainID());
959-
expect(swapRequestReceipt[3]).to.equal(await dstToken.getAddress());
960-
expect(swapRequestReceipt[4]).to.be.true;
961-
expect(swapRequestReceipt[5]).to.equal(solverRefundAddr);
962-
expect(swapRequestReceipt[6]).to.equal(recipientAddr);
963-
expect(swapRequestReceipt[7]).to.equal(amount);
964-
965-
// Check transaction receipt values compared to emitted event
966-
expect(reqId).to.equal(swapRequestReceipt[0]);
967-
expect(sourceChainId).to.equal(swapRequestReceipt[1]);
968-
expect(dstChainId).to.equal(swapRequestReceipt[2]);
961+
expect(reqId).to.equal(requestId);
962+
expect(sourceChainId).to.equal(srcChainId);
963+
expect(dstChainId).to.equal(await router.getChainID());
964+
expect(srcTokenAddr).to.equal(await srcToken.getAddress());
965+
expect(dstTokenAddr).to.equal(await dstToken.getAddress());
966+
expect(fulfilled).to.be.true;
967+
expect(sender).to.equal(solverRefundAddr);
968+
expect(recipient).to.equal(recipientAddr);
969+
expect(amountOut).to.equal(amount);
969970

970971
// Check recipient balance after transfer
971972
expect(await dstToken.balanceOf(recipientAddr)).to.equal(amount);
@@ -1490,7 +1491,8 @@ describe("Router", function () {
14901491
[sigPointToAffine.x, sigPointToAffine.y],
14911492
);
14921493

1493-
const tx = await router.setMinimumContractUpgradeDelay(newDelay, sigBytes);
1494+
// anyone can call this function, not just owner
1495+
const tx = await router.connect(solver).setMinimumContractUpgradeDelay(newDelay, sigBytes);
14941496
await expect(tx).to.emit(router, "MinimumContractUpgradeDelayUpdated").withArgs(newDelay);
14951497

14961498
expect(await router.minimumContractUpgradeDelay()).to.equal(newDelay);

0 commit comments

Comments
 (0)