Source Code
Overview
ETH Balance
ETH Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Rescue | 17086584 | 312 days ago | IN | 0 ETH | 0.00000209 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 17086584 | 312 days ago | 0 ETH | ||||
| 16886487 | 317 days ago | 0 ETH | ||||
| 16883249 | 317 days ago | 0.00126038 ETH | ||||
| 16883249 | 317 days ago | 0.00126038 ETH | ||||
| 16882762 | 317 days ago | 0.00132818 ETH | ||||
| 16882762 | 317 days ago | 0.00132818 ETH | ||||
| 16882693 | 317 days ago | 0.00122752 ETH | ||||
| 16882693 | 317 days ago | 0.00122752 ETH | ||||
| 16882236 | 317 days ago | 0.00106316 ETH | ||||
| 16882236 | 317 days ago | 0.00106316 ETH | ||||
| 16878936 | 317 days ago | 0.00054887 ETH | ||||
| 16878936 | 317 days ago | 0.00054887 ETH | ||||
| 16878603 | 317 days ago | 0.00066023 ETH | ||||
| 16878603 | 317 days ago | 0.00066023 ETH | ||||
| 16878563 | 317 days ago | 0 ETH | ||||
| 16878228 | 317 days ago | 0.00068376 ETH | ||||
| 16878228 | 317 days ago | 0.00068376 ETH | ||||
| 16877179 | 317 days ago | 0 ETH | ||||
| 16873294 | 318 days ago | 0 ETH | ||||
| 16864445 | 318 days ago | 0 ETH | ||||
| 16851763 | 318 days ago | 0 ETH | ||||
| 16851763 | 318 days ago | 0 ETH | ||||
| 16850348 | 318 days ago | 0 ETH | ||||
| 16850348 | 318 days ago | 0 ETH | ||||
| 16850204 | 318 days ago | 0.00366639 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RFQRouter
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import {BaseRouter} from "./BaseRouterSingleOutput.sol";
import {FulfilExec, ExtractExec} from "../common/SingleOutputStructs.sol";
import {BungeeEvents} from "../common/BungeeEvents.sol";
import {Ownable} from "../utils/Ownable.sol";
import {IFeeCollector} from "../interfaces/IFeeCollector.sol";
import {InsufficientNativeAmount} from "../common/BungeeErrors.sol";
// Follows IRouter
contract RFQRouter is BaseRouter, BungeeEvents, Ownable {
constructor(address _bungeeGateway, address _owner) Ownable(_owner) BaseRouter(_bungeeGateway) {}
// execute the function
function _execute(
uint256 amount,
address inputToken,
bytes32 requestHash,
uint256 expiry,
address receiverContract,
ExtractExec calldata exec
) internal override {
// Do nothing, not needed.
}
// Called by Bungee on the destination chain to fulfil requests
function _fulfil(bytes32 requestHash, FulfilExec calldata fulfilExec, address transmitter) internal override {
// Transfer fulfilAmount from transmitter to user
bool isNativeToken = fulfilExec.request.basicReq.outputToken == NATIVE_TOKEN_ADDRESS;
// check msg.value against refuel / native token amount amount
uint256 totalNativeTokenAmount = isNativeToken
? fulfilExec.fulfilAmount + fulfilExec.refuelFulfilAmount
: fulfilExec.refuelFulfilAmount;
if (totalNativeTokenAmount > msg.value) revert InsufficientNativeAmount();
// Send the tokens in the exec to the receiver.
if (isNativeToken) {
// send total native token if outputToken is native token
_sendFundsFromContract(NATIVE_TOKEN_ADDRESS, totalNativeTokenAmount, fulfilExec.request.basicReq.receiver);
} else {
// send outputToken to receiver
_sendFundsToReceiver({
token: fulfilExec.request.basicReq.outputToken,
from: transmitter,
amount: fulfilExec.fulfilAmount, // pass fulfilAmount since we're preventing native tokens in outputToken
to: fulfilExec.request.basicReq.receiver
});
// Send refuel amount to the receiver.
_sendFundsFromContract({
token: NATIVE_TOKEN_ADDRESS,
amount: fulfilExec.refuelFulfilAmount,
to: fulfilExec.request.basicReq.receiver
});
}
}
/// @dev can only be called by BungeeGateways
function _releaseFunds(address token, uint256 amount, address recipient) internal override {
// Send the tokens in the exec to the receiver.
_sendFundsFromContract(token, amount, recipient);
}
function _collectFee(
address token,
uint256 amount,
address feeTaker,
address feeCollector,
bytes32 requestHash
) internal override {
_sendFundsFromContract(token, amount, feeCollector);
IFeeCollector(feeCollector).registerFee(feeTaker, amount, token, requestHash);
}
/**
* @notice send funds to the provided address if stuck, can be called only by owner.
* @param token address of the token
* @param amount hash of the command.
* @param to address, funds will be transferred to this address.
*/
function rescue(address token, address to, uint256 amount) external onlyOwner {
_sendFundsFromContract(token, amount, to);
}
receive() external payable {}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
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;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
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]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
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 because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
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)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // error MofaSignatureInvalid(); error InsufficientNativeAmount(); error InvalidMultipleNativeTokens(); error FulfilmentChainInvalid(); error RequestAlreadyFulfilled(); error RouterNotRegistered(); error TransferFailed(); error CallerNotBungeeGateway(); error NoExecutionCacheFound(); error ExecutionCacheFailed(); error SwapOutputInsufficient(); error UnsupportedDestinationChainId(); error MinOutputNotMet(); error OnlyOwner(); error OnlyNominee(); error InvalidRequest(); error FulfilmentDeadlineNotMet(); error CallerNotDelegate(); error BungeeSiblingDoesNotExist(); error InvalidMsg(); error NotDelegate(); error RequestProcessed(); error RequestNotProcessed(); error InvalidSwitchboard(); error PromisedAmountNotMet(); error MsgReceiveFailed(); error RouterAlreadyWhitelisted(); error InvalidStake(); error RouterAlreadyRegistered(); error InvalidFulfil(); error InsufficientCapacity();
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract BungeeEvents {
/// @notice Emitted when a request is extracted
/// @param requestHash hash of the request
/// @param transmitter address of the transmitter
/// @param execution encoded execution data
event RequestExtracted(bytes32 indexed requestHash, uint8 implId, address transmitter, bytes execution);
/// @notice Emitted when a request is fulfilled
/// @param requestHash hash of the request
/// @param fulfiller address of the fulfiller
/// @param execution encoded execution data
event RequestFulfilled(bytes32 indexed requestHash, uint8 implId, address fulfiller, bytes execution);
// emitted on the source once settlement completes
/// @param requestHash hash of the request
event RequestSettled(bytes32 indexed requestHash);
// emitted on the destination once settlement completes
event RequestsSettledOnDestination(
bytes32[] requestHashes,
uint8 implId,
address transmitter,
uint256 outboundFees
);
/// @notice Emitted on the originChain when a request is withdrawn beyond fulfilment deadline
/// @param requestHash hash of the request
/// @param token token being withdrawn
/// @param amount amount being withdrawn
/// @param to address of the recipient
event WithdrawOnOrigin(bytes32 indexed requestHash, address token, uint256 amount, address to);
/// @notice Emitted on the destinationChain when a request is withdrawn if transmitter fails to fulfil
/// @param requestHash hash of the request
/// @param token token being withdrawn
/// @param amount amount being withdrawn
/// @param to address of the recipient
event WithdrawOnDestination(bytes32 indexed requestHash, address token, uint256 amount, address to);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
// Basic details in the request
struct BasicRequest {
// src chain id
uint256 originChainId;
// dest chain id
uint256 destinationChainId;
// deadline of the request
uint256 deadline;
// nonce used for uniqueness in signature
uint256 nonce;
// address of the user placing the request.
address sender;
// address of the receiver on destination chain
address receiver;
// delegate address that has some rights over the request signed
address delegate;
// address of bungee gateway, this address will have access to pull funds from the sender.
address bungeeGateway;
// id of the switchboard
uint32 switchboardId;
// address of the input token
address inputToken;
// amount of the input tokens
uint256 inputAmount;
// output token to be received on the destination.
address outputToken;
// minimum amount to be receive on the destination for the output token.
uint256 minOutputAmount;
// native token refuel amount on the destination chain
uint256 refuelAmount;
}
// The Request which user signs
struct Request {
// basic details in the request.
BasicRequest basicReq;
// swap output token that the user is okay with swapping input token to.
address swapOutputToken;
// minimum swap output the user is okay with swapping the input token to.
// Transmitter can choose or not choose to swap tokens.
uint256 minSwapOutput;
// any sort of metadata to be passed with the request
bytes32 metadata;
// fees of the affiliate if any
bytes affiliateFees;
}
// Transmitter's origin chain execution details for a request with promisedAmounts.
struct ExtractExec {
// User signed Request
Request request;
// address of the router being used for the request.
address router;
// promised amount for output token on the destination
uint256 promisedAmount;
// promised amount for native token refuel on the destination
uint256 promisedRefuelAmount;
// RouterPayload (router specific data) + RouterValue (value required by the router) etc etc
bytes routerData;
// swapPayload 0x00 if no swap is involved.
bytes swapPayload;
// swapRouterAddress
address swapRouter;
// user signature against the request
bytes userSignature;
// address of the beneficiary submitted by the transmitter.
// the beneficiary will be the one receiving locked tokens when a request is settled.
address beneficiary;
}
// Transmitter's destination chain execution details with fulfil amounts.
struct FulfilExec {
// User Signed Request
Request request;
// address of the router
address fulfilRouter;
// amount to be sent to the receiver for output token.
uint256 fulfilAmount;
// amount to be sent to the receiver for native token refuel.
uint256 refuelFulfilAmount;
// extraPayload for router.
bytes routerData;
// total msg.value to be sent to fulfil native token output token
uint256 msgValue;
}
struct ExtractedRequest {
uint256 expiry;
address router;
address sender;
address delegate;
uint32 switchboardId;
address token;
address transmitter; // For stake capacity
address beneficiary; // For Transmitter
uint256 amount;
uint256 promisedAmount; // For Transmitter
uint256 promisedRefuelAmount;
bytes affiliateFees; // For integrator
}
struct FulfilledRequest {
uint256 fulfilledAmount;
uint256 fulfilledRefuelAmount;
bool processed;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
interface IBaseRouter {
function releaseFunds(address token, uint256 amount, address recipient) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import {IBaseRouter} from "./IBaseRouter.sol";
import {FulfilExec, ExtractExec, Request} from "../common/SingleOutputStructs.sol";
interface IBaseRouterSingleOutput is IBaseRouter {
function execute(
uint256 amount,
address inputToken,
bytes32 requestHash,
uint256 expiry,
address receiverContract,
address feeCollector,
ExtractExec memory exec
) external;
function fulfil(bytes32 requestHash, FulfilExec calldata fulfilExec, address transmitter) external payable;
function withdrawRequestOnDestination(Request calldata request, bytes calldata withdrawRequestData) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
interface IBungeeGateway {
function setWhitelistedReceiver(address receiver, uint256 destinationChainId, address router) external;
function getWhitelistedReceiver(address router, uint256 destinationChainId) external view returns (address);
function inboundMsgFromSwitchboard(uint8 msgId, uint32 switchboardId, bytes calldata payload) external;
function isBungeeRouter(address router) external view returns (bool);
function withdrawnRequests(bytes32 requestHash) external view returns (bool);
function withdrawRequestOnOrigin(bytes32 requestHash) external;
function executeSOR(bytes calldata data) external payable returns (bytes memory);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
interface IFeeCollector {
function registerFee(address feeTaker, uint256 feeAmount, address feeToken) external;
function registerFee(address feeTaker, uint256 feeAmount, address feeToken, bytes32 requestHash) external;
function settleFee(bytes32 requestHash) external;
function refundFee(bytes32 requestHash, address to) external;
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.17;
import {ERC20, SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol";
import {BytesLib} from "./BytesLib.sol";
/// @notice helpers for AffiliateFees struct
library AffiliateFeesLib {
/// @notice SafeTransferLib - library for safe and optimized operations on ERC20 tokens
using SafeTransferLib for ERC20;
/// @notice error when affiliate fee length is wrong
error WrongAffiliateFeeLength();
/// @notice event emitted when affiliate fee is deducted
event AffiliateFeeDeducted(address feeToken, address feeTakerAddress, uint256 feeAmount);
// Precision used for affiliate fee calculation
uint256 internal constant PRECISION = 10000000000000000;
/**
* @dev calculates & transfers fee to feeTakerAddress
* @param bridgingAmount amount to be bridged
* @param affiliateFees packed bytes containing feeTakerAddress and feeInBps
* ensure the affiliateFees is packed as follows:
* address feeTakerAddress (20 bytes) + uint48 feeInBps (6 bytes) = 26 bytes
* @return bridgingAmount after deducting affiliate fees
*/
function getAffiliateFees(
uint256 bridgingAmount,
bytes memory affiliateFees
) internal pure returns (uint256, uint256, address) {
address feeTakerAddress;
uint256 feeAmount = 0;
if (affiliateFees.length > 0) {
uint48 feeInBps;
if (affiliateFees.length != 26) revert WrongAffiliateFeeLength();
feeInBps = BytesLib.toUint48(affiliateFees, 20);
feeTakerAddress = BytesLib.toAddress(affiliateFees, 0);
if (feeInBps > 0) {
// calculate fee
feeAmount = ((bridgingAmount * feeInBps) / PRECISION);
bridgingAmount -= feeAmount;
}
}
return (bridgingAmount, feeAmount, feeTakerAddress);
}
function getAmountAfterFee(uint256 bridgingAmount, bytes memory affiliateFees) internal pure returns (uint256) {
address feeTakerAddress;
uint256 feeAmount = 0;
if (affiliateFees.length > 0) {
uint48 feeInBps;
if (affiliateFees.length != 26) revert WrongAffiliateFeeLength();
feeInBps = BytesLib.toUint48(affiliateFees, 20);
feeTakerAddress = BytesLib.toAddress(affiliateFees, 0);
if (feeInBps > 0) {
// calculate fee
feeAmount = ((bridgingAmount * feeInBps) / PRECISION);
bridgingAmount -= feeAmount;
}
}
return (bridgingAmount);
}
}// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.4 <0.9.0; library BytesLib { function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore( 0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. ) ) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1, "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint48(bytes memory _bytes, uint256 _start) internal pure returns (uint48) { require(_bytes.length >= _start + 6, "toUint48_outOfBounds"); uint48 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x6), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equal_nonAligned(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let endMinusWord := add(_preBytes, length) let mc := add(_preBytes, 0x20) let cc := add(_postBytes, 0x20) for { // the next line is the loop condition: // while(uint256(mc < endWord) + cb == 2) } eq(add(lt(mc, endMinusWord), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } // Only if still successful // For <1 word tail bytes if gt(success, 0) { // Get the remainder of length/32 // length % 32 = AND(length, 32 - 1) let numTailBytes := and(length, 0x1f) let mcRem := mload(mc) let ccRem := mload(cc) for { let i := 0 // the next line is the loop condition: // while(uint256(i < numTailBytes) + cb == 2) } eq(add(lt(i, numTailBytes), cb), 2) { i := add(i, 1) } { if iszero(eq(byte(i, mcRem), byte(i, ccRem))) { // unsuccess: success := 0 cb := 0 } } } } default { // unsuccess: success := 0 } } return success; } function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for { } eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import {Request, FulfilExec, ExtractExec} from "../common/SingleOutputStructs.sol";
import {IBaseRouter} from "../interfaces/IBaseRouterSingleOutput.sol";
import {IBungeeGateway} from "../interfaces/IBungeeGateway.sol";
import {TransferFailed} from "../common/BungeeErrors.sol";
import {ERC20} from "solmate/src/tokens/ERC20.sol";
import {SafeTransferLib} from "solmate/src/utils/SafeTransferLib.sol";
import {CallerNotBungeeGateway} from "../common/BungeeErrors.sol";
import {AffiliateFeesLib} from "../lib/AffiliateFeesLib.sol";
// Abstract Contract implemented by Routers
abstract contract BaseRouter is IBaseRouter {
using SafeTransferLib for ERC20;
// BungeeGateway Contract
IBungeeGateway public immutable BUNGEE_GATEWAY;
/// @notice address to identify the native token
address public constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @dev id used to identify single output implementation
uint8 public constant SINGLE_OUTPUT_IMPL_ID = 1;
constructor(address _bungeeGateway) {
BUNGEE_GATEWAY = IBungeeGateway(_bungeeGateway);
}
/// @dev can only be called by BungeeGateway
function execute(
uint256 amount,
address inputToken,
bytes32 requestHash,
uint256 expiry,
address receiverContract,
address feeCollector,
ExtractExec calldata exec
) external {
// Should only be called by Bungee contract
if (msg.sender != address(BUNGEE_GATEWAY)) revert CallerNotBungeeGateway();
// Check if fee is supposed to be deducted
(uint256 bridgeAmount, uint256 feeAmount, address feeTaker) = AffiliateFeesLib.getAffiliateFees(
amount,
exec.request.affiliateFees
);
if (feeAmount > 0) {
_collectFee(inputToken, feeAmount, feeTaker, feeCollector, requestHash);
}
_execute(bridgeAmount, inputToken, requestHash, expiry, receiverContract, exec);
}
/// @dev can only be called by BungeeGateway
function fulfil(bytes32 requestHash, FulfilExec calldata fulfilExec, address transmitter) external payable {
// Should only be called by Bungee contract
if (msg.sender != address(BUNGEE_GATEWAY)) revert CallerNotBungeeGateway();
_fulfil(requestHash, fulfilExec, transmitter);
}
function withdrawRequestOnDestination(Request calldata request, bytes calldata withdrawRequestData) external {
// Should only be called by Bungee contract
if (msg.sender != address(BUNGEE_GATEWAY)) revert CallerNotBungeeGateway();
_withdrawRequestOnDestination(request, withdrawRequestData);
}
/// @dev can only be called by BungeeGateways
function releaseFunds(address token, uint256 amount, address recipient) external {
// Should only be called by Bungee contract
if (msg.sender != address(BUNGEE_GATEWAY)) revert CallerNotBungeeGateway();
// Send the tokens in the exec to the receiver.
_releaseFunds(token, amount, recipient);
}
/// @dev internal function for fulfil that every router needs to implement
function _fulfil(bytes32 requestHash, FulfilExec calldata fulfilExec, address transmitter) internal virtual {}
/// @dev internal function for executing the route every router needs to implement
function _execute(
uint256 amount,
address inputToken,
bytes32 requestHash,
uint256 expiry,
address receiverContract,
ExtractExec calldata exec
) internal virtual {}
/// @dev can only be called by BungeeGateways
function _releaseFunds(address token, uint256 amount, address recipient) internal virtual {}
function _collectFee(
address token,
uint256 amount,
address feeTaker,
address feeCollector,
bytes32 requestHash
) internal virtual {}
function _withdrawRequestOnDestination(
Request calldata request,
bytes calldata withdrawRequestData
) internal virtual {}
/**
* @dev send funds from an address to the provided address.
* @param token address of the token
* @param from atomic execution.
* @param amount hash of the command.
* @param to address, funds will be transferred to this address.
*/
function _sendFundsToReceiver(address token, address from, uint256 amount, address to) internal {
/// native token case
if (token == NATIVE_TOKEN_ADDRESS) {
(bool success, ) = to.call{value: amount, gas: 5000}("");
if (!success) revert TransferFailed();
return;
}
/// ERC20 case
ERC20(token).safeTransferFrom(from, to, amount);
}
/**
* @dev send funds to the provided address.
* @param token address of the token
* @param amount hash of the command.
* @param to address, funds will be transferred to this address.
*/
function _sendFundsFromContract(address token, uint256 amount, address to) internal {
/// native token case
if (token == NATIVE_TOKEN_ADDRESS) {
(bool success, ) = to.call{value: amount, gas: 5000}("");
if (!success) revert TransferFailed();
return;
}
/// ERC20 case
ERC20(token).safeTransfer(to, amount);
}
}// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.17;
import {OnlyOwner, OnlyNominee} from "../common/BungeeErrors.sol";
abstract contract Ownable {
address private _owner;
address private _nominee;
event OwnerNominated(address indexed nominee);
event OwnerClaimed(address indexed claimer);
constructor(address owner_) {
_claimOwner(owner_);
}
modifier onlyOwner() {
if (msg.sender != _owner) {
revert OnlyOwner();
}
_;
}
function owner() public view returns (address) {
return _owner;
}
function nominee() public 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_);
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_bungeeGateway","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotBungeeGateway","type":"error"},{"inputs":[],"name":"InsufficientNativeAmount","type":"error"},{"inputs":[],"name":"OnlyNominee","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"WrongAffiliateFeeLength","type":"error"},{"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":"requestHash","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"implId","type":"uint8"},{"indexed":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"bytes","name":"execution","type":"bytes"}],"name":"RequestExtracted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestHash","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"implId","type":"uint8"},{"indexed":false,"internalType":"address","name":"fulfiller","type":"address"},{"indexed":false,"internalType":"bytes","name":"execution","type":"bytes"}],"name":"RequestFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestHash","type":"bytes32"}],"name":"RequestSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"requestHashes","type":"bytes32[]"},{"indexed":false,"internalType":"uint8","name":"implId","type":"uint8"},{"indexed":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"uint256","name":"outboundFees","type":"uint256"}],"name":"RequestsSettledOnDestination","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"WithdrawOnDestination","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"WithdrawOnOrigin","type":"event"},{"inputs":[],"name":"BUNGEE_GATEWAY","outputs":[{"internalType":"contract IBungeeGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE_TOKEN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SINGLE_OUTPUT_IMPL_ID","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"bytes32","name":"requestHash","type":"bytes32"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"address","name":"receiverContract","type":"address"},{"internalType":"address","name":"feeCollector","type":"address"},{"components":[{"components":[{"components":[{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"address","name":"bungeeGateway","type":"address"},{"internalType":"uint32","name":"switchboardId","type":"uint32"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"refuelAmount","type":"uint256"}],"internalType":"struct BasicRequest","name":"basicReq","type":"tuple"},{"internalType":"address","name":"swapOutputToken","type":"address"},{"internalType":"uint256","name":"minSwapOutput","type":"uint256"},{"internalType":"bytes32","name":"metadata","type":"bytes32"},{"internalType":"bytes","name":"affiliateFees","type":"bytes"}],"internalType":"struct Request","name":"request","type":"tuple"},{"internalType":"address","name":"router","type":"address"},{"internalType":"uint256","name":"promisedAmount","type":"uint256"},{"internalType":"uint256","name":"promisedRefuelAmount","type":"uint256"},{"internalType":"bytes","name":"routerData","type":"bytes"},{"internalType":"bytes","name":"swapPayload","type":"bytes"},{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"userSignature","type":"bytes"},{"internalType":"address","name":"beneficiary","type":"address"}],"internalType":"struct ExtractExec","name":"exec","type":"tuple"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestHash","type":"bytes32"},{"components":[{"components":[{"components":[{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"address","name":"bungeeGateway","type":"address"},{"internalType":"uint32","name":"switchboardId","type":"uint32"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"refuelAmount","type":"uint256"}],"internalType":"struct BasicRequest","name":"basicReq","type":"tuple"},{"internalType":"address","name":"swapOutputToken","type":"address"},{"internalType":"uint256","name":"minSwapOutput","type":"uint256"},{"internalType":"bytes32","name":"metadata","type":"bytes32"},{"internalType":"bytes","name":"affiliateFees","type":"bytes"}],"internalType":"struct Request","name":"request","type":"tuple"},{"internalType":"address","name":"fulfilRouter","type":"address"},{"internalType":"uint256","name":"fulfilAmount","type":"uint256"},{"internalType":"uint256","name":"refuelFulfilAmount","type":"uint256"},{"internalType":"bytes","name":"routerData","type":"bytes"},{"internalType":"uint256","name":"msgValue","type":"uint256"}],"internalType":"struct FulfilExec","name":"fulfilExec","type":"tuple"},{"internalType":"address","name":"transmitter","type":"address"}],"name":"fulfil","outputs":[],"stateMutability":"payable","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":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"releaseFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"delegate","type":"address"},{"internalType":"address","name":"bungeeGateway","type":"address"},{"internalType":"uint32","name":"switchboardId","type":"uint32"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"refuelAmount","type":"uint256"}],"internalType":"struct BasicRequest","name":"basicReq","type":"tuple"},{"internalType":"address","name":"swapOutputToken","type":"address"},{"internalType":"uint256","name":"minSwapOutput","type":"uint256"},{"internalType":"bytes32","name":"metadata","type":"bytes32"},{"internalType":"bytes","name":"affiliateFees","type":"bytes"}],"internalType":"struct Request","name":"request","type":"tuple"},{"internalType":"bytes","name":"withdrawRequestData","type":"bytes"}],"name":"withdrawRequestOnDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a060405234801561001057600080fd5b50604051610f83380380610f8383398101604081905261002f916100bd565b6001600160a01b038216608052806100468161004e565b5050506100f0565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b80516001600160a01b03811681146100b857600080fd5b919050565b600080604083850312156100d057600080fd5b6100d9836100a1565b91506100e7602084016100a1565b90509250929050565b608051610e5c610127600039600081816101de015281816102d50152818161039f0152818161045d01526104b10152610e5c6000f3fe6080604052600436106100ab5760003560e01c80635b94db27116100645780635b94db271461018c57806362524dd7146101ac57806370372d85146101cc5780638da5cb5b14610200578063da2de3441461021e578063df2ebdbb1461023157600080fd5b806320f99c0a146100b757806320ff430b146100ee5780633bd1adec146101105780633cbc7eaa146101255780633ed33c7f1461014c5780634eae20e21461016c57600080fd5b366100b257005b600080fd5b3480156100c357600080fd5b506001546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100fa57600080fd5b5061010e610109366004610b21565b610259565b005b34801561011c57600080fd5b5061010e610294565b34801561013157600080fd5b5061013a600181565b60405160ff90911681526020016100e5565b34801561015857600080fd5b5061010e610167366004610b5d565b6102ca565b34801561017857600080fd5b5061010e610187366004610bf1565b610394565b34801561019857600080fd5b5061010e6101a7366004610c91565b6103dd565b3480156101b857600080fd5b5061010e6101c7366004610cb3565b610452565b3480156101d857600080fd5b506100d17f000000000000000000000000000000000000000000000000000000000000000081565b34801561020c57600080fd5b506000546001600160a01b03166100d1565b61010e61022c366004610cef565b6104a6565b34801561023d57600080fd5b506100d173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6000546001600160a01b0316331461028457604051635fc483c560e01b815260040160405180910390fd5b61028f8382846104fa565b505050565b6001546001600160a01b031633146102bf57604051637c91ccdd60e01b815260040160405180910390fd5b6102c8336105b2565b565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461031357604051634556123760e01b815260040160405180910390fd5b6000808061036e8a6103258680610d42565b61033490610220810190610d63565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061060592505050565b91945092509050811561038857610388898383888c6106a2565b50505050505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461028f57604051634556123760e01b815260040160405180910390fd5b6000546001600160a01b0316331461040857604051635fc483c560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461049b57604051634556123760e01b815260040160405180910390fd5b61028f838383610725565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104ef57604051634556123760e01b815260040160405180910390fd5b61028f838383610730565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0384160161059e576000816001600160a01b03168361138890604051600060405180830381858888f193505050503d8060008114610571576040519150601f19603f3d011682016040523d82523d6000602084013e610576565b606091505b5050905080610598576040516312171d8360e31b815260040160405180910390fd5b50505050565b61028f6001600160a01b038416828461086e565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b600080600080600080865111156106975760008651601a1461063a57604051634115207f60e01b815260040160405180910390fd5b6106458760146108f4565b9050610652876000610957565b925065ffffffffffff81161561069557662386f26fc1000061067c65ffffffffffff83168a610dc7565b6106869190610dde565b91506106928289610e00565b97505b505b959690945092505050565b6106ad8585846104fa565b60405163eacedbf160e01b81526001600160a01b0384811660048301526024820186905286811660448301526064820183905283169063eacedbf190608401600060405180830381600087803b15801561070657600080fd5b505af115801561071a573d6000803e3d6000fd5b505050505050505050565b61028f8383836104fa565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6107518480610d42565b6107649061018081019061016001610c91565b6001600160a01b0316149050600081610781578360600135610793565b61079360608501356040860135610e13565b9050348111156107b657604051637bf261fb60e01b815260040160405180910390fd5b81156107fa576107f573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee826107df8780610d42565b6107f09060c081019060a001610c91565b6104fa565b610867565b6108406108078580610d42565b61081a9061018081019061016001610c91565b84604087013561082a8880610d42565b61083b9060c081019060a001610c91565b6109bc565b61086773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60608601356107df8780610d42565b5050505050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806105985760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064015b60405180910390fd5b6000610901826006610e13565b835110156109485760405162461bcd60e51b8152602060048201526014602482015273746f55696e7434385f6f75744f66426f756e647360601b60448201526064016108eb565b50818101600601515b92915050565b6000610964826014610e13565b835110156109ac5760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016108eb565b500160200151600160601b900490565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03851601610a60576000816001600160a01b03168361138890604051600060405180830381858888f193505050503d8060008114610a33576040519150601f19603f3d011682016040523d82523d6000602084013e610a38565b606091505b5050905080610a5a576040516312171d8360e31b815260040160405180910390fd5b50610598565b6105986001600160a01b03851684838560006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b03841660248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806108675760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b60448201526064016108eb565b80356001600160a01b0381168114610b1c57600080fd5b919050565b600080600060608486031215610b3657600080fd5b610b3f84610b05565b9250610b4d60208501610b05565b9150604084013590509250925092565b600080600080600080600060e0888a031215610b7857600080fd5b87359650610b8860208901610b05565b95506040880135945060608801359350610ba460808901610b05565b9250610bb260a08901610b05565b915060c088013567ffffffffffffffff811115610bce57600080fd5b8801610120818b031215610be157600080fd5b8091505092959891949750929550565b600080600060408486031215610c0657600080fd5b833567ffffffffffffffff80821115610c1e57600080fd5b908501906102408288031215610c3357600080fd5b90935060208501359080821115610c4957600080fd5b818601915086601f830112610c5d57600080fd5b813581811115610c6c57600080fd5b876020828501011115610c7e57600080fd5b6020830194508093505050509250925092565b600060208284031215610ca357600080fd5b610cac82610b05565b9392505050565b600080600060608486031215610cc857600080fd5b610cd184610b05565b925060208401359150610ce660408501610b05565b90509250925092565b600080600060608486031215610d0457600080fd5b83359250602084013567ffffffffffffffff811115610d2257600080fd5b840160c08187031215610d3457600080fd5b9150610ce660408501610b05565b6000823561023e19833603018112610d5957600080fd5b9190910192915050565b6000808335601e19843603018112610d7a57600080fd5b83018035915067ffffffffffffffff821115610d9557600080fd5b602001915036819003821315610daa57600080fd5b9250929050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761095157610951610db1565b600082610dfb57634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561095157610951610db1565b8082018082111561095157610951610db156fea26469706673582212200655634b96606d6a0560508e9e5c02b2750e0cedfc09d1c069895d21062a763564736f6c6343000813003300000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c865000000000000000000000000daee4d2156de6fe6f7d50ca047136d758f96a6f0
Deployed Bytecode
0x6080604052600436106100ab5760003560e01c80635b94db27116100645780635b94db271461018c57806362524dd7146101ac57806370372d85146101cc5780638da5cb5b14610200578063da2de3441461021e578063df2ebdbb1461023157600080fd5b806320f99c0a146100b757806320ff430b146100ee5780633bd1adec146101105780633cbc7eaa146101255780633ed33c7f1461014c5780634eae20e21461016c57600080fd5b366100b257005b600080fd5b3480156100c357600080fd5b506001546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100fa57600080fd5b5061010e610109366004610b21565b610259565b005b34801561011c57600080fd5b5061010e610294565b34801561013157600080fd5b5061013a600181565b60405160ff90911681526020016100e5565b34801561015857600080fd5b5061010e610167366004610b5d565b6102ca565b34801561017857600080fd5b5061010e610187366004610bf1565b610394565b34801561019857600080fd5b5061010e6101a7366004610c91565b6103dd565b3480156101b857600080fd5b5061010e6101c7366004610cb3565b610452565b3480156101d857600080fd5b506100d17f00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c86581565b34801561020c57600080fd5b506000546001600160a01b03166100d1565b61010e61022c366004610cef565b6104a6565b34801561023d57600080fd5b506100d173eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b6000546001600160a01b0316331461028457604051635fc483c560e01b815260040160405180910390fd5b61028f8382846104fa565b505050565b6001546001600160a01b031633146102bf57604051637c91ccdd60e01b815260040160405180910390fd5b6102c8336105b2565b565b336001600160a01b037f00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c865161461031357604051634556123760e01b815260040160405180910390fd5b6000808061036e8a6103258680610d42565b61033490610220810190610d63565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061060592505050565b91945092509050811561038857610388898383888c6106a2565b50505050505050505050565b336001600160a01b037f00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c865161461028f57604051634556123760e01b815260040160405180910390fd5b6000546001600160a01b0316331461040857604051635fc483c560e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b336001600160a01b037f00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c865161461049b57604051634556123760e01b815260040160405180910390fd5b61028f838383610725565b336001600160a01b037f00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c86516146104ef57604051634556123760e01b815260040160405180910390fd5b61028f838383610730565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0384160161059e576000816001600160a01b03168361138890604051600060405180830381858888f193505050503d8060008114610571576040519150601f19603f3d011682016040523d82523d6000602084013e610576565b606091505b5050905080610598576040516312171d8360e31b815260040160405180910390fd5b50505050565b61028f6001600160a01b038416828461086e565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b600080600080600080865111156106975760008651601a1461063a57604051634115207f60e01b815260040160405180910390fd5b6106458760146108f4565b9050610652876000610957565b925065ffffffffffff81161561069557662386f26fc1000061067c65ffffffffffff83168a610dc7565b6106869190610dde565b91506106928289610e00565b97505b505b959690945092505050565b6106ad8585846104fa565b60405163eacedbf160e01b81526001600160a01b0384811660048301526024820186905286811660448301526064820183905283169063eacedbf190608401600060405180830381600087803b15801561070657600080fd5b505af115801561071a573d6000803e3d6000fd5b505050505050505050565b61028f8383836104fa565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6107518480610d42565b6107649061018081019061016001610c91565b6001600160a01b0316149050600081610781578360600135610793565b61079360608501356040860135610e13565b9050348111156107b657604051637bf261fb60e01b815260040160405180910390fd5b81156107fa576107f573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee826107df8780610d42565b6107f09060c081019060a001610c91565b6104fa565b610867565b6108406108078580610d42565b61081a9061018081019061016001610c91565b84604087013561082a8880610d42565b61083b9060c081019060a001610c91565b6109bc565b61086773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee60608601356107df8780610d42565b5050505050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806105985760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064015b60405180910390fd5b6000610901826006610e13565b835110156109485760405162461bcd60e51b8152602060048201526014602482015273746f55696e7434385f6f75744f66426f756e647360601b60448201526064016108eb565b50818101600601515b92915050565b6000610964826014610e13565b835110156109ac5760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016108eb565b500160200151600160601b900490565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03851601610a60576000816001600160a01b03168361138890604051600060405180830381858888f193505050503d8060008114610a33576040519150601f19603f3d011682016040523d82523d6000602084013e610a38565b606091505b5050905080610a5a576040516312171d8360e31b815260040160405180910390fd5b50610598565b6105986001600160a01b03851684838560006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b03841660248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806108675760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b60448201526064016108eb565b80356001600160a01b0381168114610b1c57600080fd5b919050565b600080600060608486031215610b3657600080fd5b610b3f84610b05565b9250610b4d60208501610b05565b9150604084013590509250925092565b600080600080600080600060e0888a031215610b7857600080fd5b87359650610b8860208901610b05565b95506040880135945060608801359350610ba460808901610b05565b9250610bb260a08901610b05565b915060c088013567ffffffffffffffff811115610bce57600080fd5b8801610120818b031215610be157600080fd5b8091505092959891949750929550565b600080600060408486031215610c0657600080fd5b833567ffffffffffffffff80821115610c1e57600080fd5b908501906102408288031215610c3357600080fd5b90935060208501359080821115610c4957600080fd5b818601915086601f830112610c5d57600080fd5b813581811115610c6c57600080fd5b876020828501011115610c7e57600080fd5b6020830194508093505050509250925092565b600060208284031215610ca357600080fd5b610cac82610b05565b9392505050565b600080600060608486031215610cc857600080fd5b610cd184610b05565b925060208401359150610ce660408501610b05565b90509250925092565b600080600060608486031215610d0457600080fd5b83359250602084013567ffffffffffffffff811115610d2257600080fd5b840160c08187031215610d3457600080fd5b9150610ce660408501610b05565b6000823561023e19833603018112610d5957600080fd5b9190910192915050565b6000808335601e19843603018112610d7a57600080fd5b83018035915067ffffffffffffffff821115610d9557600080fd5b602001915036819003821315610daa57600080fd5b9250929050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761095157610951610db1565b600082610dfb57634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561095157610951610db1565b8082018082111561095157610951610db156fea26469706673582212200655634b96606d6a0560508e9e5c02b2750e0cedfc09d1c069895d21062a763564736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c865000000000000000000000000daee4d2156de6fe6f7d50ca047136d758f96a6f0
-----Decoded View---------------
Arg [0] : _bungeeGateway (address): 0x79C7a69499Cf1866734E8D3154200a05aE41c865
Arg [1] : _owner (address): 0xDaeE4D2156DE6fe6f7D50cA047136D758f96A6f0
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000079c7a69499cf1866734e8d3154200a05ae41c865
Arg [1] : 000000000000000000000000daee4d2156de6fe6f7d50ca047136d758f96a6f0
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1.63
Net Worth in ETH
Token Allocations
USDB
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| BLAST | 100.00% | $0.998013 | 1.6299 | $1.63 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.