From 2f9be2270fe94f8a449a8f8a7c1989a4d99c4513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Wed, 12 Feb 2025 16:55:25 +0700 Subject: [PATCH 1/7] deployed stargate to gnosis --- config/stargate.json | 21 ++++++++++--------- deployments/_deployments_log_file.json | 28 ++++++++++++++++++++++++++ deployments/gnosis.json | 4 +++- script/deploy/_targetState.json | 4 +++- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/config/stargate.json b/config/stargate.json index ee7aa8e60..14701c906 100644 --- a/config/stargate.json +++ b/config/stargate.json @@ -49,24 +49,25 @@ "LinkToDeployedToAddresses": "https://stargateprotocol.gitbook.io/stargate/v/v2-developer-docs/technical-reference/mainnet-contracts", "mainnet": "0x6d6620eFa72948C5f68A3C8646d58C00d3f4A980", "bsc": "0x6e3d884c96d640526f273c61dfcf08915ebd7e2b", - "polygon": "0x6ce9bf8cdab780416ad1fd87b318a077d2f50eac", "abstract": "0x183D6b82680189bB4dB826F739CdC9527D467B25", "arbitrum": "0x19cfce47ed54a88614648dc3f19a5980097007dd", + "aurora": "0x5f688f563dc16590e570f97b542fa87931af2fed", + "avalanche": "0x17e450be3ba9557f2378e20d64ad417e59ef9a34", + "base": "0x5634c4a5fed09819e3c46d86a965dd9447d86e47", + "fantom": "----FantomIsNotSupportedByStargateV2----", "fuse": "0x45a01e4e04f14f7a4a6702c74187c5f6222033cd", + "gnosis": "0xAf368c91793CB22739386DFCbBb2F1A9e4bCBeBf", + "gravity": "0x9c2dc7377717603eB92b2655c5f2E7997a4945BD", + "kaia": "0x16F3F98D82d965988E6853681fD578F4d719A1c0", + "linea": "0x5f688f563dc16590e570f97b542fa87931af2fed", "mantle": "0x41b491285a4f888f9f636cec8a363ab9770a0aef", "metis": "0xcbe78230cca58b9ef4c3c5d1bc0d7e4b3206588a", - "linea": "0x5f688f563dc16590e570f97b542fa87931af2fed", - "kaia": "0x16F3F98D82d965988E6853681fD578F4d719A1c0", - "scroll": "0x4e422b0acb2bd7e3ac70b5c0e5eb806e86a94038", - "optimism": "0xf1fcb4cbd57b67d683972a59b6a7b1e2e8bf27e6", "opbnb": "0x0000000000000000000000000000000000000000", - "base": "0x5634c4a5fed09819e3c46d86a965dd9447d86e47", - "avalanche": "0x17e450be3ba9557f2378e20d64ad417e59ef9a34", - "aurora": "0x5f688f563dc16590e570f97b542fa87931af2fed", - "fantom": "----FantomIsNotSupportedByStargateV2----", - "gravity": "0x9c2dc7377717603eB92b2655c5f2E7997a4945BD", + "optimism": "0xf1fcb4cbd57b67d683972a59b6a7b1e2e8bf27e6", + "polygon": "0x6ce9bf8cdab780416ad1fd87b318a077d2f50eac", "rootstock": "0x45a01e4e04f14f7a4a6702c74187c5f6222033cd", "sei": "0x1502FA4be69d526124D453619276FacCab275d3D", + "scroll": "0x4e422b0acb2bd7e3ac70b5c0e5eb806e86a94038", "taiko": "0x45d417612e177672958dC0537C45a8f8d754Ac2E", "zksync": "---comingSoon---" }, diff --git a/deployments/_deployments_log_file.json b/deployments/_deployments_log_file.json index f4364d6d2..6037965c0 100644 --- a/deployments/_deployments_log_file.json +++ b/deployments/_deployments_log_file.json @@ -24460,6 +24460,20 @@ } ] } + }, + "gnosis": { + "production": { + "1.0.1": [ + { + "ADDRESS": "0xCB68AAcEb848E5007B56b1ff09D240CE8946B4EC", + "OPTIMIZER_RUNS": "1000000", + "TIMESTAMP": "2025-02-12 16:43:59", + "CONSTRUCTOR_ARGS": "0x000000000000000000000000af368c91793cb22739386dfcbbb2f1a9e4bcbebf", + "SALT": "", + "VERIFIED": "true" + } + ] + } } }, "ReceiverStargateV2": { @@ -24740,6 +24754,20 @@ } ] } + }, + "gnosis": { + "production": { + "1.1.0": [ + { + "ADDRESS": "0x0dC56076590CdF0efc37114273f02f45A96B5500", + "OPTIMIZER_RUNS": "1000000", + "TIMESTAMP": "2025-02-12 16:47:19", + "CONSTRUCTOR_ARGS": "0x000000000000000000000000156cebba59deb2cb23742f70dcb0a11cc775591f0000000000000000000000002dfadab8266483bed9fd9a292ce56596a2d1378d000000000000000000000000af368c91793cb22739386dfcbbb2f1a9e4bcbebf0000000000000000000000001a44076050125825900e736c501f859c50fe728c00000000000000000000000000000000000000000000000000000000000186a0", + "SALT": "", + "VERIFIED": "true" + } + ] + } } }, "LiFiDEXAggregator": { diff --git a/deployments/gnosis.json b/deployments/gnosis.json index e482d50c4..1177825f0 100644 --- a/deployments/gnosis.json +++ b/deployments/gnosis.json @@ -35,5 +35,7 @@ "GasZipFacet": "0xF5c923a087fb3c554579e2DD10AB6E37E0f6F849", "GasZipPeriphery": "0x9a21E33F1a78b17DAd32010CeDB9Fd2F071C17d3", "RelayFacet": "0x424BDbbaEda89732443fb1B737b6Dc194a6Ddbd5", - "DeBridgeDlnFacet": "0x18C85B940c29ECC3c210Ea40a5B6d91F5aeE2803" + "DeBridgeDlnFacet": "0x18C85B940c29ECC3c210Ea40a5B6d91F5aeE2803", + "StargateFacetV2": "0xCB68AAcEb848E5007B56b1ff09D240CE8946B4EC", + "ReceiverStargateV2": "0x0dC56076590CdF0efc37114273f02f45A96B5500" } \ No newline at end of file diff --git a/script/deploy/_targetState.json b/script/deploy/_targetState.json index 1d0ccaa35..60051ee50 100644 --- a/script/deploy/_targetState.json +++ b/script/deploy/_targetState.json @@ -262,7 +262,9 @@ "HopFacet": "2.0.0", "HopFacetPacked": "1.0.6", "HopFacetOptimized": "2.0.0", - "OmniBridgeFacet": "1.0.0" + "OmniBridgeFacet": "1.0.0", + "StargateFacetV2": "2.2.0", + "ReceiverStargateV2": "1.1.0" } } }, From 8da39bcf4cb17526a1a2606aa1f690b43566a357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Wed, 12 Feb 2025 17:03:14 +0700 Subject: [PATCH 2/7] diamond logs updated --- deployments/gnosis.diamond.json | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/deployments/gnosis.diamond.json b/deployments/gnosis.diamond.json index 85abda5a8..7a4129b4b 100644 --- a/deployments/gnosis.diamond.json +++ b/deployments/gnosis.diamond.json @@ -77,9 +77,9 @@ "Name": "CalldataVerificationFacet", "Version": "1.1.1" }, - "0xF965f52046D7095d5080bD31459601F4Eb24f72D": { - "Name": "", - "Version": "" + "0x18C85B940c29ECC3c210Ea40a5B6d91F5aeE2803": { + "Name": "DeBridgeDlnFacet", + "Version": "1.0.0" }, "0xF18A285f4e6f720Eb9b4e05df71f88b9552E6ADB": { "Name": "AmarokFacetPacked", @@ -94,23 +94,35 @@ "Version": "1.0.0" }, "0xF5c923a087fb3c554579e2DD10AB6E37E0f6F849": { + "Name": "GasZipFacet", + "Version": "2.0.0" + }, + "0x424BDbbaEda89732443fb1B737b6Dc194a6Ddbd5": { + "Name": "RelayFacet", + "Version": "1.0.0" + }, + "0x5656E307E4dEd573695Dd3eAC64EC4778F910DcA": { "Name": "", "Version": "" + }, + "0xCB68AAcEb848E5007B56b1ff09D240CE8946B4EC": { + "Name": "StargateFacetV2", + "Version": "1.0.1" } }, "Periphery": { "ERC20Proxy": "0x5741A7FfE7c39Ca175546a54985fA79211290b51", "Executor": "0x2dfaDAB8266483beD9Fd9A292Ce56596a2D1378D", "FeeCollector": "0xbD6C7B0d2f68c2b7805d88388319cfB6EcB50eA9", + "GasZipPeriphery": "0x9a21E33F1a78b17DAd32010CeDB9Fd2F071C17d3", "LiFiDEXAggregator": "0x6140b987d6B51Fd75b66C3B07733Beb5167c42fc", "LiFuelFeeCollector": "0xc02FFcdD914DbA646704439c6090BAbaD521d04C", "Permit2Proxy": "", "Receiver": "0x5439f8ca43f832DD21a28C5BF038dad4c07ad02c", "ReceiverAcrossV3": "", - "ReceiverStargateV2": "", + "ReceiverStargateV2": "0x0dC56076590CdF0efc37114273f02f45A96B5500", "RelayerCelerIM": "", - "TokenWrapper": "0x5215E9fd223BC909083fbdB2860213873046e45d", - "GasZipPeriphery": "0x9a21E33F1a78b17DAd32010CeDB9Fd2F071C17d3" + "TokenWrapper": "0x5215E9fd223BC909083fbdB2860213873046e45d" } } } \ No newline at end of file From de8e10a15b43c0c99d0851faf46a47d21ddadcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Mon, 17 Feb 2025 13:56:35 +0700 Subject: [PATCH 3/7] replace testFail_ with testRevert_ pattern due to deprecation --- .../deploy/facets/utils/DeployScriptBase.sol | 1 - test/solidity/Facets/AcrossFacet.t.sol | 15 +++++--- test/solidity/Facets/AcrossFacetV3.t.sol | 12 ++++-- test/solidity/Facets/CBridgeRefund.t.sol | 21 ++++++++-- test/solidity/Facets/DexManagerFacet.t.sol | 19 ++++++++-- test/solidity/Facets/OwnershipFacet.t.sol | 36 +++++++++++++++--- test/solidity/Facets/RelayFacet.t.sol | 22 ++++------- .../Helpers/TransferrableOwnership.t.sol | 33 +++++++++++++--- test/solidity/Periphery/Executor.t.sol | 10 +++-- test/solidity/Periphery/FeeCollector.t.sol | 38 ++++++++++--------- 10 files changed, 143 insertions(+), 64 deletions(-) diff --git a/script/deploy/facets/utils/DeployScriptBase.sol b/script/deploy/facets/utils/DeployScriptBase.sol index 55bf6f585..afe38ec25 100644 --- a/script/deploy/facets/utils/DeployScriptBase.sol +++ b/script/deploy/facets/utils/DeployScriptBase.sol @@ -44,7 +44,6 @@ contract DeployScriptBase is ScriptBase { } // reproduce and log calldata that is sent to CREATE3 - bytes4 funcSel = CREATE3Factory.deploy.selector; bytes memory create3Calldata = abi.encodeWithSelector( CREATE3Factory.deploy.selector, salt, diff --git a/test/solidity/Facets/AcrossFacet.t.sol b/test/solidity/Facets/AcrossFacet.t.sol index 196a9a8a8..661ede3bb 100644 --- a/test/solidity/Facets/AcrossFacet.t.sol +++ b/test/solidity/Facets/AcrossFacet.t.sol @@ -108,19 +108,22 @@ contract AcrossFacetTest is TestBaseFacet { } } - function testFailsToBridgeERC20TokensDueToQuoteTimeout() public { - console.logBytes4(IAcrossSpokePool.deposit.selector); - vm.startPrank(WETH_HOLDER); - ERC20 weth = ERC20(ADDRESS_WRAPPED_NATIVE); - weth.approve(address(acrossFacet), 10_000 * 10 ** weth.decimals()); + function testRevert_FailsIfCalledWithOutdatedQuote() public { + vm.startPrank(USER_SENDER); + + usdc.approve(address(acrossFacet), bridgeData.minAmount); AcrossFacet.AcrossData memory data = AcrossFacet.AcrossData( 0, // Relayer fee - uint32(block.timestamp + 20 minutes), + uint32(block.timestamp - 100 days), "", type(uint256).max ); + + vm.expectRevert("invalid quote time"); + acrossFacet.startBridgeTokensViaAcross(bridgeData, data); + vm.stopPrank(); } } diff --git a/test/solidity/Facets/AcrossFacetV3.t.sol b/test/solidity/Facets/AcrossFacetV3.t.sol index 6928bd18a..b5bad412c 100644 --- a/test/solidity/Facets/AcrossFacetV3.t.sol +++ b/test/solidity/Facets/AcrossFacetV3.t.sol @@ -36,6 +36,8 @@ contract AcrossFacetV3Test is TestBaseFacet { AcrossFacetV3.AcrossV3Data internal validAcrossData; TestAcrossFacetV3 internal acrossFacetV3; + error InvalidQuoteTimestamp(); + function setUp() public { customBlockNumberForForking = 19960294; initTestBase(); @@ -249,11 +251,13 @@ contract AcrossFacetV3Test is TestBaseFacet { vm.stopPrank(); } - function testFailsToBridgeERC20TokensDueToQuoteTimeout() public { - vm.startPrank(WETH_HOLDER); - weth.approve(address(acrossFacetV3), 10_000 * 10 ** weth.decimals()); + function testRevert_FailsIfCalledWithOutdatedQuote() public { + vm.startPrank(USER_SENDER); + usdc.approve(address(acrossFacetV3), bridgeData.minAmount); + + validAcrossData.quoteTimestamp = uint32(block.timestamp - 100 days); - validAcrossData.quoteTimestamp = uint32(block.timestamp + 20 minutes); + vm.expectRevert(InvalidQuoteTimestamp.selector); acrossFacetV3.startBridgeTokensViaAcrossV3( bridgeData, diff --git a/test/solidity/Facets/CBridgeRefund.t.sol b/test/solidity/Facets/CBridgeRefund.t.sol index da69d7723..36b15592b 100644 --- a/test/solidity/Facets/CBridgeRefund.t.sol +++ b/test/solidity/Facets/CBridgeRefund.t.sol @@ -7,6 +7,7 @@ import { DiamondTest, LiFiDiamond } from "../utils/DiamondTest.sol"; import { Vm } from "forge-std/Vm.sol"; import { ERC20 } from "solmate/tokens/ERC20.sol"; import { WithdrawFacet } from "lifi/Facets/WithdrawFacet.sol"; +import { UnAuthorized, NotAContract } from "lifi/Errors/GenericErrors.sol"; // Test CBridge refund by forking polygon at 25085298 // Actual refund was processed at 25085299(Feb-18-2022 03:24:09 PM +UTC) @@ -27,6 +28,8 @@ contract CBridgeRefundTestPolygon is DSTest, DiamondTest { 0x3db00D1334B5faDd2A897D8A702cDCbb6F159D87; uint256 internal constant REFUND_AMOUNT = 92734538876076486098; + error WithdrawFailed(); + bytes internal CALLDATA; LiFiDiamond internal diamond; @@ -126,7 +129,11 @@ contract CBridgeRefundTestPolygon is DSTest, DiamondTest { /// @notice Fails to execute extra call and withdraw from non-owner. /// @dev It calls executeCallAndWithdraw from address that is not OWNER_ADDRESS. - function testFailExecuteCallAndWithdrawFromNonOwner() public { + function testRevert_NonOwnerCannotWithdrawFunds() public { + vm.startPrank(LIFI_ADDRESS); + + vm.expectRevert(UnAuthorized.selector); + withdrawFacet.executeCallAndWithdraw( payable(CBRIDGE_ADDRESS), CALLDATA, @@ -138,9 +145,13 @@ contract CBridgeRefundTestPolygon is DSTest, DiamondTest { /// @notice Fails to execute extra call and withdraw when callTo is invalid. /// @dev It tries to execute extra call at REFUND_ADDRESS instead of CBRIDGE_ADDRESS. - function testFailExecuteCallAndWithdraw() public { + function testRevert_FailsWhenCalledWithInvalidCallToAddress() public { + vm.startPrank(OWNER_ADDRESS); + + vm.expectRevert(NotAContract.selector); + withdrawFacet.executeCallAndWithdraw( - payable(REFUND_ADDRESS), + payable(REFUND_ADDRESS), //invalid callTo address CALLDATA, REFUND_ASSET, REFUND_ADDRESS, @@ -151,7 +162,7 @@ contract CBridgeRefundTestPolygon is DSTest, DiamondTest { /// @notice Fails to execute extra call and withdraw when refund is already processed. /// @dev It tries to withdraw multiple times. /// First withdraw should be success but second withdraw should be failed. - function testFailExecuteCallAndWithdrawMultiple() public { + function testRevert_RevertsIfRefundWasAlreadyProcessed() public { ERC20 asset = ERC20(REFUND_ASSET); uint256 assetBalance = asset.balanceOf(REFUND_ADDRESS); @@ -168,6 +179,8 @@ contract CBridgeRefundTestPolygon is DSTest, DiamondTest { asset.balanceOf(REFUND_ADDRESS) == assetBalance + REFUND_AMOUNT ); + vm.expectRevert(WithdrawFailed.selector); + withdrawFacet.executeCallAndWithdraw( payable(CBRIDGE_ADDRESS), CALLDATA, diff --git a/test/solidity/Facets/DexManagerFacet.t.sol b/test/solidity/Facets/DexManagerFacet.t.sol index 0ae6e6f18..840801d93 100644 --- a/test/solidity/Facets/DexManagerFacet.t.sol +++ b/test/solidity/Facets/DexManagerFacet.t.sol @@ -6,6 +6,7 @@ import { console } from "../utils/Console.sol"; import { DiamondTest, LiFiDiamond } from "../utils/DiamondTest.sol"; import { Vm } from "forge-std/Vm.sol"; import { DexManagerFacet } from "lifi/Facets/DexManagerFacet.sol"; +import { InvalidContract } from "lifi/Errors/GenericErrors.sol"; contract Foo {} @@ -111,27 +112,37 @@ contract DexManagerFacetTest is DSTest, DiamondTest { } } - function testFailAddZeroAddress() public { + function testRevert_CannotAddZeroAddress() public { + vm.expectRevert(InvalidContract.selector); + dexMgr.addDex(address(0)); } - function testFailAddNonContract() public { + function testRevert_CannotAddNonContract() public { + vm.expectRevert(InvalidContract.selector); + dexMgr.addDex(address(1337)); } - function testFailBatchAddZeroAddress() public { + function testRevert_CannotBatchAddZeroAddress() public { address[] memory dexs = new address[](3); dexs[0] = address(c1); dexs[1] = address(c2); dexs[2] = address(0); + + vm.expectRevert(InvalidContract.selector); + dexMgr.batchAddDex(dexs); } - function testFailBatchAddNonContract() public { + function testRevert_CannotBatchAddNonContract() public { address[] memory dexs = new address[](3); dexs[0] = address(c1); dexs[1] = address(c2); dexs[2] = address(1337); + + vm.expectRevert(InvalidContract.selector); + dexMgr.batchAddDex(dexs); } } diff --git a/test/solidity/Facets/OwnershipFacet.t.sol b/test/solidity/Facets/OwnershipFacet.t.sol index 388d0b29d..37809be8b 100644 --- a/test/solidity/Facets/OwnershipFacet.t.sol +++ b/test/solidity/Facets/OwnershipFacet.t.sol @@ -3,10 +3,16 @@ pragma solidity ^0.8.17; import { OwnershipFacet } from "lifi/Facets/OwnershipFacet.sol"; import { LibAllowList, LibSwap, TestBase, console, LiFiDiamond } from "../utils/TestBase.sol"; +import { OnlyContractOwner } from "lifi/Errors/GenericErrors.sol"; contract OwnershipFacetTest is TestBase { OwnershipFacet internal ownershipFacet; + error NoNullOwner(); + error NewOwnerMustNotBeSelf(); + error NoPendingOwnershipTransfer(); + error NotPendingOwner(); + function setUp() public { initTestBase(); @@ -15,34 +21,54 @@ contract OwnershipFacetTest is TestBase { function testOwnerCanTransferOwnership() public { address newOwner = address(0x1234567890123456789012345678901234567890); + ownershipFacet.transferOwnership(newOwner); + assert(ownershipFacet.owner() != newOwner); + vm.startPrank(newOwner); + ownershipFacet.confirmOwnershipTransfer(); + assert(ownershipFacet.owner() == newOwner); + vm.stopPrank(); } - function testFailNonOwnerCanTransferOwnership() public { + function testRevert_NonOwnerCannotTransferOwnership() public { address newOwner = address(0x1234567890123456789012345678901234567890); assert(ownershipFacet.owner() != newOwner); vm.prank(newOwner); + + vm.expectRevert(OnlyContractOwner.selector); + ownershipFacet.transferOwnership(newOwner); } - function testFailOnwershipTransferToNullAddr() public { - address newOwner = address(0x0); + function testRevert_CannotTransferOnwershipToNullAddr() public { + address newOwner = address(0); + + vm.expectRevert(NoNullOwner.selector); + ownershipFacet.transferOwnership(newOwner); } - function testFailOwnerCanConfirmPendingOwnershipTransfer() public { + function testRevert_PendingOwnershipTransferCannotBeConfirmedByNonNewOwner() + public + { address newOwner = address(0x1234567890123456789012345678901234567890); ownershipFacet.transferOwnership(newOwner); + + vm.expectRevert(NotPendingOwner.selector); + ownershipFacet.confirmOwnershipTransfer(); } - function testFailOwnershipTransferToSelf() public { + function testRevert_CannotTransferOwnershipToSelf() public { address newOwner = address(this); + + vm.expectRevert(NewOwnerMustNotBeSelf.selector); + ownershipFacet.transferOwnership(newOwner); } } diff --git a/test/solidity/Facets/RelayFacet.t.sol b/test/solidity/Facets/RelayFacet.t.sol index 21c64af4d..6da0edd98 100644 --- a/test/solidity/Facets/RelayFacet.t.sol +++ b/test/solidity/Facets/RelayFacet.t.sol @@ -654,14 +654,9 @@ contract RelayFacetTest is TestBaseFacet { vm.stopPrank(); } - function testFail_RevertIsBubbledWhenBridgingTokensFails() + function testRevert_RevertIsBubbledUpWhenBridgingERC20TokensFails() public virtual - assertBalanceChange( - ADDRESS_USDC, - USER_SENDER, - -int256(defaultUSDCAmount) - ) assertBalanceChange(ADDRESS_USDC, USER_RECEIVER, 0) assertBalanceChange(ADDRESS_DAI, USER_SENDER, 0) assertBalanceChange(ADDRESS_DAI, USER_RECEIVER, 0) @@ -681,19 +676,16 @@ contract RelayFacetTest is TestBaseFacet { "I always revert" ); - vm.expectRevert("I always revert"); + vm.expectRevert(); + initiateBridgeTxWithFacet(false); + vm.stopPrank(); } - function testFail_RevertIsBubbledWhenBridgingNativeTokensFails() + function testRevert_RevertIsBubbledUpWhenBridgingNativeTokensFails() public virtual - assertBalanceChange( - address(0), - USER_SENDER, - -int256((defaultNativeAmount + addToMessageValue)) - ) assertBalanceChange(address(0), USER_RECEIVER, 0) assertBalanceChange(ADDRESS_USDC, USER_SENDER, 0) assertBalanceChange(ADDRESS_DAI, USER_SENDER, 0) @@ -706,8 +698,10 @@ contract RelayFacetTest is TestBaseFacet { _makeRevertable(RELAY_RECEIVER); - vm.expectRevert("I always revert"); + vm.expectRevert(); + initiateBridgeTxWithFacet(true); + vm.stopPrank(); } diff --git a/test/solidity/Helpers/TransferrableOwnership.t.sol b/test/solidity/Helpers/TransferrableOwnership.t.sol index 6d1f445f5..e5a16983a 100644 --- a/test/solidity/Helpers/TransferrableOwnership.t.sol +++ b/test/solidity/Helpers/TransferrableOwnership.t.sol @@ -4,11 +4,17 @@ pragma solidity ^0.8.17; import { DSTest } from "ds-test/test.sol"; import { Vm } from "forge-std/Vm.sol"; import { TransferrableOwnership } from "lifi/Helpers/TransferrableOwnership.sol"; +import { OnlyContractOwner, UnAuthorized } from "lifi/Errors/GenericErrors.sol"; contract TransferrableOwnershipTest is DSTest { TransferrableOwnership internal ownable; Vm internal immutable vm = Vm(HEVM_ADDRESS); + error NoNullOwner(); + error NewOwnerMustNotBeSelf(); + error NoPendingOwnershipTransfer(); + error NotPendingOwner(); + function setUp() public { ownable = new TransferrableOwnership(address(this)); } @@ -23,26 +29,43 @@ contract TransferrableOwnershipTest is DSTest { vm.stopPrank(); } - function testFailNonOwnerCanTransferOwnership() public { + function testRevert_NonOwnerCannotTransferOwnership() public { address newOwner = address(0x1234567890123456789012345678901234567890); + assert(ownable.owner() != newOwner); + vm.prank(newOwner); + + vm.expectRevert(UnAuthorized.selector); + ownable.transferOwnership(newOwner); } - function testFailOnwershipTransferToNullAddr() public { - address newOwner = address(0x0); + function testRevert_CannotTransferOnwershipToNullAddr() public { + address newOwner = address(0); + + vm.expectRevert(NoNullOwner.selector); + ownable.transferOwnership(newOwner); } - function testFailOwnerCanConfirmPendingOwnershipTransfer() public { + function testRevert_PendingOwnershipTransferCannotBeConfirmedByNonNewOwner() + public + { address newOwner = address(0x1234567890123456789012345678901234567890); + ownable.transferOwnership(newOwner); + + vm.expectRevert(NotPendingOwner.selector); + ownable.confirmOwnershipTransfer(); } - function testFailOwnershipTransferToSelf() public { + function testRevert_CannotTransferOwnershipToSelf() public { address newOwner = address(this); + + vm.expectRevert(NewOwnerMustNotBeSelf.selector); + ownable.transferOwnership(newOwner); } } diff --git a/test/solidity/Periphery/Executor.t.sol b/test/solidity/Periphery/Executor.t.sol index a1c8652c6..704664c7b 100644 --- a/test/solidity/Periphery/Executor.t.sol +++ b/test/solidity/Periphery/Executor.t.sol @@ -6,11 +6,11 @@ import { console } from "../utils/Console.sol"; import { Vm } from "forge-std/Vm.sol"; import { Executor } from "lifi/Periphery/Executor.sol"; import { ERC20Proxy } from "lifi/Periphery/ERC20Proxy.sol"; -import { ILiFi } from "lifi/Interfaces/ILiFi.sol"; import { TestAMM } from "../utils/TestAMM.sol"; import { TestToken as ERC20 } from "../utils/TestToken.sol"; import { LibSwap } from "lifi/Libraries/LibSwap.sol"; import { UniswapV2Router02 } from "../utils/Interfaces.sol"; +import { UnAuthorized } from "lifi/Errors/GenericErrors.sol"; // Stub Vault Contract contract Vault { @@ -548,7 +548,7 @@ contract ExecutorTest is DSTest { assertEq(tokenD.balanceOf(address(vault)), 100 ether); } - function testFailWhenCallingERC20ProxyDirectly() public { + function testRevert_DoesNotAllowToCallERC20ProxyDirectly() public { ERC20 tokenA = new ERC20("Token A", "TOKA", 18); ERC20 tokenB = new ERC20("Token B", "TOKB", 18); @@ -556,8 +556,8 @@ contract ExecutorTest is DSTest { // Get some Token B swapData[0] = LibSwap.SwapData( - address(amm), - address(amm), + address(erc20Proxy), + address(erc20Proxy), address(tokenA), address(tokenB), 0.2 ether, @@ -573,6 +573,8 @@ contract ExecutorTest is DSTest { tokenA.mint(address(this), 1 ether); tokenA.approve(address(erc20Proxy), 1 ether); + vm.expectRevert(UnAuthorized.selector); + executor.swapAndExecute( "", swapData, diff --git a/test/solidity/Periphery/FeeCollector.t.sol b/test/solidity/Periphery/FeeCollector.t.sol index f30085145..99bb26314 100644 --- a/test/solidity/Periphery/FeeCollector.t.sol +++ b/test/solidity/Periphery/FeeCollector.t.sol @@ -6,6 +6,7 @@ import { console } from "../utils/Console.sol"; import { Vm } from "forge-std/Vm.sol"; import { FeeCollector } from "lifi/Periphery/FeeCollector.sol"; import { TestToken as ERC20 } from "../utils/TestToken.sol"; +import { UnAuthorized } from "lifi/Errors/GenericErrors.sol"; contract FeeCollectorTest is DSTest { Vm internal immutable vm = Vm(HEVM_ADDRESS); @@ -184,11 +185,14 @@ contract FeeCollectorTest is DSTest { assert(feeToken.balanceOf(address(feeCollector)) == 1 ether); } - function testFailWhenNonOwnerAttemptsToWithdrawLifiFees() public { + function testRevert_NonOwnerCannotWithdrawLifiFees() public { // Arrange uint256 integratorFee = 1 ether; uint256 lifiFee = 0.015 ether; + feeToken.approve(address(feeCollector), integratorFee + lifiFee); + + // make sure feeCollector has collected fees feeCollector.collectTokenFees( address(feeToken), integratorFee, @@ -198,20 +202,27 @@ contract FeeCollectorTest is DSTest { // Act vm.prank(address(0xb33f)); + + vm.expectRevert(UnAuthorized.selector); + feeCollector.withdrawLifiFees(address(feeToken)); } - function testFailWhenNonOwnerAttemptsToBatchWithdrawLifiFees() public { + function testRevert_NonOwnerCannotBatchWithdrawLifiFees() public { // Arranges.newOwner uint256 integratorFee = 1 ether; uint256 lifiFee = 0.015 ether; + feeToken.approve(address(feeCollector), integratorFee + lifiFee); + + // make sure feeCollector has collected fees feeCollector.collectTokenFees( address(feeToken), integratorFee, lifiFee, address(0xb33f) ); + feeCollector.collectNativeFees{ value: integratorFee + lifiFee }( integratorFee, lifiFee, @@ -222,7 +233,11 @@ contract FeeCollectorTest is DSTest { address[] memory tokens = new address[](2); tokens[0] = address(feeToken); tokens[1] = address(0); + vm.prank(address(0xb33f)); + + vm.expectRevert(UnAuthorized.selector); + feeCollector.batchWithdrawLifiFees(tokens); } @@ -236,26 +251,15 @@ contract FeeCollectorTest is DSTest { vm.stopPrank(); } - function testFailNonOwnerCanTransferOwnership() public { + function testRevert_NonOwnerCannotTransferOwnership() public { address newOwner = address(0x1234567890123456789012345678901234567890); + assert(feeCollector.owner() != newOwner); - vm.prank(newOwner); - feeCollector.transferOwnership(newOwner); - } - function testFailOnwershipTransferToNullAddr() public { - address newOwner = address(0x0); - feeCollector.transferOwnership(newOwner); - } + vm.prank(newOwner); - function testFailOwnerCanConfirmPendingOwnershipTransfer() public { - address newOwner = address(0x1234567890123456789012345678901234567890); - feeCollector.transferOwnership(newOwner); - feeCollector.confirmOwnershipTransfer(); - } + vm.expectRevert(UnAuthorized.selector); - function testFailOwnershipTransferToSelf() public { - address newOwner = address(this); feeCollector.transferOwnership(newOwner); } } From b1c9366a82e923bb0f632acb2bad51936310bdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Mon, 17 Feb 2025 15:57:27 +0700 Subject: [PATCH 4/7] added tests for DexManagerFacet --- test/solidity/Facets/DexManagerFacet.t.sol | 95 +++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/test/solidity/Facets/DexManagerFacet.t.sol b/test/solidity/Facets/DexManagerFacet.t.sol index 840801d93..ea4e1fd3d 100644 --- a/test/solidity/Facets/DexManagerFacet.t.sol +++ b/test/solidity/Facets/DexManagerFacet.t.sol @@ -6,7 +6,8 @@ import { console } from "../utils/Console.sol"; import { DiamondTest, LiFiDiamond } from "../utils/DiamondTest.sol"; import { Vm } from "forge-std/Vm.sol"; import { DexManagerFacet } from "lifi/Facets/DexManagerFacet.sol"; -import { InvalidContract } from "lifi/Errors/GenericErrors.sol"; +import { AccessManagerFacet } from "lifi/Facets/AccessManagerFacet.sol"; +import { InvalidContract, OnlyContractOwner, CannotAuthoriseSelf, UnAuthorized } from "lifi/Errors/GenericErrors.sol"; contract Foo {} @@ -16,6 +17,7 @@ contract DexManagerFacetTest is DSTest, DiamondTest { LiFiDiamond internal diamond; DexManagerFacet internal dexMgr; + AccessManagerFacet internal accessMgr; Foo internal c1; Foo internal c2; Foo internal c3; @@ -27,7 +29,7 @@ contract DexManagerFacetTest is DSTest, DiamondTest { c2 = new Foo(); c3 = new Foo(); - bytes4[] memory functionSelectors = new bytes4[](8); + bytes4[] memory functionSelectors = new bytes4[](9); functionSelectors[0] = DexManagerFacet.addDex.selector; functionSelectors[1] = DexManagerFacet.removeDex.selector; functionSelectors[2] = DexManagerFacet.batchAddDex.selector; @@ -43,6 +45,15 @@ contract DexManagerFacetTest is DSTest, DiamondTest { addFacet(diamond, address(dexMgr), functionSelectors); + // add AccessManagerFacet to be able to whitelist addresses for execution of protected functions + accessMgr = new AccessManagerFacet(); + + functionSelectors = new bytes4[](2); + functionSelectors[0] = accessMgr.setCanExecute.selector; + functionSelectors[1] = accessMgr.addressCanExecuteMethod.selector; + addFacet(diamond, address(accessMgr), functionSelectors); + + accessMgr = AccessManagerFacet(address(diamond)); dexMgr = DexManagerFacet(address(diamond)); vm.startPrank(USER_DIAMOND_OWNER); } @@ -118,6 +129,17 @@ contract DexManagerFacetTest is DSTest, DiamondTest { dexMgr.addDex(address(0)); } + function testRevert_NonOwnerCannotAddAddress() public { + vm.stopPrank(); + vm.startPrank(USER_PAUSER); // not the owner + + vm.expectRevert(UnAuthorized.selector); + + dexMgr.addDex(address(0)); + + vm.stopPrank(); + } + function testRevert_CannotAddNonContract() public { vm.expectRevert(InvalidContract.selector); @@ -135,6 +157,17 @@ contract DexManagerFacetTest is DSTest, DiamondTest { dexMgr.batchAddDex(dexs); } + function testRevert_CannotBatchAddSelf() public { + address[] memory dexs = new address[](3); + dexs[0] = address(c1); + dexs[1] = address(c2); + dexs[2] = address(dexMgr); + + vm.expectRevert(CannotAuthoriseSelf.selector); + + dexMgr.batchAddDex(dexs); + } + function testRevert_CannotBatchAddNonContract() public { address[] memory dexs = new address[](3); dexs[0] = address(c1); @@ -145,4 +178,62 @@ contract DexManagerFacetTest is DSTest, DiamondTest { dexMgr.batchAddDex(dexs); } + + function test_AllowsWhitelistedAddressToAddContract() public { + vm.stopPrank(); + vm.startPrank(USER_PAUSER); + vm.expectRevert(UnAuthorized.selector); + + dexMgr.addDex(address(c1)); + + // allow USER_PAUSER address to execute addDex() function + vm.startPrank(USER_DIAMOND_OWNER); + + accessMgr.setCanExecute( + DexManagerFacet.addDex.selector, + USER_PAUSER, + true + ); + + // try to call addDex() + vm.startPrank(USER_PAUSER); + + dexMgr.addDex(address(c1)); + + address[] memory approved = dexMgr.approvedDexs(); + + assertEq(approved[0], address(c1)); + } + + function test_AllowsWhitelistedAddressToBatchAddContract() public { + address[] memory dexs = new address[](2); + dexs[0] = address(c1); + dexs[1] = address(c2); + + vm.stopPrank(); + vm.startPrank(USER_PAUSER); + + vm.expectRevert(UnAuthorized.selector); + + dexMgr.batchAddDex(dexs); + + // allow USER_PAUSER address to execute batchAddDex() function + vm.startPrank(USER_DIAMOND_OWNER); + + accessMgr.setCanExecute( + DexManagerFacet.batchAddDex.selector, + USER_PAUSER, + true + ); + + // try to call addDex() + vm.startPrank(USER_PAUSER); + + dexMgr.batchAddDex(dexs); + + address[] memory approved = dexMgr.approvedDexs(); + + assertEq(approved[0], address(c1)); + assertEq(approved[1], address(c2)); + } } From 3550cd65ca60f8e6fb59ccabfd072a1dd7cabf8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Mon, 17 Feb 2025 15:58:08 +0700 Subject: [PATCH 5/7] added test for AcrossFacetV3 --- test/solidity/Facets/AcrossFacetV3.t.sol | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/solidity/Facets/AcrossFacetV3.t.sol b/test/solidity/Facets/AcrossFacetV3.t.sol index b5bad412c..40176db07 100644 --- a/test/solidity/Facets/AcrossFacetV3.t.sol +++ b/test/solidity/Facets/AcrossFacetV3.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: Unlicense pragma solidity ^0.8.17; -import { LibAllowList, TestBaseFacet, console, ERC20 } from "../utils/TestBaseFacet.sol"; +import { LibAllowList, TestBaseFacet, console } from "../utils/TestBaseFacet.sol"; import { AcrossFacetV3 } from "lifi/Facets/AcrossFacetV3.sol"; import { IAcrossSpokePool } from "lifi/Interfaces/IAcrossSpokePool.sol"; import { LibUtil } from "lifi/Libraries/LibUtil.sol"; import { LibSwap } from "lifi/Libraries/LibSwap.sol"; +import { InformationMismatch } from "lifi/Errors/GenericErrors.sol"; // Stub AcrossFacetV3 Contract contract TestAcrossFacetV3 is AcrossFacetV3 { @@ -275,4 +276,23 @@ contract AcrossFacetV3Test is TestBaseFacet { true ); } + + function testRevert_WillFailIfBridgeDataReceiverDoesNotMatchWithAcrossData() + public + { + vm.startPrank(USER_SENDER); + usdc.approve(address(acrossFacetV3), bridgeData.minAmount); + + validAcrossData.quoteTimestamp = uint32(block.timestamp - 100 days); + + bridgeData.receiver = USER_REFUND; // does not match with USER_RECEIVER + + vm.expectRevert(InformationMismatch.selector); + + acrossFacetV3.startBridgeTokensViaAcrossV3( + bridgeData, + validAcrossData + ); + vm.stopPrank(); + } } From d68e3f5ed5e29bad98c2fd4b79756e1a619ba4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Mon, 17 Feb 2025 17:05:18 +0700 Subject: [PATCH 6/7] add tests for ownershipfacet --- test/solidity/Facets/OwnershipFacet.t.sol | 62 ++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/test/solidity/Facets/OwnershipFacet.t.sol b/test/solidity/Facets/OwnershipFacet.t.sol index 37809be8b..87f15dac4 100644 --- a/test/solidity/Facets/OwnershipFacet.t.sol +++ b/test/solidity/Facets/OwnershipFacet.t.sol @@ -13,13 +13,73 @@ contract OwnershipFacetTest is TestBase { error NoPendingOwnershipTransfer(); error NotPendingOwner(); + event OwnershipTransferRequested( + address indexed _from, + address indexed _to + ); + + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + function setUp() public { initTestBase(); ownershipFacet = OwnershipFacet(address(diamond)); } - function testOwnerCanTransferOwnership() public { + function test_OwnerCanTransferOwnership() public { + vm.startPrank(USER_DIAMOND_OWNER); + + address newOwner = address(0x1234567890123456789012345678901234567890); + + vm.expectEmit(true, true, true, true, address(ownershipFacet)); + emit OwnershipTransferRequested(address(this), newOwner); + + ownershipFacet.transferOwnership(newOwner); + + assert(ownershipFacet.owner() != newOwner); + + vm.stopPrank(); + vm.startPrank(newOwner); + + vm.expectEmit(true, true, true, true, address(ownershipFacet)); + emit OwnershipTransferred(address(USER_DIAMOND_OWNER), newOwner); + + ownershipFacet.confirmOwnershipTransfer(); + + assert(ownershipFacet.owner() == newOwner); + + vm.stopPrank(); + } + + function testRevert_CannotCancelNonPendingOwnershipTransfer() public { + assert(ownershipFacet.owner() == USER_DIAMOND_OWNER); + vm.startPrank(USER_DIAMOND_OWNER); + + vm.expectRevert(NoPendingOwnershipTransfer.selector); + + ownershipFacet.cancelOwnershipTransfer(); + + assert(ownershipFacet.owner() == USER_DIAMOND_OWNER); + + vm.stopPrank(); + } + + function test_OwnerCanCancelOwnershipTransfer() public { + address newOwner = address(0x1234567890123456789012345678901234567890); + + ownershipFacet.transferOwnership(newOwner); + + assert(ownershipFacet.owner() != newOwner); + + ownershipFacet.cancelOwnershipTransfer(); + + assert(ownershipFacet.owner() != newOwner); + } + + function testRevert_NonOwnerCannotCancelOwnershipTransfer() public { address newOwner = address(0x1234567890123456789012345678901234567890); ownershipFacet.transferOwnership(newOwner); From 60ef907e422fe50e9915a946a11255825395fcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Bl=C3=A4cker?= Date: Mon, 17 Feb 2025 17:51:35 +0700 Subject: [PATCH 7/7] fix log file --- deployments/gnosis.diamond.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/deployments/gnosis.diamond.json b/deployments/gnosis.diamond.json index ad5e33aa8..e7f10a9ec 100644 --- a/deployments/gnosis.diamond.json +++ b/deployments/gnosis.diamond.json @@ -97,10 +97,6 @@ "Name": "GasZipFacet", "Version": "2.0.0" }, - "0x5656E307E4dEd573695Dd3eAC64EC4778F910DcA": { - "Name": "GasZipFacet", - "Version": "2.0.0" - }, "0x424BDbbaEda89732443fb1B737b6Dc194a6Ddbd5": { "Name": "RelayFacet", "Version": "1.0.0"