编译器
0.8.13+commit.abaa5c0e
文件 1 的 16:AccessControl.sol
pragma solidity 0.8.13;
import "./Ownable.sol";
abstract contract AccessControl is Ownable {
mapping(bytes32 => mapping(address => bool)) private _permits;
event RoleGranted(bytes32 indexed role, address indexed grantee);
event RoleRevoked(bytes32 indexed role, address indexed revokee);
error NoPermit(bytes32 role);
constructor(address owner_) Ownable(owner_) {}
modifier onlyRole(bytes32 role) {
if (!_permits[role][msg.sender]) revert NoPermit(role);
_;
}
function _checkRole(bytes32 role_, address address_) internal virtual {
if (!_hasRole(role_, address_)) revert NoPermit(role_);
}
function grantRole(
bytes32 role_,
address grantee_
) external virtual onlyOwner {
_grantRole(role_, grantee_);
}
function revokeRole(
bytes32 role_,
address revokee_
) external virtual onlyOwner {
_revokeRole(role_, revokee_);
}
function _grantRole(bytes32 role_, address grantee_) internal {
_permits[role_][grantee_] = true;
emit RoleGranted(role_, grantee_);
}
function _revokeRole(bytes32 role_, address revokee_) internal {
_permits[role_][revokee_] = false;
emit RoleRevoked(role_, revokee_);
}
function hasRole(
bytes32 role_,
address address_
) external view returns (bool) {
return _hasRole(role_, address_);
}
function _hasRole(
bytes32 role_,
address address_
) internal view returns (bool) {
return _permits[role_][address_];
}
}
文件 2 的 16:Base.sol
pragma solidity 0.8.13;
import {IMintableERC20} from "../interfaces/IMintableERC20.sol";
import {IConnector} from "../interfaces/IConnector.sol";
import "lib/solmate/src/utils/SafeTransferLib.sol";
import "../interfaces/IHook.sol";
import "../common/Errors.sol";
import "lib/solmate/src/utils/ReentrancyGuard.sol";
import "../interfaces/IBridge.sol";
import "../utils/RescueBase.sol";
import "../common/Constants.sol";
abstract contract Base is ReentrancyGuard, IBridge, RescueBase {
address public immutable token;
bytes32 public bridgeType;
IHook public hook__;
mapping(bytes32 => bytes) public identifierCache;
mapping(address => bytes) public connectorCache;
mapping(address => bool) public validConnectors;
event ConnectorStatusUpdated(address connector, bool status);
event HookUpdated(address newHook);
event BridgingTokens(
address connector,
address sender,
address receiver,
uint256 amount,
bytes32 messageId
);
event TokensBridged(
address connecter,
address receiver,
uint256 amount,
bytes32 messageId
);
constructor(address token_) AccessControl(msg.sender) {
if (token_ != ETH_ADDRESS && token_.code.length == 0)
revert InvalidTokenContract();
token = token_;
_grantRole(RESCUE_ROLE, msg.sender);
}
function updateHook(
address hook_,
bool approve_
) external virtual onlyOwner {
if (token != ETH_ADDRESS) {
if (ERC20(token).allowance(address(this), address(hook__)) > 0) {
SafeTransferLib.safeApprove(ERC20(token), address(hook__), 0);
}
if (approve_) {
SafeTransferLib.safeApprove(
ERC20(token),
hook_,
type(uint256).max
);
}
}
hook__ = IHook(hook_);
emit HookUpdated(hook_);
}
function updateConnectorStatus(
address[] calldata connectors,
bool[] calldata statuses
) external onlyOwner {
uint256 length = connectors.length;
for (uint256 i; i < length; i++) {
validConnectors[connectors[i]] = statuses[i];
emit ConnectorStatusUpdated(connectors[i], statuses[i]);
}
}
function _beforeBridge(
address connector_,
TransferInfo memory transferInfo_
)
internal
returns (TransferInfo memory transferInfo, bytes memory postHookData)
{
if (transferInfo_.receiver == address(0)) revert ZeroAddressReceiver();
if (!validConnectors[connector_]) revert InvalidConnector();
if (token == ETH_ADDRESS && msg.value < transferInfo_.amount)
revert InsufficientMsgValue();
if (address(hook__) != address(0)) {
(transferInfo, postHookData) = hook__.srcPreHookCall(
SrcPreHookCallParams(connector_, msg.sender, transferInfo_)
);
}
}
function _afterBridge(
uint256 msgGasLimit_,
address connector_,
bytes memory options_,
bytes memory postSrcHookData_,
TransferInfo memory transferInfo_
) internal {
TransferInfo memory transferInfo = transferInfo_;
if (address(hook__) != address(0)) {
transferInfo = hook__.srcPostHookCall(
SrcPostHookCallParams(
connector_,
options_,
postSrcHookData_,
transferInfo_
)
);
}
uint256 fees = token == ETH_ADDRESS
? msg.value - transferInfo.amount
: msg.value;
bytes32 messageId = IConnector(connector_).getMessageId();
bytes32 returnedMessageId = IConnector(connector_).outbound{
value: fees
}(
msgGasLimit_,
abi.encode(
transferInfo.receiver,
transferInfo.amount,
messageId,
transferInfo.data
),
options_
);
if (returnedMessageId != messageId) revert MessageIdMisMatched();
emit BridgingTokens(
connector_,
msg.sender,
transferInfo.receiver,
transferInfo.amount,
messageId
);
}
function _beforeMint(
uint32,
TransferInfo memory transferInfo_
)
internal
returns (bytes memory postHookData, TransferInfo memory transferInfo)
{
if (!validConnectors[msg.sender]) revert InvalidConnector();
if (
transferInfo_.receiver == address(this) ||
transferInfo_.receiver == token
) revert CannotTransferOrExecuteOnBridgeContracts();
if (address(hook__) != address(0)) {
(postHookData, transferInfo) = hook__.dstPreHookCall(
DstPreHookCallParams(
msg.sender,
connectorCache[msg.sender],
transferInfo_
)
);
}
}
function _afterMint(
uint256,
bytes32 messageId_,
bytes memory postHookData_,
TransferInfo memory transferInfo_
) internal {
if (address(hook__) != address(0)) {
CacheData memory cacheData = hook__.dstPostHookCall(
DstPostHookCallParams(
msg.sender,
messageId_,
connectorCache[msg.sender],
postHookData_,
transferInfo_
)
);
identifierCache[messageId_] = cacheData.identifierCache;
connectorCache[msg.sender] = cacheData.connectorCache;
}
emit TokensBridged(
msg.sender,
transferInfo_.receiver,
transferInfo_.amount,
messageId_
);
}
function _beforeRetry(
address connector_,
bytes32 messageId_
)
internal
returns (
bytes memory postRetryHookData,
TransferInfo memory transferInfo
)
{
if (!validConnectors[connector_]) revert InvalidConnector();
CacheData memory cacheData = CacheData(
identifierCache[messageId_],
connectorCache[connector_]
);
if (cacheData.identifierCache.length == 0) revert NoPendingData();
(postRetryHookData, transferInfo) = hook__.preRetryHook(
PreRetryHookCallParams(connector_, cacheData)
);
}
function _afterRetry(
address connector_,
bytes32 messageId_,
bytes memory postRetryHookData
) internal {
CacheData memory cacheData = CacheData(
identifierCache[messageId_],
connectorCache[connector_]
);
(cacheData) = hook__.postRetryHook(
PostRetryHookCallParams(
connector_,
messageId_,
postRetryHookData,
cacheData
)
);
identifierCache[messageId_] = cacheData.identifierCache;
connectorCache[connector_] = cacheData.connectorCache;
}
function getMinFees(
address connector_,
uint256 msgGasLimit_,
uint256 payloadSize_
) external view returns (uint256 totalFees) {
return IConnector(connector_).getMinFees(msgGasLimit_, payloadSize_);
}
}
文件 3 的 16:Constants.sol
pragma solidity 0.8.13;
address constant ETH_ADDRESS = address(
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
);
bytes32 constant NORMAL_CONTROLLER = keccak256("NORMAL_CONTROLLER");
bytes32 constant FIAT_TOKEN_CONTROLLER = keccak256("FIAT_TOKEN_CONTROLLER");
bytes32 constant LIMIT_HOOK = keccak256("LIMIT_HOOK");
bytes32 constant LIMIT_EXECUTION_HOOK = keccak256("LIMIT_EXECUTION_HOOK");
bytes32 constant LIMIT_EXECUTION_YIELD_HOOK = keccak256(
"LIMIT_EXECUTION_YIELD_HOOK"
);
bytes32 constant LIMIT_EXECUTION_YIELD_TOKEN_HOOK = keccak256(
"LIMIT_EXECUTION_YIELD_TOKEN_HOOK"
);
bytes32 constant ERC20_VAULT = keccak256("ERC20_VAULT");
bytes32 constant NATIVE_VAULT = keccak256("NATIVE_VAULT");
文件 4 的 16:ERC20.sol
pragma solidity >=0.8.0;
abstract contract ERC20 {
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
文件 5 的 16:Errors.sol
pragma solidity 0.8.13;
error SiblingNotSupported();
error NotAuthorized();
error NotBridge();
error NotSocket();
error ConnectorUnavailable();
error InvalidPoolId();
error CannotTransferOrExecuteOnBridgeContracts();
error NoPendingData();
error MessageIdMisMatched();
error NotMessageBridge();
error InvalidSiblingChainSlug();
error InvalidTokenContract();
error InvalidExchangeRateContract();
error InvalidConnector();
error InvalidConnectorPoolId();
error ZeroAddressReceiver();
error ZeroAddress();
error ZeroAmount();
error DebtRatioTooHigh();
error NotEnoughAssets();
error VaultShutdown();
error InsufficientFunds();
error PermitDeadlineExpired();
error InvalidSigner();
error InsufficientMsgValue();
文件 6 的 16:IBridge.sol
pragma solidity ^0.8.3;
interface IBridge {
function bridge(
address receiver_,
uint256 amount_,
uint256 msgGasLimit_,
address connector_,
bytes calldata execPayload_,
bytes calldata options_
) external payable;
function receiveInbound(
uint32 siblingChainSlug_,
bytes memory payload_
) external payable;
function retry(address connector_, bytes32 messageId_) external;
}
文件 7 的 16:IConnector.sol
pragma solidity ^0.8.13;
interface IConnector {
function outbound(
uint256 msgGasLimit_,
bytes memory payload_,
bytes memory options_
) external payable returns (bytes32 messageId_);
function siblingChainSlug() external view returns (uint32);
function getMinFees(
uint256 msgGasLimit_,
uint256 payloadSize_
) external view returns (uint256 totalFees);
function getMessageId() external view returns (bytes32);
}
文件 8 的 16:IHook.sol
pragma solidity ^0.8.3;
import "../common/Structs.sol";
interface IHook {
function srcPreHookCall(
SrcPreHookCallParams calldata params_
)
external
returns (
TransferInfo memory transferInfo,
bytes memory postSrcHookData
);
function srcPostHookCall(
SrcPostHookCallParams calldata params_
) external returns (TransferInfo memory transferInfo);
function dstPreHookCall(
DstPreHookCallParams calldata params_
)
external
returns (bytes memory postHookData, TransferInfo memory transferInfo);
function dstPostHookCall(
DstPostHookCallParams calldata params_
) external returns (CacheData memory cacheData);
function preRetryHook(
PreRetryHookCallParams calldata params_
)
external
returns (
bytes memory postRetryHookData,
TransferInfo memory transferInfo
);
function postRetryHook(
PostRetryHookCallParams calldata params_
) external returns (CacheData memory cacheData);
}
文件 9 的 16:IMintableERC20.sol
pragma solidity 0.8.13;
interface IMintableERC20 {
function mint(address receiver_, uint256 amount_) external;
function burn(address burner_, uint256 amount_) external;
}
文件 10 的 16:Ownable.sol
pragma solidity 0.8.13;
abstract contract Ownable {
address private _owner;
address private _nominee;
event OwnerNominated(address indexed nominee);
event OwnerClaimed(address indexed claimer);
error OnlyOwner();
error OnlyNominee();
constructor(address owner_) {
_claimOwner(owner_);
}
modifier onlyOwner() {
if (msg.sender != _owner) revert OnlyOwner();
_;
}
function owner() external view returns (address) {
return _owner;
}
function nominee() external view returns (address) {
return _nominee;
}
function nominateOwner(address nominee_) external {
if (msg.sender != _owner) revert OnlyOwner();
_nominee = nominee_;
emit OwnerNominated(_nominee);
}
function claimOwner() external {
if (msg.sender != _nominee) revert OnlyNominee();
_claimOwner(msg.sender);
}
function _claimOwner(address claimer_) internal {
_owner = claimer_;
_nominee = address(0);
emit OwnerClaimed(claimer_);
}
}
文件 11 的 16:ReentrancyGuard.sol
pragma solidity >=0.8.0;
abstract contract ReentrancyGuard {
uint256 private locked = 1;
modifier nonReentrant() virtual {
require(locked == 1, "REENTRANCY");
locked = 2;
_;
locked = 1;
}
}
文件 12 的 16:RescueBase.sol
pragma solidity 0.8.13;
import {RescueFundsLib} from "../libraries/RescueFundsLib.sol";
import {AccessControl} from "./AccessControl.sol";
abstract contract RescueBase is AccessControl {
bytes32 constant RESCUE_ROLE = keccak256("RESCUE_ROLE");
function rescueFunds(
address token_,
address rescueTo_,
uint256 amount_
) external onlyRole(RESCUE_ROLE) {
RescueFundsLib.rescueFunds(token_, rescueTo_, amount_);
}
}
文件 13 的 16:RescueFundsLib.sol
pragma solidity 0.8.13;
import "lib/solmate/src/utils/SafeTransferLib.sol";
import "lib/solmate/src/tokens/ERC20.sol";
error ZeroAddress();
library RescueFundsLib {
address public constant ETH_ADDRESS =
address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
error InvalidTokenAddress();
function rescueFunds(
address token_,
address rescueTo_,
uint256 amount_
) internal {
if (rescueTo_ == address(0)) revert ZeroAddress();
if (token_ == ETH_ADDRESS) {
SafeTransferLib.safeTransferETH(rescueTo_, amount_);
} else {
if (token_.code.length == 0) revert InvalidTokenAddress();
SafeTransferLib.safeTransfer(ERC20(token_), rescueTo_, amount_);
}
}
}
文件 14 的 16:SafeTransferLib.sol
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
library SafeTransferLib {
function safeTransferETH(address to, uint256 amount) internal {
bool success;
assembly {
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(freeMemoryPointer, 68), amount)
success := and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(freeMemoryPointer, 36), amount)
success := and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
assembly {
let freeMemoryPointer := mload(0x40)
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff))
mstore(add(freeMemoryPointer, 36), amount)
success := and(
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}
文件 15 的 16:Structs.sol
pragma solidity 0.8.13;
struct UpdateLimitParams {
bool isMint;
address connector;
uint256 maxLimit;
uint256 ratePerSecond;
}
struct SrcPreHookCallParams {
address connector;
address msgSender;
TransferInfo transferInfo;
}
struct SrcPostHookCallParams {
address connector;
bytes options;
bytes postSrcHookData;
TransferInfo transferInfo;
}
struct DstPreHookCallParams {
address connector;
bytes connectorCache;
TransferInfo transferInfo;
}
struct DstPostHookCallParams {
address connector;
bytes32 messageId;
bytes connectorCache;
bytes postHookData;
TransferInfo transferInfo;
}
struct PreRetryHookCallParams {
address connector;
CacheData cacheData;
}
struct PostRetryHookCallParams {
address connector;
bytes32 messageId;
bytes postRetryHookData;
CacheData cacheData;
}
struct TransferInfo {
address receiver;
uint256 amount;
bytes data;
}
struct CacheData {
bytes identifierCache;
bytes connectorCache;
}
struct LimitParams {
uint256 lastUpdateTimestamp;
uint256 ratePerSecond;
uint256 maxLimit;
uint256 lastUpdateLimit;
}
文件 16 的 16:Vault.sol
pragma solidity 0.8.13;
import "./Base.sol";
import "../interfaces/IConnector.sol";
import "lib/solmate/src/tokens/ERC20.sol";
contract Vault is Base {
using SafeTransferLib for ERC20;
constructor(address token_) Base(token_) {
bridgeType = token_ == ETH_ADDRESS ? NATIVE_VAULT : ERC20_VAULT;
}
function bridge(
address receiver_,
uint256 amount_,
uint256 msgGasLimit_,
address connector_,
bytes calldata execPayload_,
bytes calldata options_
) external payable nonReentrant {
(
TransferInfo memory transferInfo,
bytes memory postHookData
) = _beforeBridge(
connector_,
TransferInfo(receiver_, amount_, execPayload_)
);
_receiveTokens(transferInfo.amount);
_afterBridge(
msgGasLimit_,
connector_,
options_,
postHookData,
transferInfo
);
}
function receiveInbound(
uint32 siblingChainSlug_,
bytes memory payload_
) external payable override nonReentrant {
(
address receiver,
uint256 unlockAmount,
bytes32 messageId,
bytes memory extraData
) = abi.decode(payload_, (address, uint256, bytes32, bytes));
TransferInfo memory transferInfo = TransferInfo(
receiver,
unlockAmount,
extraData
);
bytes memory postHookData;
(postHookData, transferInfo) = _beforeMint(
siblingChainSlug_,
transferInfo
);
_transferTokens(transferInfo.receiver, transferInfo.amount);
_afterMint(unlockAmount, messageId, postHookData, transferInfo);
}
function retry(
address connector_,
bytes32 messageId_
) external nonReentrant {
(
bytes memory postRetryHookData,
TransferInfo memory transferInfo
) = _beforeRetry(connector_, messageId_);
_transferTokens(transferInfo.receiver, transferInfo.amount);
_afterRetry(connector_, messageId_, postRetryHookData);
}
function _transferTokens(address receiver_, uint256 amount_) internal {
if (amount_ == 0) return;
if (address(token) == ETH_ADDRESS) {
SafeTransferLib.safeTransferETH(receiver_, amount_);
} else {
ERC20(token).safeTransfer(receiver_, amount_);
}
}
function _receiveTokens(uint256 amount_) internal {
if (amount_ == 0 || address(token) == ETH_ADDRESS) return;
ERC20(token).safeTransferFrom(msg.sender, address(this), amount_);
}
}
{
"compilationTarget": {
"contracts/bridge/Vault.sol": "Vault"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotTransferOrExecuteOnBridgeContracts","type":"error"},{"inputs":[],"name":"InsufficientMsgValue","type":"error"},{"inputs":[],"name":"InvalidConnector","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"InvalidTokenContract","type":"error"},{"inputs":[],"name":"MessageIdMisMatched","type":"error"},{"inputs":[],"name":"NoPendingData","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"NoPermit","type":"error"},{"inputs":[],"name":"OnlyNominee","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAddressReceiver","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"connector","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"messageId","type":"bytes32"}],"name":"BridgingTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"connector","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ConnectorStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newHook","type":"address"}],"name":"HookUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"OwnerClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominee","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"grantee","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"revokee","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"connecter","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"messageId","type":"bytes32"}],"name":"TokensBridged","type":"event"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"msgGasLimit_","type":"uint256"},{"internalType":"address","name":"connector_","type":"address"},{"internalType":"bytes","name":"execPayload_","type":"bytes"},{"internalType":"bytes","name":"options_","type":"bytes"}],"name":"bridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bridgeType","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"connectorCache","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"connector_","type":"address"},{"internalType":"uint256","name":"msgGasLimit_","type":"uint256"},{"internalType":"uint256","name":"payloadSize_","type":"uint256"}],"name":"getMinFees","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"grantee_","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"address_","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hook__","outputs":[{"internalType":"contract IHook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"identifierCache","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nominee_","type":"address"}],"name":"nominateOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"siblingChainSlug_","type":"uint32"},{"internalType":"bytes","name":"payload_","type":"bytes"}],"name":"receiveInbound","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"rescueTo_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"connector_","type":"address"},{"internalType":"bytes32","name":"messageId_","type":"bytes32"}],"name":"retry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"revokee_","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"connectors","type":"address[]"},{"internalType":"bool[]","name":"statuses","type":"bool[]"}],"name":"updateConnectorStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hook_","type":"address"},{"internalType":"bool","name":"approve_","type":"bool"}],"name":"updateHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validConnectors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]