Skip to content

Commit b223f6c

Browse files
authored
feat(svm): svm-dev fixes from review (#727)
* refactor(svm): reuse bytes32 to address lib in svm adapter Signed-off-by: Pablo Maldonado <pablomaldonadoturci@gmail.com> * feat: custom errors Signed-off-by: Pablo Maldonado <pablomaldonadoturci@gmail.com> * feat: fix test Signed-off-by: Pablo Maldonado <pablomaldonadoturci@gmail.com> --------- Signed-off-by: Pablo Maldonado <pablomaldonadoturci@gmail.com>
1 parent 38be8e0 commit b223f6c

File tree

3 files changed

+24
-16
lines changed

3 files changed

+24
-16
lines changed

contracts/chain-adapters/Solana_Adapter.sol

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IMessageTransmitter, ITokenMessenger } from "../external/interfaces/CCT
55
import { SpokePoolInterface } from "../interfaces/SpokePoolInterface.sol";
66
import { AdapterInterface } from "./interfaces/AdapterInterface.sol";
77
import { CircleCCTPAdapter, CircleDomainIds } from "../libraries/CircleCCTPAdapter.sol";
8+
import { Bytes32ToAddress } from "../libraries/AddressConverters.sol";
89

910
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
1011

@@ -19,6 +20,14 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
1920

2021
// solhint-disable-next-line contract-name-camelcase
2122
contract Solana_Adapter is AdapterInterface, CircleCCTPAdapter {
23+
/**
24+
* @notice We use Bytes32ToAddress library to map a Solana address to an Ethereum address representation.
25+
* @dev The Ethereum address is derived from the Solana address by truncating it to its lowest 20 bytes. This same
26+
* conversion must be done by the HubPool owner when adding Solana spoke pool and setting the corresponding pool
27+
* rebalance and deposit routes.
28+
*/
29+
using Bytes32ToAddress for bytes32;
30+
2231
/**
2332
* @notice The official Circle CCTP MessageTransmitter contract endpoint.
2433
* @dev Posted officially here: https://developers.circle.com/stablecoins/docs/evm-smart-contracts
@@ -84,10 +93,10 @@ contract Solana_Adapter is AdapterInterface, CircleCCTPAdapter {
8493
cctpMessageTransmitter = _cctpMessageTransmitter;
8594

8695
SOLANA_SPOKE_POOL_BYTES32 = solanaSpokePool;
87-
SOLANA_SPOKE_POOL_ADDRESS = _trimSolanaAddress(solanaSpokePool);
96+
SOLANA_SPOKE_POOL_ADDRESS = solanaSpokePool.toAddressUnchecked();
8897

8998
SOLANA_USDC_BYTES32 = solanaUsdc;
90-
SOLANA_USDC_ADDRESS = _trimSolanaAddress(solanaUsdc);
99+
SOLANA_USDC_ADDRESS = solanaUsdc.toAddressUnchecked();
91100

92101
SOLANA_SPOKE_POOL_USDC_VAULT = solanaSpokePoolUsdcVault;
93102
}
@@ -151,18 +160,6 @@ contract Solana_Adapter is AdapterInterface, CircleCCTPAdapter {
151160
emit TokensRelayed(l1Token, l2Token, amount, to);
152161
}
153162

154-
/**
155-
* @notice Helper to map a Solana address to an Ethereum address representation.
156-
* @dev The Ethereum address is derived from the Solana address by truncating it to its lowest 20 bytes. This same
157-
* conversion must be done by the HubPool owner when adding Solana spoke pool and setting the corresponding pool
158-
* rebalance and deposit routes.
159-
* @param solanaAddress Solana address (Base58 decoded to bytes32) to map to its Ethereum address representation.
160-
* @return Ethereum address representation of the Solana address.
161-
*/
162-
function _trimSolanaAddress(bytes32 solanaAddress) internal pure returns (address) {
163-
return address(uint160(uint256(solanaAddress)));
164-
}
165-
166163
/**
167164
* @notice Translates a message to enable/disable a route on Solana spoke pool.
168165
* @param message Message to translate, expecting setEnableRoute(address,uint256,bool).

contracts/libraries/AddressConverters.sol

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22
pragma solidity ^0.8.0;
33

44
library Bytes32ToAddress {
5+
/**************************************
6+
* ERRORS *
7+
**************************************/
8+
error InvalidBytes32();
9+
510
function toAddress(bytes32 _bytes32) internal pure returns (address) {
6-
require(uint256(_bytes32) >> 192 == 0, "Invalid bytes32: highest 12 bytes must be 0");
11+
if (uint256(_bytes32) >> 192 != 0) {
12+
revert InvalidBytes32();
13+
}
14+
return address(uint160(uint256(_bytes32)));
15+
}
16+
17+
function toAddressUnchecked(bytes32 _bytes32) internal pure returns (address) {
718
return address(uint160(uint256(_bytes32)));
819
}
920
}

test/evm/hardhat/chain-adapters/Solana_Adapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe("Solana Chain Adapter", function () {
8787
const functionCallData = mockSpoke.interface.encodeFunctionData("setCrossDomainAdmin", [newAdmin]);
8888
expect(await hubPool.relaySpokePoolAdminFunction(solanaChainId, functionCallData))
8989
.to.emit(solanaAdapter.attach(hubPool.address), "MessageRelayed")
90-
.withArgs(solanaSpokePoolAddress, functionCallData);
90+
.withArgs(solanaSpokePoolAddress.toLowerCase(), functionCallData);
9191
expect(cctpMessageTransmitter.sendMessage).to.have.been.calledWith(
9292
solanaDomainId,
9393
solanaSpokePoolBytes32,

0 commit comments

Comments
 (0)