Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Hop use SSLOAD2 #618

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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 .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
[submodule "lib/sstore2"]
path = lib/sstore2
url = https://github.com/0xsequence/sstore2
[submodule "lib/create3"]
path = lib/create3
url = https://github.com/0xsequence/create3
1 change: 1 addition & 0 deletions lib/create3
Submodule create3 added at acc470
1 change: 1 addition & 0 deletions lib/sstore2
Submodule sstore2 added at 0a28fe
3 changes: 3 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ hardhat-deploy/=node_modules/hardhat-deploy/
celer-network/=lib/sgn-v2-contracts/
create3-factory/=lib/create3-factory/src/
solmate/=lib/solmate/src/
sstore2/=lib/sstore2/contracts
create3/=lib/create3/contracts
@0xsequence/create3/contracts/=lib/create3/contracts

ds-test/=lib/ds-test/src/
forge-std/=lib/forge-std/src/
Expand Down
34 changes: 10 additions & 24 deletions src/Facets/HopFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,17 @@ import { ReentrancyGuard } from "../Helpers/ReentrancyGuard.sol";
import { InvalidConfig, AlreadyInitialized, NotInitialized } from "../Errors/GenericErrors.sol";
import { SwapperV2, LibSwap } from "../Helpers/SwapperV2.sol";
import { Validatable } from "../Helpers/Validatable.sol";
import { SSTORE2 } from 'sstore2/SSTORE2.sol';
import { SSTORE2Map } from 'sstore2/SSTORE2Map.sol';

/// @title Hop Facet
/// @author LI.FI (https://li.fi)
/// @notice Provides functionality for bridging through Hop
/// @custom:version 2.0.0
contract HopFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {
/// Storage ///

bytes32 internal constant NAMESPACE = keccak256("com.lifi.facets.hop");

/// Types ///

struct Storage {
mapping(address => IHopBridge) bridges;
bool initialized; // no longer used but kept here to maintain the same storage layout
}

struct Config {
address assetId;
address bridge;
Expand Down Expand Up @@ -54,16 +48,17 @@ contract HopFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {
function initHop(Config[] calldata configs) external {
LibDiamond.enforceIsContractOwner();

Storage storage s = getStorage();

for (uint256 i = 0; i < configs.length; i++) {
if (configs[i].bridge == address(0)) {
revert InvalidConfig();
}
s.bridges[configs[i].assetId] = IHopBridge(configs[i].bridge);
string memory key = string(abi.encodePacked(configs[i].assetId));
bytes memory data = abi.encode(configs[i].bridge);
SSTORE2Map.write(key, data);
}

emit HopInitialized(configs);

}

/// External Methods ///
Expand All @@ -74,13 +69,13 @@ contract HopFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {
function registerBridge(address assetId, address bridge) external {
LibDiamond.enforceIsContractOwner();

Storage storage s = getStorage();

if (bridge == address(0)) {
revert InvalidConfig();
}

s.bridges[assetId] = IHopBridge(bridge);
string memory key = string(abi.encodePacked(assetId));
bytes memory data = abi.encode(bridge);
SSTORE2Map.write(key, data);

emit HopBridgeRegistered(assetId, bridge);
}
Expand Down Expand Up @@ -144,8 +139,7 @@ contract HopFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {
HopData calldata _hopData
) private {
address sendingAssetId = _bridgeData.sendingAssetId;
Storage storage s = getStorage();
IHopBridge bridge = s.bridges[sendingAssetId];
IHopBridge bridge = abi.decode(SSTORE2Map.read(string(abi.encodePacked(sendingAssetId))), (IHopBridge));

// Give Hop approval to bridge tokens
LibAsset.maxApproveERC20(
Expand Down Expand Up @@ -186,12 +180,4 @@ contract HopFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable {
emit LiFiTransferStarted(_bridgeData);
}

/// @dev fetch local storage
function getStorage() private pure returns (Storage storage s) {
bytes32 namespace = NAMESPACE;
// solhint-disable-next-line no-inline-assembly
assembly {
s.slot := namespace
}
}
}
4 changes: 2 additions & 2 deletions test/solidity/Facets/HopFacet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ contract HopFacetTest is TestBaseFacet {
vm.startPrank(USER_DIAMOND_OWNER);

vm.expectEmit(true, true, true, true, address(hopFacet));
emit HopBridgeRegistered(ADDRESS_USDC, NATIVE_BRIDGE);
emit HopBridgeRegistered(ADDRESS_WETH, NATIVE_BRIDGE);

hopFacet.registerBridge(ADDRESS_USDC, NATIVE_BRIDGE);
hopFacet.registerBridge(ADDRESS_WETH, NATIVE_BRIDGE);
}

function testRevert_RegisterBridgeNonOwner() public {
Expand Down
Loading