Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BridgeWorkflow
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {IERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/utils/SafeERC20.sol";
import {IBridge} from "@kinto-core/interfaces/bridger/IBridge.sol";
import {IAccessPoint} from "@kinto-core/interfaces/IAccessPoint.sol";
import {IBridger} from "@kinto-core/interfaces/bridger/IBridger.sol";
contract BridgeWorkflow {
using SafeERC20 for IERC20;
/**
* @notice Emitted when a bridge operation is made.
* @param wallet The address of the Kinto wallet on L2.
* @param asset The address of the input asset.
* @param amount The amount of the input asset.
*/
event Bridged(address indexed wallet, address indexed asset, uint256 amount);
IBridger public immutable bridger;
constructor(IBridger bridger_) {
bridger = bridger_;
}
function bridge(address asset, uint256 amount, address wallet, IBridger.BridgeData calldata bridgeData)
external
payable
{
if (bridger.bridgeVaults(bridgeData.vault) == false) revert IBridger.InvalidVault(bridgeData.vault);
if (amount == 0) {
amount = IERC20(asset).balanceOf(address(this));
}
// Approve max allowance to save on gas for future transfers
if (IERC20(asset).allowance(address(this), bridgeData.vault) < amount) {
IERC20(asset).forceApprove(bridgeData.vault, type(uint256).max);
}
// Bridge the amount to Kinto
// slither-disable-next-line arbitrary-send-eth
IBridge(bridgeData.vault).bridge{value: bridgeData.gasFee}(
wallet, amount, bridgeData.msgGasLimit, bridgeData.connector, bridgeData.execPayload, bridgeData.options
);
emit Bridged(wallet, asset, amount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
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;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "./IAccessRegistry.sol";
interface IAccessPoint {
/* ============ Errors ============ */
/// @notice Thrown when calldata for then execute is mallformed.
error ExecuteInvalidInput();
/// @notice Thrown when a target contract reverts without a specified reason.
error ExecutionReverted();
/// @notice Thrown when an unauthorized workflow is invoked.
error WorkflowUnauthorized(address target);
/// @notice Thrown when an unauthorized account tries to execute a delegate call.
error ExecutionUnauthorized(address owner, address caller);
/// @notice Thrown when a fallback called.
error FallbackIsNotAllowed(bytes data);
/// @notice Thrown when a non-contract address is passed as the target.
error TargetNotContract(address target);
/* ============ Events ============ */
/// @notice Emitted when a target contract is delegate called.
event Execute(address indexed target, bytes data, bytes response);
/* ============ View functions ============ */
/// @notice The address of the owner account or contract, which controls the access point.
function owner() external view returns (address);
/// @notice The address of the registry that has deployed this access point.
function registry() external view returns (IAccessRegistry);
/// @notice
function getNonce() external view returns (uint256);
/* ============ State Change ============ */
/// @notice
function initialize(address owner_) external;
/**
* @notice Delegate calls to the provided target contract by forwarding the data. It returns the data it
* gets back, and bubbles up any potential revert.
*
* @dev Emits an {Execute} event.
*
* Requirements:
* - The caller must be either the owner or an envoy with permission.
* - `target` must be a contract.
*
* @param target The address of the target contract.
* @param data Function selector plus ABI encoded data.
* @return response The response received from the target contract, if any.
*/
function execute(address target, bytes calldata data) external payable returns (bytes memory response);
/**
* @notice Delegate calls to the provided target contract by forwarding the data. It returns the data it
* gets back, and bubbles up any potential revert.
*/
function executeBatch(address[] calldata target, bytes[] calldata data)
external
payable
returns (bytes[] memory response);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol";
/**
* @title IDAI
* @notice Interface for DAI token operations.
*/
interface IDAI {
/**
* @notice Permit the spender to spend the specified amount of tokens on behalf of the owner.
* @param holder The address of the token holder.
* @param spender The address of the spender.
* @param nonce The current nonce of the token holder.
* @param expiry The timestamp at which the permit expires.
* @param allowed Whether the spender is allowed to spend the tokens.
* @param v The recovery byte of the signature.
* @param r Half of the ECDSA signature pair.
* @param s Half of the ECDSA signature pair.
*/
function permit(
address holder,
address spender,
uint256 nonce,
uint256 expiry,
bool allowed,
uint8 v,
bytes32 r,
bytes32 s
) external;
}
/**
* @title IsUSDe
* @notice Interface for sUSDe token operations.
*/
interface IsUSDe is IERC20 {
/**
* @notice Deposit USDe tokens and receive sUSDe tokens.
* @param amount Amount of USDe tokens to deposit.
* @param recipient Address to receive the sUSDe tokens.
* @return Amount of sUSDe tokens received.
*/
function deposit(uint256 amount, address recipient) external returns (uint256);
}
/**
* @title IBridger
* @notice Interface for Bridger contract operations.
*/
interface IBridger {
/* ============ Errors ============ */
/// @notice Only the owner can call this function.
error OnlyOwner();
/// @notice The signature has expired.
error SignatureExpired();
/// @notice The nonce is invalid.
error InvalidNonce();
/// @notice The vault is not permitted.
error InvalidVault(address vault);
/// @notice The signer is invalid.
/// @param signer The signer.
error InvalidSigner(address signer);
/// @notice The amount is invalid.
/// @param amount The invalid amount.
error InvalidAmount(uint256 amount);
/// @notice Failed to stake ETH.
error FailedToStakeEth();
/// @notice Slippage error occurred.
/// @param boughtAmount The amount bought.
/// @param minReceive The minimum amount to receive.
error SlippageError(uint256 boughtAmount, uint256 minReceive);
/// @notice Returns the amount of final asset to deposit.
/// @param amountOut The amount to deposit.
error DepositBySigResult(uint256 amountOut);
/* ============ Structs ============ */
/**
* @title SignatureData
* @notice Struct to hold signature data for deposits.
*/
struct SignatureData {
/// @notice Kinto Wallet Address on L2 where tokens will be deposited.
address kintoWallet;
/// @notice Address of the signer.
address signer;
/// @notice Address of the input asset.
address inputAsset;
/// @notice Address of the final asset.
address finalAsset;
/// @notice Amount of the input asset.
uint256 amount;
/// @notice Minimum amount of finalAsset to receive.
uint256 minReceive;
/// @notice Nonce for replay protection.
uint256 nonce;
/// @notice Expiration time of the signature.
uint256 expiresAt;
/// @notice Signature to be verified.
bytes signature;
}
/**
* @title Permit
* @notice Struct to hold permit data.
*/
struct Permit {
/// @notice Address of the owner.
address owner;
/// @notice Address of the spender.
address spender;
/// @notice Value to be spent.
uint256 value;
/// @notice Nonce for replay protection.
uint256 nonce;
/// @notice Deadline for the permit.
uint256 deadline;
}
/**
* @title BridgeData
* @notice Struct to hold bridge data.
*/
struct BridgeData {
/// @notice Address of the vault.
address vault;
/// @notice Gas fee for the bridge.
uint256 gasFee;
/// @notice Gas limit for the message.
uint256 msgGasLimit;
/// @notice Address of the connector.
address connector;
/// @notice Execution payload for the bridge.
bytes execPayload;
/// @notice Options for the bridge.
bytes options;
}
/* ============ State Change ============ */
/**
* @notice Deposits the specified amount of tokens into the Kinto L2.
* @param permitSignature Signature for permit.
* @param signatureData Data for the deposit.
* @param swapCallData Data required for the swap.
* @param bridgeData Data required for the bridge.
* @return The amount of the final asset deposited.
*/
function depositBySig(
bytes calldata permitSignature,
IBridger.SignatureData calldata signatureData,
bytes calldata swapCallData,
BridgeData calldata bridgeData
) external payable returns (uint256);
/**
* @notice Deposits the specified amount of tokens into the Kinto L2.
* @param permitSingle Signature data for permit2.
* @param permit2Signature Signature for permit2.
* @param depositData Data for the deposit.
* @param swapCallData Data required for the swap.
* @param bridgeData Data required for the bridge.
* @return The amount of the final asset deposited.
*/
function depositPermit2(
IAllowanceTransfer.PermitSingle calldata permitSingle,
bytes calldata permit2Signature,
IBridger.SignatureData calldata depositData,
bytes calldata swapCallData,
BridgeData calldata bridgeData
) external payable returns (uint256);
/**
* @notice Deposits the specified amount of ERC20 tokens into the Kinto L2.
* @param inputAsset Address of the input asset.
* @param amount Amount of the input asset.
* @param kintoWallet Kinto Wallet Address on L2 where tokens will be deposited.
* @param finalAsset Address of the final asset.
* @param minReceive Minimum amount to receive after swap.
* @param swapCallData Data required for the swap.
* @param bridgeData Data required for the bridge.
* @return The amount of the final asset deposited.
*/
function depositERC20(
address inputAsset,
uint256 amount,
address kintoWallet,
address finalAsset,
uint256 minReceive,
bytes calldata swapCallData,
BridgeData calldata bridgeData
) external payable returns (uint256);
/**
* @notice Deposits the specified amount of ETH into the Kinto L2 as the final asset.
* @param amount Amount of ETH to deposit.
* @param kintoWallet Kinto Wallet Address on L2 where tokens will be deposited.
* @param finalAsset Address of the final asset.
* @param minReceive Minimum amount to receive after swap.
* @param swapCallData Data required for the swap.
* @param bridgeData Data required for the bridge.
* @return The amount of the final asset deposited.
*/
function depositETH(
uint256 amount,
address kintoWallet,
address finalAsset,
uint256 minReceive,
bytes calldata swapCallData,
BridgeData calldata bridgeData
) external payable returns (uint256);
/**
* @notice Pause the contract.
*/
function pause() external;
/**
* @notice Unpause the contract.
*/
function unpause() external;
/**
* @notice Set the sender account.
* @param senderAccount Address of the sender account.
*/
function setSenderAccount(address senderAccount) external;
/**
* @notice Enables the vault contract for bridge operations.
* @param vault Address of the sender account.
* @param flag True to enable, false to disable.
*/
function setBridgeVault(address vault, bool flag) external;
/* ============ View ============ */
/**
* @notice Get the nonce for an account.
* @param account Address of the account.
* @return Nonce of the account.
*/
function nonces(address account) external view returns (uint256);
/**
* @notice Get the domain separator.
* @return Domain separator.
*/
function domainSeparator() external view returns (bytes32);
/**
* @notice Get the sender account address.
* @return Sender account address.
*/
function senderAccount() external view returns (address);
/**
* @notice Get the swap router address.
* @return Swap router address.
*/
function swapRouter() external view returns (address);
/**
* @notice Check if the vault is registered.
* @return True if registered.
*/
function bridgeVaults(address vault) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {IAccessPoint} from "./IAccessPoint.sol";
import {UpgradeableBeacon} from "@openzeppelin-5.0.1/contracts/proxy/beacon/UpgradeableBeacon.sol";
/**
* @title Access Registry Interface
* @notice Manages and deploys new proxy contracts using CREATE2, maintaining a registry linking owners to proxies.
* Each owner can only have one proxy, which is non-transferable.
*/
interface IAccessRegistry {
/* ============ Errors ============ */
/// @notice Thrown when a target workflow is already disallowed.
error WorkflowAlreadyDisallowed(address workflow);
/// @notice Thrown when a target workflow is already allowed.
error WorkflowAlreadyAllowed(address workflow);
/// @notice Thrown when a function requires the user to have a accessPoint.
error UserDoesNotHaveAccessPoint(address user);
/// @notice Thrown when a function requires the user to not have a accessPoint.
error UserHasAccessPoint(address user, IAccessPoint accessPoint);
/* ============ Events ============ */
/// @notice Emitted when a workflow's allowance status is changed.
event WorkflowStatusChanged(address indexed workflow, bool indexed status);
/// @notice Emitted when the access point factory is upgraded.
event AccessPointFactoryUpgraded(address indexed beacon, address indexed newAccessPoint);
/// @notice Emitted when a new access point is deployed for a user.
event DeployAccessPoint(address indexed operator, address indexed owner, IAccessPoint accessPoint);
/* ============ View Functions ============ */
/// @notice Checks if a workflow is currently allowed.
/// @param workflow The address of the workflow to check.
/// @return status True if the workflow is allowed, false otherwise.
function isWorkflowAllowed(address workflow) external view returns (bool status);
/// @notice Retrieves the access point associated with a user.
/// @param user The user address for which to retrieve the access point.
/// @return accessPoint The access point associated with the user.
function getAccessPoint(address user) external view returns (IAccessPoint accessPoint);
/**
* @notice Calculates the address of a proxy that could be deployed via `deployFor`.
* @param owner The owner address for which to calculate the proxy address.
* @return The address of the proxy.
*/
function getAddress(address owner) external view returns (address);
/**
* @notice Calculates the address of a proxy that could be deployed with a specified salt.
* @param owner The owner address for which to calculate the proxy address.
* @param salt The salt to use in the CREATE2 deployment process.
* @return The address of the proxy.
*/
function getAddress(address owner, uint256 salt) external view returns (address);
/// @notice Retrieves the beacon contract used for proxy upgrades.
/// @return The beacon contract used for upgrades.
function beacon() external view returns (UpgradeableBeacon);
/// @notice Retrieves the version number of the Acesss Point.
/// @return The factory version as a uint256.
function accessPointVersion() external view returns (uint256);
/* ============ State Change Functions ============ */
/// @notice Disallows a specified workflow.
/// @param workflow The address of the workflow to disallow.
function disallowWorkflow(address workflow) external;
/// @notice Allows a specified workflow.
/// @param workflow The address of the workflow to allow.
function allowWorkflow(address workflow) external;
/// @notice Upgrades all deployed access points to a new implementation.
/// @param newImplementation The new access point implementation to upgrade to.
function upgradeAll(IAccessPoint newImplementation) external;
/// @notice Deploys a new access point for the specified user.
/// @param user The address that will own the new access point.
/// @return accessPoint The address of the newly deployed access point.
function deployFor(address user) external returns (IAccessPoint accessPoint);
/// @notice Creates a new access point account for the specified owner using a salt for deterministic deployment.
/// @param owner The address that will own the new access point.
/// @param salt The salt to use in the CREATE2 deployment process.
/// @return accessPoint The address of the newly created access point account.
function createAccount(address owner, uint256 salt) external returns (IAccessPoint accessPoint);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IEIP712} from "./IEIP712.sol";
/// @title AllowanceTransfer
/// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts
/// @dev Requires user's token approval on the Permit2 contract
interface IAllowanceTransfer is IEIP712 {
/// @notice Thrown when an allowance on a token has expired.
/// @param deadline The timestamp at which the allowed amount is no longer valid
error AllowanceExpired(uint256 deadline);
/// @notice Thrown when an allowance on a token has been depleted.
/// @param amount The maximum amount allowed
error InsufficientAllowance(uint256 amount);
/// @notice Thrown when too many nonces are invalidated.
error ExcessiveInvalidation();
/// @notice Emits an event when the owner successfully invalidates an ordered nonce.
event NonceInvalidation(
address indexed owner, address indexed token, address indexed spender, uint48 newNonce, uint48 oldNonce
);
/// @notice Emits an event when the owner successfully sets permissions on a token for the spender.
event Approval(
address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration
);
/// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender.
event Permit(
address indexed owner,
address indexed token,
address indexed spender,
uint160 amount,
uint48 expiration,
uint48 nonce
);
/// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function.
event Lockdown(address indexed owner, address token, address spender);
/// @notice The permit data for a token
struct PermitDetails {
// ERC20 token address
address token;
// the maximum amount allowed to spend
uint160 amount;
// timestamp at which a spender's token allowances become invalid
uint48 expiration;
// an incrementing value indexed per owner,token,and spender for each signature
uint48 nonce;
}
/// @notice The permit message signed for a single token allowance
struct PermitSingle {
// the permit data for a single token alownce
PermitDetails details;
// address permissioned on the allowed tokens
address spender;
// deadline on the permit signature
uint256 sigDeadline;
}
/// @notice The permit message signed for multiple token allowances
struct PermitBatch {
// the permit data for multiple token allowances
PermitDetails[] details;
// address permissioned on the allowed tokens
address spender;
// deadline on the permit signature
uint256 sigDeadline;
}
/// @notice The saved permissions
/// @dev This info is saved per owner, per token, per spender and all signed over in the permit message
/// @dev Setting amount to type(uint160).max sets an unlimited approval
struct PackedAllowance {
// amount allowed
uint160 amount;
// permission expiry
uint48 expiration;
// an incrementing value indexed per owner,token,and spender for each signature
uint48 nonce;
}
/// @notice A token spender pair.
struct TokenSpenderPair {
// the token the spender is approved
address token;
// the spender address
address spender;
}
/// @notice Details for a token transfer.
struct AllowanceTransferDetails {
// the owner of the token
address from;
// the recipient of the token
address to;
// the amount of the token
uint160 amount;
// the token to be transferred
address token;
}
/// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval.
/// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress]
/// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals.
function allowance(address user, address token, address spender)
external
view
returns (uint160 amount, uint48 expiration, uint48 nonce);
/// @notice Approves the spender to use up to amount of the specified token up until the expiration
/// @param token The token to approve
/// @param spender The spender address to approve
/// @param amount The approved amount of the token
/// @param expiration The timestamp at which the approval is no longer valid
/// @dev The packed allowance also holds a nonce, which will stay unchanged in approve
/// @dev Setting amount to type(uint160).max sets an unlimited approval
function approve(address token, address spender, uint160 amount, uint48 expiration) external;
/// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature
/// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce
/// @param owner The owner of the tokens being approved
/// @param permitSingle Data signed over by the owner specifying the terms of approval
/// @param signature The owner's signature over the permit data
function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external;
/// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature
/// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce
/// @param owner The owner of the tokens being approved
/// @param permitBatch Data signed over by the owner specifying the terms of approval
/// @param signature The owner's signature over the permit data
function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external;
/// @notice Transfer approved tokens from one address to another
/// @param from The address to transfer from
/// @param to The address of the recipient
/// @param amount The amount of the token to transfer
/// @param token The token address to transfer
/// @dev Requires the from address to have approved at least the desired amount
/// of tokens to msg.sender.
function transferFrom(address from, address to, uint160 amount, address token) external;
/// @notice Transfer approved tokens in a batch
/// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers
/// @dev Requires the from addresses to have approved at least the desired amount
/// of tokens to msg.sender.
function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external;
/// @notice Enables performing a "lockdown" of the sender's Permit2 identity
/// by batch revoking approvals
/// @param approvals Array of approvals to revoke.
function lockdown(TokenSpenderPair[] calldata approvals) external;
/// @notice Invalidate nonces for a given (token, spender) pair
/// @param token The token to invalidate nonces for
/// @param spender The spender to invalidate nonces for
/// @param newNonce The new nonce to set. Invalidates all nonces less than it.
/// @dev Can't invalidate more than 2**16 nonces per transaction.
function invalidateNonces(address token, address spender, uint48 newNonce) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/UpgradeableBeacon.sol)
pragma solidity ^0.8.20;
import {IBeacon} from "./IBeacon.sol";
import {Ownable} from "../../access/Ownable.sol";
/**
* @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
* implementation contract, which is where they will delegate all function calls.
*
* An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
*/
contract UpgradeableBeacon is IBeacon, Ownable {
address private _implementation;
/**
* @dev The `implementation` of the beacon is invalid.
*/
error BeaconInvalidImplementation(address implementation);
/**
* @dev Emitted when the implementation returned by the beacon is changed.
*/
event Upgraded(address indexed implementation);
/**
* @dev Sets the address of the initial implementation, and the initial owner who can upgrade the beacon.
*/
constructor(address implementation_, address initialOwner) Ownable(initialOwner) {
_setImplementation(implementation_);
}
/**
* @dev Returns the current implementation address.
*/
function implementation() public view virtual returns (address) {
return _implementation;
}
/**
* @dev Upgrades the beacon to a new implementation.
*
* Emits an {Upgraded} event.
*
* Requirements:
*
* - msg.sender must be the owner of the contract.
* - `newImplementation` must be a contract.
*/
function upgradeTo(address newImplementation) public virtual onlyOwner {
_setImplementation(newImplementation);
}
/**
* @dev Sets the implementation contract address for this beacon
*
* Requirements:
*
* - `newImplementation` must be a contract.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert BeaconInvalidImplementation(newImplementation);
}
_implementation = newImplementation;
emit Upgraded(newImplementation);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IEIP712 {
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.20;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}{
"remappings": [
"node_modules/account-abstraction-0.7.0:@openzeppelin/contracts/=node_modules/openzeppelin-contracts-5.0.1/",
"@aa-v7/=node_modules/account-abstraction-0.7.0/contracts/",
"ds-test/=node_modules/forge-std/lib/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"@kinto-core-script/=script/",
"@kinto-core-test/=test/",
"@kinto-core/=src/",
"@openzeppelin-5.0.1/contracts/=node_modules/openzeppelin-contracts-5.0.1/",
"node_modules/openzeppelin-contracts-upgradeable-5.0.1:@openzeppelin/contracts/=node_modules/openzeppelin-contracts-5.0.1/",
"@openzeppelin-5.0.1/contracts-upgradeable/=node_modules/openzeppelin-contracts-upgradeable-5.0.1/",
"@openzeppelin/contracts/=node_modules/openzeppelin-contracts/",
"@openzeppelin/contracts-upgradeable/=node_modules/openzeppelin-contracts-upgradeable/",
"node_modules/account-abstraction:@openzeppelin/contracts/=node_modules/openzeppelin-contracts/",
"@aa/=node_modules/account-abstraction/contracts/",
"@solady/=node_modules/solady/src/",
"solady/=node_modules/solady/src/",
"@token-bridge-contracts/=node_modules/token-bridge-contracts/",
"@arbitrum/nitro-contracts/=node_modules/nitro-contracts/",
"@alto/=node_modules/alto/contracts/",
"permit2/=node_modules/permit2/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IBridger","name":"bridger_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"InvalidVault","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Bridged","type":"event"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"},{"components":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"gasFee","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"}],"internalType":"struct IBridger.BridgeData","name":"bridgeData","type":"tuple"}],"name":"bridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bridger","outputs":[{"internalType":"contract IBridger","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405234801561001057600080fd5b5060405161094238038061094283398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516108b26100906000396000818160550152609d01526108b26000f3fe6080604052600436106100295760003560e01c80633be9a30a1461002e5780634d47fc8514610043575b600080fd5b61004161003c3660046106b6565b610093565b005b34801561004f57600080fd5b506100777f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200160405180910390f35b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663294218356100cf6020840184610723565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610113573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610137919061073e565b15156000036101775761014d6020820182610723565b6040516357b980d760e11b81526001600160a01b0390911660048201526024015b60405180910390fd5b826000036101ea576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa1580156101c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e79190610760565b92505b826001600160a01b03851663dd62ed3e306102086020860186610723565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102779190610760565b10156102a0576102a061028d6020830183610723565b6001600160a01b03861690600019610399565b6102ad6020820182610723565b6001600160a01b031663405e720a6020830135848660408601356102d76080880160608901610723565b6102e46080890189610779565b6102f160a08b018b610779565b6040518a63ffffffff1660e01b81526004016103149897969594939291906107f0565b6000604051808303818588803b15801561032d57600080fd5b505af1158015610341573d6000803e3d6000fd5b5050505050836001600160a01b0316826001600160a01b03167f443b8dd22f57096a1fb621c5ff3e8c3a9a3a5b90236c81dacc0df9b9b6014c758560405161038b91815260200190565b60405180910390a350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526103ea8482610453565b61044d57604080516001600160a01b038516602482015260006044808301919091528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526104439085906104fb565b61044d84826104fb565b50505050565b6000806000846001600160a01b031684604051610470919061084d565b6000604051808303816000865af19150503d80600081146104ad576040519150601f19603f3d011682016040523d82523d6000602084013e6104b2565b606091505b50915091508180156104dc5750805115806104dc5750808060200190518101906104dc919061073e565b80156104f257506000856001600160a01b03163b115b95945050505050565b60006105106001600160a01b03841683610563565b90508051600014158015610535575080806020019051810190610533919061073e565b155b1561055e57604051635274afe760e01b81526001600160a01b038416600482015260240161016e565b505050565b606061057183836000610578565b9392505050565b60608147101561059d5760405163cd78605960e01b815230600482015260240161016e565b600080856001600160a01b031684866040516105b9919061084d565b60006040518083038185875af1925050503d80600081146105f6576040519150601f19603f3d011682016040523d82523d6000602084013e6105fb565b606091505b509150915061060b868383610615565b9695505050505050565b60608261062a5761062582610671565b610571565b815115801561064157506001600160a01b0384163b155b1561066a57604051639996b31560e01b81526001600160a01b038516600482015260240161016e565b5080610571565b8051156106815780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b03811681146106b157600080fd5b919050565b600080600080608085870312156106cc57600080fd5b6106d58561069a565b9350602085013592506106ea6040860161069a565b9150606085013567ffffffffffffffff81111561070657600080fd5b850160c0818803121561071857600080fd5b939692955090935050565b60006020828403121561073557600080fd5b6105718261069a565b60006020828403121561075057600080fd5b8151801515811461057157600080fd5b60006020828403121561077257600080fd5b5051919050565b6000808335601e1984360301811261079057600080fd5b83018035915067ffffffffffffffff8211156107ab57600080fd5b6020019150368190038213156107c057600080fd5b9250929050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03898116825260208201899052604082018890528616606082015260c06080820181905260009061082b90830186886107c7565b82810360a084015261083e8185876107c7565b9b9a5050505050505050505050565b6000825160005b8181101561086e5760208186018101518583015201610854565b50600092019182525091905056fea264697066735822122036fd002ff7feae2e8fa6ac7aa6c4662675e86827d2ba61900839cf20746a5e6d64736f6c634300081800330000000000000000000000000f1b7bd7762662b23486320aa91f30312184f70c
Deployed Bytecode
0x6080604052600436106100295760003560e01c80633be9a30a1461002e5780634d47fc8514610043575b600080fd5b61004161003c3660046106b6565b610093565b005b34801561004f57600080fd5b506100777f0000000000000000000000000f1b7bd7762662b23486320aa91f30312184f70c81565b6040516001600160a01b03909116815260200160405180910390f35b6001600160a01b037f0000000000000000000000000f1b7bd7762662b23486320aa91f30312184f70c1663294218356100cf6020840184610723565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610113573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610137919061073e565b15156000036101775761014d6020820182610723565b6040516357b980d760e11b81526001600160a01b0390911660048201526024015b60405180910390fd5b826000036101ea576040516370a0823160e01b81523060048201526001600160a01b038516906370a0823190602401602060405180830381865afa1580156101c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e79190610760565b92505b826001600160a01b03851663dd62ed3e306102086020860186610723565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102779190610760565b10156102a0576102a061028d6020830183610723565b6001600160a01b03861690600019610399565b6102ad6020820182610723565b6001600160a01b031663405e720a6020830135848660408601356102d76080880160608901610723565b6102e46080890189610779565b6102f160a08b018b610779565b6040518a63ffffffff1660e01b81526004016103149897969594939291906107f0565b6000604051808303818588803b15801561032d57600080fd5b505af1158015610341573d6000803e3d6000fd5b5050505050836001600160a01b0316826001600160a01b03167f443b8dd22f57096a1fb621c5ff3e8c3a9a3a5b90236c81dacc0df9b9b6014c758560405161038b91815260200190565b60405180910390a350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526103ea8482610453565b61044d57604080516001600160a01b038516602482015260006044808301919091528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526104439085906104fb565b61044d84826104fb565b50505050565b6000806000846001600160a01b031684604051610470919061084d565b6000604051808303816000865af19150503d80600081146104ad576040519150601f19603f3d011682016040523d82523d6000602084013e6104b2565b606091505b50915091508180156104dc5750805115806104dc5750808060200190518101906104dc919061073e565b80156104f257506000856001600160a01b03163b115b95945050505050565b60006105106001600160a01b03841683610563565b90508051600014158015610535575080806020019051810190610533919061073e565b155b1561055e57604051635274afe760e01b81526001600160a01b038416600482015260240161016e565b505050565b606061057183836000610578565b9392505050565b60608147101561059d5760405163cd78605960e01b815230600482015260240161016e565b600080856001600160a01b031684866040516105b9919061084d565b60006040518083038185875af1925050503d80600081146105f6576040519150601f19603f3d011682016040523d82523d6000602084013e6105fb565b606091505b509150915061060b868383610615565b9695505050505050565b60608261062a5761062582610671565b610571565b815115801561064157506001600160a01b0384163b155b1561066a57604051639996b31560e01b81526001600160a01b038516600482015260240161016e565b5080610571565b8051156106815780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b03811681146106b157600080fd5b919050565b600080600080608085870312156106cc57600080fd5b6106d58561069a565b9350602085013592506106ea6040860161069a565b9150606085013567ffffffffffffffff81111561070657600080fd5b850160c0818803121561071857600080fd5b939692955090935050565b60006020828403121561073557600080fd5b6105718261069a565b60006020828403121561075057600080fd5b8151801515811461057157600080fd5b60006020828403121561077257600080fd5b5051919050565b6000808335601e1984360301811261079057600080fd5b83018035915067ffffffffffffffff8211156107ab57600080fd5b6020019150368190038213156107c057600080fd5b9250929050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03898116825260208201899052604082018890528616606082015260c06080820181905260009061082b90830186886107c7565b82810360a084015261083e8185876107c7565b9b9a5050505050505050505050565b6000825160005b8181101561086e5760208186018101518583015201610854565b50600092019182525091905056fea264697066735822122036fd002ff7feae2e8fa6ac7aa6c4662675e86827d2ba61900839cf20746a5e6d64736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000f1b7bd7762662b23486320aa91f30312184f70c
-----Decoded View---------------
Arg [0] : bridger_ (address): 0x0f1b7bd7762662B23486320AA91F30312184f70C
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000f1b7bd7762662b23486320aa91f30312184f70c
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.