Overview
ETH Balance
0.00001 ETH
Eth Value
$0.04 (@ $3,677.42/ETH)More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 11,611 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Receive Message ... | 19915411 | 15 mins ago | IN | 0 ETH | 0.00393595 | ||||
Start | 19915357 | 26 mins ago | IN | 0.11 ETH | 0.00153324 | ||||
Start | 19914915 | 1 hr ago | IN | 0.8 ETH | 0.00199855 | ||||
Receive Message ... | 19914165 | 4 hrs ago | IN | 0 ETH | 0.00922567 | ||||
Start | 19914084 | 4 hrs ago | IN | 0.25 ETH | 0.00403185 | ||||
Receive Message ... | 19913593 | 6 hrs ago | IN | 0 ETH | 0.02036356 | ||||
Receive Message ... | 19913368 | 7 hrs ago | IN | 0 ETH | 0.02031995 | ||||
Start | 19913138 | 7 hrs ago | IN | 0.5 ETH | 0.00159536 | ||||
Start | 19912942 | 8 hrs ago | IN | 0.18 ETH | 0.0012901 | ||||
Receive Message ... | 19912929 | 8 hrs ago | IN | 0 ETH | 0.00390569 | ||||
Start | 19912877 | 8 hrs ago | IN | 0.004 ETH | 0.0015062 | ||||
Start | 19912668 | 9 hrs ago | IN | 0.05 ETH | 0.00357365 | ||||
Start | 19912503 | 10 hrs ago | IN | 0.025 ETH | 0.00186973 | ||||
Start | 19911727 | 12 hrs ago | IN | 0.42 ETH | 0.00148071 | ||||
Start | 19911566 | 13 hrs ago | IN | 0.3 ETH | 0.00091401 | ||||
Start | 19911234 | 14 hrs ago | IN | 0.66 ETH | 0.00091906 | ||||
Receive Message ... | 19910736 | 15 hrs ago | IN | 0 ETH | 0.00295229 | ||||
Receive Message ... | 19910702 | 16 hrs ago | IN | 0 ETH | 0.0031102 | ||||
Start | 19910664 | 16 hrs ago | IN | 0.01 ETH | 0.00089776 | ||||
Receive Message ... | 19910575 | 16 hrs ago | IN | 0 ETH | 0.00303972 | ||||
Receive Message ... | 19910482 | 16 hrs ago | IN | 0 ETH | 0.00308206 | ||||
Receive Message ... | 19910354 | 17 hrs ago | IN | 0 ETH | 0.00180006 | ||||
Receive Message ... | 19910259 | 17 hrs ago | IN | 0 ETH | 0.00171752 | ||||
Receive Message ... | 19910207 | 17 hrs ago | IN | 0 ETH | 0.00190725 | ||||
Receive Message ... | 19910207 | 17 hrs ago | IN | 0 ETH | 0.00184521 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
19915411 | 15 mins ago | 0.00428472 ETH | ||||
19915411 | 15 mins ago | 0.0049157 ETH | ||||
19915411 | 15 mins ago | 0.00920043 ETH | ||||
19915357 | 26 mins ago | 0.11 ETH | ||||
19914915 | 1 hr ago | 0.8 ETH | ||||
19914165 | 4 hrs ago | 0.0124546 ETH | ||||
19914165 | 4 hrs ago | 0.33756405 ETH | ||||
19914165 | 4 hrs ago | 0.35001866 ETH | ||||
19914084 | 4 hrs ago | 0.25 ETH | ||||
19913593 | 6 hrs ago | 0.02153524 ETH | ||||
19913593 | 6 hrs ago | 0.21847757 ETH | ||||
19913593 | 6 hrs ago | 0.24001282 ETH | ||||
19913138 | 7 hrs ago | 0.5 ETH | ||||
19912942 | 8 hrs ago | 0.18 ETH | ||||
19912929 | 8 hrs ago | 0.00618181 ETH | ||||
19912929 | 8 hrs ago | 1.22386647 ETH | ||||
19912929 | 8 hrs ago | 1.23004829 ETH | ||||
19912877 | 8 hrs ago | 0.004 ETH | ||||
19912668 | 9 hrs ago | 0.05 ETH | ||||
19912503 | 10 hrs ago | 0.025 ETH | ||||
19911727 | 12 hrs ago | 0.42 ETH | ||||
19911566 | 13 hrs ago | 0.3 ETH | ||||
19911234 | 14 hrs ago | 0.66 ETH | ||||
19910664 | 16 hrs ago | 0.01 ETH | ||||
19910259 | 17 hrs ago | 0.00218445 ETH |
Loading...
Loading
Contract Name:
Portico
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSE pragma solidity ^0.8.9; import "./PorticoStructs.sol"; import "./ITokenBridge.sol"; import "./IWormhole.sol"; import "./IERC20.sol"; import "./IWETH.sol"; //uniswap import "./uniswap/ISwapRouter02.sol"; //oz import "./oz/Ownable.sol"; import "./oz/ReentrancyGuard.sol"; import "./oz/SafeERC20.sol"; contract PorticoBase is Ownable, ReentrancyGuard { using SafeERC20 for IERC20; ISwapRouter02 public immutable ROUTERV3; ITokenBridge public immutable TOKENBRIDGE; IWETH public immutable WETH; IWormhole public immutable wormhole; uint16 public immutable wormholeChainId; address public FEE_RECIPIENT; constructor(ISwapRouter02 _routerV3, ITokenBridge _bridge, IWETH _weth, address _feeRecipient) Ownable(_msgSender()) { ROUTERV3 = _routerV3; TOKENBRIDGE = _bridge; wormhole = _bridge.wormhole(); WETH = _weth; wormholeChainId = wormhole.chainId(); FEE_RECIPIENT = _feeRecipient; } function version() external pure returns (uint32) { return 1; } ///@notice config recipient for relayer fees function setFeeRecipient(address newFeeRecipient) external onlyOwner { FEE_RECIPIENT = newFeeRecipient; } ///@notice if current approval is insufficient, approve max ///@notice oz safeIncreaseAllowance controls for tokens that require allowance to be reset to 0 before increasing again function updateApproval(address spender, IERC20 token, uint256 amount) internal { // get current allowance uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < amount) { // amount is a delta, so need to pass max - current to avoid overflow token.safeIncreaseAllowance(spender, type(uint256).max - (currentAllowance + 1)); } } } abstract contract PorticoStart is PorticoBase { using PorticoFlagSetAccess for PorticoFlagSet; using SafeERC20 for IERC20; function _start_v3swap(PorticoStructs.TradeParameters memory params, uint256 actualAmount) internal returns (uint256 amount) { updateApproval(address(ROUTERV3), params.startTokenAddress, actualAmount); ROUTERV3.exactInputSingle( ISwapRouter02.ExactInputSingleParams( address(params.startTokenAddress), //tokenIn address(params.canonAssetAddress), //tokenOut params.flags.feeTierStart(), //fee address(this), //recipient actualAmount, //amountIn params.minAmountStart, //minAmountReceived 0 ) ); amount = params.canonAssetAddress.balanceOf(address(this)); } event PorticoSwapStart(uint64 indexed sequence, uint16 indexed chainId); function start( PorticoStructs.TradeParameters memory params ) external payable nonReentrant returns (address emitterAddress, uint16 chainId, uint64 sequence) { uint256 amount; uint256 whMessageFee = wormhole.messageFee(); uint256 value = msg.value; // always check for native wrapping logic if (address(params.startTokenAddress) == address(WETH) && params.flags.shouldWrapNative()) { // if wrapping, msg.value should be exactly amountSpecified + wormhole message fee require(value == params.amountSpecified + whMessageFee, "msg.value incorrect"); // if we are wrapping a token, we call WETH.deposit for the user, assuming we have been sent what we need. WETH.deposit{ value: params.amountSpecified }(); // because wormhole rounds to 1e8, some dust may exist from previous txs // we use balanceOf to lump this in with future txs amount = WETH.balanceOf(address(this)); } else { // ensure no eth needs to be refunded require(value == whMessageFee, "msg.value incorrect"); // otherwise, just get the token we need to do the swap (if we are swapping, or just the token itself) params.startTokenAddress.safeTransferFrom(_msgSender(), address(this), params.amountSpecified); // Because wormhole rounds to 1e8, some dust may exist from previous txs // we use balanceOf to lump this in with future txs amount = params.startTokenAddress.balanceOf(address(this)); } // sanity check amount received require(amount >= params.amountSpecified, "transfer insufficient"); // if the start token is the canon token, we don't need to swap if (params.startTokenAddress != params.canonAssetAddress) { // do the swap, and amount is now the amount that we received from the swap amount = _start_v3swap(params, amount); } // allow the token bridge to do its token bridge things updateApproval(address(TOKENBRIDGE), params.canonAssetAddress, amount); // now we need to produce the payload we are sending PorticoStructs.DecodedVAA memory decodedVAA = PorticoStructs.DecodedVAA( params.flags, params.finalTokenAddress, params.recipientAddress, amount, params.minAmountFinish, params.relayerFee ); // send the actual transfer tx, and get the sequence sequence = TOKENBRIDGE.transferTokensWithPayload{ value: whMessageFee }( address(params.canonAssetAddress), amount, params.flags.recipientChain(), padAddress(params.recipientPorticoAddress), params.flags.bridgeNonce(), abi.encode(decodedVAA) ); // local chain id chainId = wormholeChainId; // emitter is the local tokenbridge emitterAddress = address(TOKENBRIDGE); // emit event emit PorticoSwapStart(sequence, chainId); } ///@notice @return addr in bytes32 format, as required by Wormhole function padAddress(address addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(addr))); } } abstract contract PorticoFinish is PorticoBase { using PorticoFlagSetAccess for PorticoFlagSet; using SafeERC20 for IERC20; event PorticoSwapFinish(bool swapCompleted, uint256 finaluserAmount, uint256 relayerFeeAmount, PorticoStructs.DecodedVAA data); // receiveMessageAndSwap is the entrypoint for finishing the swap function receiveMessageAndSwap(bytes calldata encodedTransferMessage) external nonReentrant { // start by calling _completeTransfer, submitting the VAA to the token bridge (PorticoStructs.DecodedVAA memory message, PorticoStructs.BridgeInfo memory bridgeInfo) = _completeTransfer(encodedTransferMessage); // we modify the message to set the relayerFee to 0 if the msgSender is the fee recipient // this allows users to self-relay and not pay the fee, even if the fee was set to non-zero at tx origin bridgeInfo.relayerFeeAmount = (_msgSender() == message.recipientAddress) ? 0 : message.relayerFee; //now process (bool swapCompleted, uint256 finalUserAmount) = finish(message, bridgeInfo); // simply emit the raw data bytes. it should be trivial to parse. emit PorticoSwapFinish(swapCompleted, finalUserAmount, bridgeInfo.relayerFeeAmount, message); } // _completeTransfer takes the vaa for a payload3 token transfer, redeems it with the token bridge, and returns the decoded vaa payload function _completeTransfer( bytes calldata encodedTransferMessage ) internal returns (PorticoStructs.DecodedVAA memory message, PorticoStructs.BridgeInfo memory bridgeInfo) { /** * Call `completeTransferWithPayload` on the token bridge. This * method acts as a reentrancy protection since it does not allow * transfers to be redeemed more than once. */ bytes memory transferPayload = TOKENBRIDGE.completeTransferWithPayload(encodedTransferMessage); // parse the wormhole message payload into the `TransferWithPayload` struct, a payload3 token transfer ITokenBridge.TransferWithPayload memory transfer = TOKENBRIDGE.parseTransferWithPayload(transferPayload); // ensure that the to address is this address require(unpadAddress(transfer.to) == address(this) && transfer.toChain == wormholeChainId, "Token not sent to this address"); // decode the payload3 we originally sent into the decodedVAA struct. message = abi.decode(transfer.payload, (PorticoStructs.DecodedVAA)); // get the address for the token on this address. bridgeInfo.tokenReceived = IERC20( transfer.tokenChain == wormholeChainId ? unpadAddress(transfer.tokenAddress) : TOKENBRIDGE.wrappedAsset(transfer.tokenChain, transfer.tokenAddress) ); // put the transfer amount into amountReceived, knowing we may need to change it in a sec bridgeInfo.amountReceived = transfer.amount; // if there are more than 8 decimals, we need to denormalize. wormhole token bridge truncates tokens of more than 8 decimals to 8 decimals. uint8 decimals = bridgeInfo.tokenReceived.decimals(); if (decimals > 8) { bridgeInfo.amountReceived *= uint256(10) ** (decimals - 8); } } ///@notice determines we need to swap and/or unwrap, does those things if needed, and sends tokens to user & pays relayer fee function finish( PorticoStructs.DecodedVAA memory params, PorticoStructs.BridgeInfo memory bridgeInfo ) internal returns (bool swapCompleted, uint256 finalUserAmount) { // see if the unwrap flag is set, and that the finalTokenAddress is the address we have set on deploy as our native weth9 address bool shouldUnwrap = params.flags.shouldUnwrapNative() && address(params.finalTokenAddress) == address(WETH); if ((params.finalTokenAddress) == bridgeInfo.tokenReceived) { // this means that we don't need to do a swap, aka, we received the canon asset. finalUserAmount = payOut(shouldUnwrap, params.finalTokenAddress, params.recipientAddress, bridgeInfo.relayerFeeAmount); return (false, finalUserAmount); } // if we are here, if means we need to do the swap, resulting aset from the swap is sent to this contract swapCompleted = _finish_v3swap(params, bridgeInfo); // if the swap fails, we just transfer the amount we received from the token bridge to the recipientAddress. if (!swapCompleted) { bridgeInfo.tokenReceived.transfer(params.recipientAddress, bridgeInfo.amountReceived); // we also mark swapCompleted to be false for PorticoSwapFinish event return (swapCompleted, bridgeInfo.amountReceived); } // we must call payout if the swap was completed finalUserAmount = payOut(shouldUnwrap, params.finalTokenAddress, params.recipientAddress, bridgeInfo.relayerFeeAmount); } /** * @notice perform the swap via Uniswap V3 Router * if swap fails, we don't pay fees to the relayer * the reason is because that typically, the swap fails because of bad market conditions * in this case, it is in the best interest of the mev/relayer to NOT relay this message until conditions are good * the user of course, who if they self relay, does not pay a fee, does not have this problem, so they can force this if they wish * swap failed - return canon asset to recipient * it will return true if the swap was completed, indicating that funds need to be sent from this contract to the recipient */ function _finish_v3swap( PorticoStructs.DecodedVAA memory params, PorticoStructs.BridgeInfo memory bridgeInfo ) internal returns (bool swapCompleted) { // set swap options with params decoded from the payload ISwapRouter02.ExactInputSingleParams memory swapParams = ISwapRouter02.ExactInputSingleParams({ tokenIn: address(bridgeInfo.tokenReceived), tokenOut: address(params.finalTokenAddress), fee: params.flags.feeTierFinish(), recipient: address(this), // we need to receive the token in order to correctly split the fee. tragic. amountIn: bridgeInfo.amountReceived, amountOutMinimum: params.minAmountFinish, sqrtPriceLimitX96: 0 //sqrtPriceLimit is not used }); // update approval updateApproval(address(ROUTERV3), bridgeInfo.tokenReceived, bridgeInfo.amountReceived); // try the swap try ROUTERV3.exactInputSingle(swapParams) { swapCompleted = true; } catch {} } ///@notice pay out to user and relayer ///@notice this should always be called UNLESS swap fails, in which case payouts happen there // NOTE if relayerFeeAmount is incorrectly scaled, then the end user may receive nothing, and all proceeds go to relayer // it is incumbent upon the cross chain tx origin to ensure the relayerFeeAmount is passed correctly function payOut(bool unwrap, IERC20 finalToken, address recipient, uint256 relayerFeeAmount) internal returns (uint256 finalUserAmount) { uint256 totalBalance = finalToken.balanceOf(address(this)); // square up balances with what we actually have, don't trust reporting from the bridge if (relayerFeeAmount > totalBalance) { // control for underflow finalUserAmount = 0; relayerFeeAmount = totalBalance; } else { // user gets total - relayer fee finalUserAmount = totalBalance - relayerFeeAmount; } // if feeRecipient is not set, then send fees to msg.sender address feeRecipient = FEE_RECIPIENT == address(0x0) ? _msgSender() : FEE_RECIPIENT; if (unwrap) { WETH.withdraw(WETH.balanceOf(address(this))); if (finalUserAmount > 0) { // send to user sendEther(recipient, finalUserAmount); } if (relayerFeeAmount > 0) { // pay relayer fee sendEther(feeRecipient, relayerFeeAmount); } } else { // send to user if (finalUserAmount > 0) { finalToken.safeTransfer(recipient, finalUserAmount); } if (relayerFeeAmount > 0) { // pay relayer fee finalToken.safeTransfer(feeRecipient, relayerFeeAmount); } } } receive() external payable {} ///@dev https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/Utils.sol#L10-L15 function unpadAddress(bytes32 whFormatAddress) internal pure returns (address) { if (uint256(whFormatAddress) >> 160 != 0) { revert("Not EVM Addr"); } return address(uint160(uint256(whFormatAddress))); } ///@notice send ether without exposing to gas griefing attacks via returned bytes function sendEther(address to, uint256 value) internal { bool sent; assembly { sent := call(gas(), to, value, 0, 0, 0, 0) } if (!sent) { revert("failed to send ether"); } } } contract Portico is PorticoFinish, PorticoStart { constructor( ISwapRouter02 _routerV3, ITokenBridge _bridge, IWETH _weth, address _feeRecipient ) PorticoBase(_routerV3, _bridge, _weth, _feeRecipient) {} }
// SPDX-License-Identifier: UNLICENSE pragma solidity ^0.8.9; interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool success); function balanceOf(address account) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool success); function decimals() external view returns (uint8); function allowance(address owner, address spender) external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSE pragma solidity ^0.8.9; import "./IWETH.sol"; import "./IWormhole.sol"; interface ITokenBridge { struct Transfer { uint8 payloadID; uint256 amount; bytes32 tokenAddress; uint16 tokenChain; bytes32 to; uint16 toChain; uint256 fee; } struct TransferWithPayload { uint8 payloadID; uint256 amount; bytes32 tokenAddress; uint16 tokenChain; bytes32 to; uint16 toChain; bytes32 fromAddress; bytes payload; } struct AssetMeta { uint8 payloadID; bytes32 tokenAddress; uint16 tokenChain; uint8 decimals; bytes32 symbol; bytes32 name; } struct RegisterChain { bytes32 module; uint8 action; uint16 chainId; uint16 emitterChainID; bytes32 emitterAddress; } struct UpgradeContract { bytes32 module; uint8 action; uint16 chainId; bytes32 newContract; } struct RecoverChainId { bytes32 module; uint8 action; uint256 evmChainId; uint16 newChainId; } event ContractUpgraded(address indexed oldContract, address indexed newContract); event TransferRedeemed(uint16 indexed emitterChainId, bytes32 indexed emitterAddress, uint64 indexed sequence); function _parseTransferCommon(bytes memory encoded) external pure returns (Transfer memory transfer); function attestToken(address tokenAddress, uint32 nonce) external payable returns (uint64 sequence); function wrapAndTransferETH(uint16 recipientChain, bytes32 recipient, uint256 arbiterFee, uint32 nonce) external payable returns (uint64 sequence); function wrapAndTransferETHWithPayload(uint16 recipientChain, bytes32 recipient, uint32 nonce, bytes memory payload) external payable returns (uint64 sequence); function transferTokens(address token, uint256 amount, uint16 recipientChain, bytes32 recipient, uint256 arbiterFee, uint32 nonce) external payable returns (uint64 sequence); function transferTokensWithPayload(address token, uint256 amount, uint16 recipientChain, bytes32 recipient, uint32 nonce, bytes memory payload) external payable returns (uint64 sequence); function updateWrapped(bytes memory encodedVm) external returns (address token); function createWrapped(bytes memory encodedVm) external returns (address token); function completeTransferWithPayload(bytes memory encodedVm) external returns (bytes memory); function completeTransferAndUnwrapETHWithPayload(bytes memory encodedVm) external returns (bytes memory); function completeTransfer(bytes memory encodedVm) external; function completeTransferAndUnwrapETH(bytes memory encodedVm) external; function encodeAssetMeta(AssetMeta memory meta) external pure returns (bytes memory encoded); function encodeTransfer(Transfer memory transfer) external pure returns (bytes memory encoded); function encodeTransferWithPayload(TransferWithPayload memory transfer) external pure returns (bytes memory encoded); function parsePayloadID(bytes memory encoded) external pure returns (uint8 payloadID); function parseAssetMeta(bytes memory encoded) external pure returns (AssetMeta memory meta); function parseTransfer(bytes memory encoded) external pure returns (Transfer memory transfer); function parseTransferWithPayload(bytes memory encoded) external pure returns (TransferWithPayload memory transfer); function governanceActionIsConsumed(bytes32 hash) external view returns (bool); function isInitialized(address impl) external view returns (bool); function isTransferCompleted(bytes32 hash) external view returns (bool); function wormhole() external view returns (IWormhole); function chainId() external view returns (uint16); function evmChainId() external view returns (uint256); function isFork() external view returns (bool); function governanceChainId() external view returns (uint16); function governanceContract() external view returns (bytes32); function wrappedAsset(uint16 tokenChainId, bytes32 tokenAddress) external view returns (address); function bridgeContracts(uint16 chainId_) external view returns (bytes32); function tokenImplementation() external view returns (address); function WETH() external view returns (IWETH); function outstandingBridged(address token) external view returns (uint256); function isWrappedAsset(address token) external view returns (bool); function finality() external view returns (uint8); function implementation() external view returns (address); function initialize() external; function registerChain(bytes memory encodedVM) external; function upgrade(bytes memory encodedVM) external; function submitRecoverChainId(bytes memory encodedVM) external; function parseRegisterChain(bytes memory encoded) external pure returns (RegisterChain memory chain); function parseUpgrade(bytes memory encoded) external pure returns (UpgradeContract memory chain); function parseRecoverChainId(bytes memory encodedRecoverChainId) external pure returns (RecoverChainId memory rci); }
// SPDX-License-Identifier: UNLICENSE pragma solidity ^0.8.9; import "./IERC20.sol"; interface IWETH is IERC20{ function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; }
// SPDX-License-Identifier: UNLICENSE pragma solidity ^0.8.9; interface IWormhole { struct GuardianSet { address[] keys; uint32 expirationTime; } struct Signature { bytes32 r; bytes32 s; uint8 v; uint8 guardianIndex; } /** struct Signature { uint8 index; bytes signature; string name; } */ struct VM { uint8 version; uint32 timestamp; uint32 nonce; uint16 emitterChainId; bytes32 emitterAddress; uint64 sequence; uint8 consistencyLevel; bytes payload; uint32 guardianSetIndex; Signature[] signatures; bytes32 hash; } struct ContractUpgrade { bytes32 module; uint8 action; uint16 chain; address newContract; } struct GuardianSetUpgrade { bytes32 module; uint8 action; uint16 chain; GuardianSet newGuardianSet; uint32 newGuardianSetIndex; } struct SetMessageFee { bytes32 module; uint8 action; uint16 chain; uint256 messageFee; } struct TransferFees { bytes32 module; uint8 action; uint16 chain; uint256 amount; bytes32 recipient; } struct RecoverChainId { bytes32 module; uint8 action; uint256 evmChainId; uint16 newChainId; } event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel); event ContractUpgraded(address indexed oldContract, address indexed newContract); event GuardianSetAdded(uint32 indexed index); function publishMessage(uint32 nonce, bytes memory payload, uint8 consistencyLevel) external payable returns (uint64 sequence); function testSigs() external returns (Signature[] memory signatures); function test8() external returns (uint8 test); function testBytes() external returns (bytes memory payload); function testBigKahuna() external returns (VM memory vm); function initialize() external; function parseAndVerifyVM(bytes calldata encodedVM) external view returns (VM memory vm, bool valid, string memory reason); function verifyVM(VM memory vm) external view returns (bool valid, string memory reason); function verifySignatures( bytes32 hash, Signature[] memory signatures, GuardianSet memory guardianSet ) external pure returns (bool valid, string memory reason); function parseVM(bytes memory encodedVM) external pure returns (VM memory vm); function quorum(uint numGuardians) external pure returns (uint numSignaturesRequiredForQuorum); function getGuardianSet(uint32 index) external view returns (GuardianSet memory); function getCurrentGuardianSetIndex() external view returns (uint32); function getGuardianSetExpiry() external view returns (uint32); function governanceActionIsConsumed(bytes32 hash) external view returns (bool); function isInitialized(address impl) external view returns (bool); function chainId() external view returns (uint16); function isFork() external view returns (bool); function governanceChainId() external view returns (uint16); function governanceContract() external view returns (bytes32); function messageFee() external view returns (uint256); function evmChainId() external view returns (uint256); function nextSequence(address emitter) external view returns (uint64); function parseContractUpgrade(bytes memory encodedUpgrade) external pure returns (ContractUpgrade memory cu); function parseGuardianSetUpgrade(bytes memory encodedUpgrade) external pure returns (GuardianSetUpgrade memory gsu); function parseSetMessageFee(bytes memory encodedSetMessageFee) external pure returns (SetMessageFee memory smf); function parseTransferFees(bytes memory encodedTransferFees) external pure returns (TransferFees memory tf); function parseRecoverChainId(bytes memory encodedRecoverChainId) external pure returns (RecoverChainId memory rci); function submitContractUpgrade(bytes memory _vm) external; function submitSetMessageFee(bytes memory _vm) external; function submitNewGuardianSet(bytes memory _vm) external; function submitTransferFees(bytes memory _vm) external; function submitRecoverChainId(bytes memory _vm) external; }
// 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 // OpenZeppelin Contracts (last updated v5.0.0) (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; } }
// 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 ERC-20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. * * Adds the {permit} method, which can be used to change an account's ERC-20 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) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "./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.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// 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 "./IERC20Permit.sol"; import {Address} from "./Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 ERC-20 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: UNLICENSE pragma solidity ^0.8.9; import "./IERC20.sol"; type PorticoFlagSet is bytes32; library PorticoFlagSetAccess { // the portico uses one word (32 bytes) to represent a large amount of variables // bytes 0-1 is the recipient chain function recipientChain(PorticoFlagSet flagset) internal pure returns (uint16 ans) { assembly { ans := add(byte(0, flagset), shl(8, byte(1, flagset))) } } // bytes 2-5 is the bridge nonce function bridgeNonce(PorticoFlagSet flagset) internal pure returns (uint32 ans) { assembly { ans := add(add(add(byte(2, flagset), shl(8, byte(3, flagset))), shl(16, byte(4, flagset))), shl(24, byte(5, flagset))) } } // bytes 6,7,8 is the fee tier for start path function feeTierStart(PorticoFlagSet flagset) internal pure returns (uint24 ans) { assembly { ans := add(add(byte(6, flagset), shl(8, byte(7, flagset))), shl(16, byte(8, flagset))) } } // bytes 9,10,11 is the fee tier for finish path function feeTierFinish(PorticoFlagSet flagset) internal pure returns (uint24 ans) { assembly { ans := add(add(byte(9, flagset), shl(8, byte(10, flagset))), shl(16, byte(11, flagset))) } } // shouldWrapNative is the first bit of the byte 31 function shouldWrapNative(PorticoFlagSet flagset) internal pure returns (bool) { bytes32 fs = PorticoFlagSet.unwrap(flagset); return uint8(fs[31]) & (1 << 0) > 0; } // shouldUnwrapNative is the second bit of byte 31 function shouldUnwrapNative(PorticoFlagSet flagset) internal pure returns (bool) { bytes32 fs = PorticoFlagSet.unwrap(flagset); return uint8(fs[31]) & (1 << 1) > 0; } } library PorticoStructs { //https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/main/src/WormholeRelayerSDK.sol#L177 //https://docs.wormhole.com/wormhole/quick-start/tutorials/hello-token#receiving-a-token struct TokenReceived { bytes32 tokenHomeAddress; uint16 tokenHomeChain; IERC20 tokenAddress; uint256 amount; } //268,090 - to beat struct TradeParameters { PorticoFlagSet flags; IERC20 startTokenAddress; IERC20 canonAssetAddress; IERC20 finalTokenAddress; // address of the recipient on the recipientChain address recipientAddress; // address of the portico on the recipient chain address recipientPorticoAddress; // the amount of the token that the person wishes to transfer uint256 amountSpecified; uint256 minAmountStart; uint256 minAmountFinish; uint256 relayerFee; // the amount of tokens of the recipient to give to the relayer } //268,041 158,788 struct DecodedVAA { PorticoFlagSet flags; IERC20 finalTokenAddress; // the person to receive the token address recipientAddress; // the x asset amount expected to be received uint256 canonAssetAmount; uint256 minAmountFinish; uint256 relayerFee; } struct BridgeInfo { IERC20 tokenReceived; uint256 amountReceived; uint256 relayerFeeAmount; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter02 { function factory() external view returns (address); //frusturatingly, there is no deadline in this set of params //used on SwapRouter02 on Base chain struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @dev Setting `amountIn` to 0 will cause the contract to look up its own balance, /// and swap the entire amount, enabling contracts to send tokens before calling this function. /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); }
{ "optimizer": { "enabled": true, "runs": 200, "details": { "orderLiterals": true, "deduplicate": true, "cse": true, "yul": true } }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ISwapRouter02","name":"_routerV3","type":"address"},{"internalType":"contract ITokenBridge","name":"_bridge","type":"address"},{"internalType":"contract IWETH","name":"_weth","type":"address"},{"internalType":"address","name":"_feeRecipient","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":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"swapCompleted","type":"bool"},{"indexed":false,"internalType":"uint256","name":"finaluserAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"relayerFeeAmount","type":"uint256"},{"components":[{"internalType":"PorticoFlagSet","name":"flags","type":"bytes32"},{"internalType":"contract IERC20","name":"finalTokenAddress","type":"address"},{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint256","name":"canonAssetAmount","type":"uint256"},{"internalType":"uint256","name":"minAmountFinish","type":"uint256"},{"internalType":"uint256","name":"relayerFee","type":"uint256"}],"indexed":false,"internalType":"struct PorticoStructs.DecodedVAA","name":"data","type":"tuple"}],"name":"PorticoSwapFinish","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":true,"internalType":"uint16","name":"chainId","type":"uint16"}],"name":"PorticoSwapStart","type":"event"},{"inputs":[],"name":"FEE_RECIPIENT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROUTERV3","outputs":[{"internalType":"contract ISwapRouter02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKENBRIDGE","outputs":[{"internalType":"contract ITokenBridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedTransferMessage","type":"bytes"}],"name":"receiveMessageAndSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeRecipient","type":"address"}],"name":"setFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"PorticoFlagSet","name":"flags","type":"bytes32"},{"internalType":"contract IERC20","name":"startTokenAddress","type":"address"},{"internalType":"contract IERC20","name":"canonAssetAddress","type":"address"},{"internalType":"contract IERC20","name":"finalTokenAddress","type":"address"},{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"address","name":"recipientPorticoAddress","type":"address"},{"internalType":"uint256","name":"amountSpecified","type":"uint256"},{"internalType":"uint256","name":"minAmountStart","type":"uint256"},{"internalType":"uint256","name":"minAmountFinish","type":"uint256"},{"internalType":"uint256","name":"relayerFee","type":"uint256"}],"internalType":"struct PorticoStructs.TradeParameters","name":"params","type":"tuple"}],"name":"start","outputs":[{"internalType":"address","name":"emitterAddress","type":"address"},{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"wormhole","outputs":[{"internalType":"contract IWormhole","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wormholeChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101206040523480156200001257600080fd5b50604051620025b6380380620025b68339810160408190526200003591620001fe565b8383838333806200006057604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200006b8162000195565b50600180556001600160a01b03808516608052831660a0819052604080516384acd1bb60e01b815290516384acd1bb916004808201926020929091908290030181865afa158015620000c1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e7919062000266565b6001600160a01b0390811660e081905290831660c05260408051634d4502c960e11b81529051639a8a0592916004808201926020929091908290030181865afa15801562000139573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200015f91906200028d565b61ffff1661010052600280546001600160a01b0319166001600160a01b039290921691909117905550620002b395505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114620001fb57600080fd5b50565b600080600080608085870312156200021557600080fd5b84516200022281620001e5565b60208601519094506200023581620001e5565b60408601519093506200024881620001e5565b60608601519092506200025b81620001e5565b939692955090935050565b6000602082840312156200027957600080fd5b81516200028681620001e5565b9392505050565b600060208284031215620002a057600080fd5b815161ffff811681146200028657600080fd5b60805160a05160c05160e0516101005161223a6200037c600039600081816101bc0152818161090901528181610bd00152610c6601526000818161020301526103f301526000818161029a0152818161047c01528181610522015281816105aa01528181610e1a01526113cc01526000818160e40152818161077d015281816108020152818161092c01528181610a9101528181610b150152610cc00152600081816101730152818161104c015281816110780152818161159601526115db015261223a6000f3fe6080604052600436106100c65760003560e01c806384acd1bb1161007f578063ad5c464811610059578063ad5c464814610288578063e74b981b146102bc578063ebd09054146102dc578063f2fde38b146102fc57600080fd5b806384acd1bb146101f15780638da5cb5b146102255780639a4896fe1461024357600080fd5b806315a3d8f5146100d25780633d528f351461012357806354fd4d50146101455780635e3caf6914610161578063715018a614610195578063793e64e3146101aa57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506101067f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012f57600080fd5b5061014361013e366004611a40565b61031c565b005b34801561015157600080fd5b506040516001815260200161011a565b34801561016d57600080fd5b506101067f000000000000000000000000000000000000000000000000000000000000000081565b3480156101a157600080fd5b506101436103cd565b3480156101b657600080fd5b506101de7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161011a565b3480156101fd57600080fd5b506101067f000000000000000000000000000000000000000000000000000000000000000081565b34801561023157600080fd5b506000546001600160a01b0316610106565b610256610251366004611b3b565b6103e1565b604080516001600160a01b03909416845261ffff909216602084015267ffffffffffffffff169082015260600161011a565b34801561029457600080fd5b506101067f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c857600080fd5b506101436102d7366004611be2565b61099d565b3480156102e857600080fd5b50600254610106906001600160a01b031681565b34801561030857600080fd5b50610143610317366004611be2565b6109c7565b610324610a05565b6000806103318484610a2f565b9150915081604001516001600160a01b031661034a3390565b6001600160a01b031614610362578160a00151610365565b60005b60408201526000806103778484610dfc565b915091507fc2addcb063016f6dc1647fc8cd7206c3436cc4293c4acffe4feac288459ca7fc82828560400151876040516103b49493929190611c47565b60405180910390a1505050506103c960018055565b5050565b6103d5610f5b565b6103df6000610f88565b565b60008060006103ee610a05565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561044f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104739190611c6c565b905060003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031687602001516001600160a01b03161480156104c25750865160011615155b1561062857818760c001516104d79190611c9b565b81146105205760405162461bcd60e51b81526020600482015260136024820152721b5cd9cb9d985b1d59481a5b98dbdc9c9958dd606a1b60448201526064015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08860c001516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561057f57600080fd5b505af1158015610593573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031693506370a0823192506024019050602060405180830381865afa1580156105fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106219190611c6c565b92506106fe565b81811461066d5760405162461bcd60e51b81526020600482015260136024820152721b5cd9cb9d985b1d59481a5b98dbdc9c9958dd606a1b6044820152606401610517565b61068d3360c089015160208a01516001600160a01b031691903090610fd8565b60208701516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156106d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fb9190611c6c565b92505b8660c0015183101561074a5760405162461bcd60e51b81526020600482015260156024820152741d1c985b9cd9995c881a5b9cdd59999a58da595b9d605a1b6044820152606401610517565b86604001516001600160a01b031687602001516001600160a01b031614610778576107758784611045565b92505b6107a77f0000000000000000000000000000000000000000000000000000000000000000886040015185611207565b60006040518060c001604052808960000151815260200189606001516001600160a01b0316815260200189608001516001600160a01b03168152602001858152602001896101000151815260200189610120015181525090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c5a5ebda848a60400151876108508d60000151600081901a60019190911a60081b0190565b60a08e01516001600160a01b03168e51600281901a600382901a60081b01600482901a60101b0160059190911a60181b01886040516020016108929190611cae565b6040516020818303038152906040526040518863ffffffff1660e01b81526004016108c296959493929190611d0c565b60206040518083038185885af11580156108e0573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109059190611d5b565b94507f000000000000000000000000000000000000000000000000000000000000000095507f000000000000000000000000000000000000000000000000000000000000000096508561ffff168567ffffffffffffffff167f29bbdeaf59aab4b88cf0ec8a729f885d1b957311a49de002e7db6620e390467060405160405180910390a35050505061099660018055565b9193909250565b6109a5610f5b565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6109cf610f5b565b6001600160a01b0381166109f957604051631e4fbdf760e01b815260006004820152602401610517565b610a0281610f88565b50565b600260015403610a2857604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519081018552828152908101829052928301529060405163c3f511c160e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c3f511c190610ac89088908890600401611d85565b6000604051808303816000875af1158015610ae7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b0f9190810190611e32565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ea63738d836040518263ffffffff1660e01b8152600401610b5f9190611e6f565b600060405180830381865afa158015610b7c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ba49190810190611ea5565b9050306001600160a01b0316610bbd82608001516112b1565b6001600160a01b0316148015610bfe57507f000000000000000000000000000000000000000000000000000000000000000061ffff168160a0015161ffff16145b610c4a5760405162461bcd60e51b815260206004820152601e60248201527f546f6b656e206e6f742073656e7420746f2074686973206164647265737300006044820152606401610517565b8060e00151806020019051810190610c629190611f6e565b93507f000000000000000000000000000000000000000000000000000000000000000061ffff16816060015161ffff1614610d385760608101516040808301519051630ff8f14360e11b815261ffff909216600483015260248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ff1e28690604401602060405180830381865afa158015610d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d339190611ffa565b610d45565b610d4581604001516112b1565b6001600160a01b0316808452602080830151818601526040805163313ce56760e01b815290516000939263313ce56792600480820193918290030181865afa158015610d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db99190612017565b905060088160ff161115610df257610dd2600882612032565b610ddd90600a61212f565b84602001818151610dee919061213e565b9052505b5050509250929050565b6000806000610e118560000151600216151590565b8015610e5257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685602001516001600160a01b0316145b905083600001516001600160a01b031685602001516001600160a01b031603610e9957610e8d818660200151876040015187604001516112f8565b91506000925050610f54565b610ea385856114fd565b925082610f385783516040868101516020870151915163a9059cbb60e01b81526001600160a01b03918216600482015260248101929092529091169063a9059cbb906044016020604051808303816000875af1158015610f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2b9190612155565b5050506020820151610f54565b610f50818660200151876040015187604001516112f8565b9150505b9250929050565b6000546001600160a01b031633146103df5760405163118cdaa760e01b8152336004820152602401610517565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b03848116602483015283811660448301526064820183905261103f9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061165d565b50505050565b60006110767f0000000000000000000000000000000000000000000000000000000000000000846020015184611207565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166304e45aaf6040518060e0016040528086602001516001600160a01b0316815260200186604001516001600160a01b031681526020016110fb876000015160008160081a60101b8260071a60081b8360061a01019050919050565b62ffffff168152602001306001600160a01b031681526020018581526020018660e00151815260200160006001600160a01b03168152506040518263ffffffff1660e01b815260040161114e9190612177565b6020604051808303816000875af115801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111919190611c6c565b5060408084015190516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190611c6c565b9392505050565b604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301526000919084169063dd62ed3e90604401602060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190611c6c565b90508181101561103f5761103f84611294836001611c9b565b6112a0906000196121d5565b6001600160a01b03861691906116c5565b600060a082901c156112f45760405162461bcd60e51b815260206004820152600c60248201526b2737ba1022ab269020b2323960a11b6044820152606401610517565b5090565b6040516370a0823160e01b815230600482015260009081906001600160a01b038616906370a0823190602401602060405180830381865afa158015611341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113659190611c6c565b90508083111561137b5760009150809250611388565b61138583826121d5565b91505b6002546000906001600160a01b0316156113ad576002546001600160a01b03166113af565b335b905086156114bf576040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d9082906370a0823190602401602060405180830381865afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114479190611c6c565b6040518263ffffffff1660e01b815260040161146591815260200190565b600060405180830381600087803b15801561147f57600080fd5b505af1158015611493573d6000803e3d6000fd5b5050505060008311156114aa576114aa858461174f565b83156114ba576114ba818561174f565b6114f3565b82156114d9576114d96001600160a01b03871686856117a1565b83156114f3576114f36001600160a01b03871682866117a1565b5050949350505050565b6000806040518060e0016040528084600001516001600160a01b0316815260200185602001516001600160a01b031681526020016115548660000151600981901a600a82901a60081b01600b9190911a60101b0190565b62ffffff168152602001306001600160a01b03168152602001846020015181526020018560800151815260200160006001600160a01b031681525090506115c47f000000000000000000000000000000000000000000000000000000000000000084600001518560200151611207565b6040516304e45aaf60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906304e45aaf90611610908490600401612177565b6020604051808303816000875af192505050801561164b575060408051601f3d908101601f1916820190925261164891810190611c6c565b60015b156116565750600191505b5092915050565b60006116726001600160a01b038416836117d2565b905080516000141580156116975750808060200190518101906116959190612155565b155b156116c057604051635274afe760e01b81526001600160a01b0384166004820152602401610517565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015611715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117399190611c6c565b905061103f848461174a8585611c9b565b6117e6565b600080600080600085875af19050806116c05760405162461bcd60e51b81526020600482015260146024820152733330b4b632b2103a379039b2b7321032ba3432b960611b6044820152606401610517565b6040516001600160a01b038381166024830152604482018390526116c091859182169063a9059cbb9060640161100d565b606061120083836000611876565b92915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526118378482611913565b61103f576040516001600160a01b0384811660248301526000604483015261186c91869182169063095ea7b39060640161100d565b61103f848261165d565b60608147101561189b5760405163cd78605960e01b8152306004820152602401610517565b600080856001600160a01b031684866040516118b791906121e8565b60006040518083038185875af1925050503d80600081146118f4576040519150601f19603f3d011682016040523d82523d6000602084013e6118f9565b606091505b50915091506119098683836119bb565b9695505050505050565b6000806000846001600160a01b03168460405161193091906121e8565b6000604051808303816000865af19150503d806000811461196d576040519150601f19603f3d011682016040523d82523d6000602084013e611972565b606091505b509150915081801561199c57508051158061199c57508080602001905181019061199c9190612155565b80156119b257506000856001600160a01b03163b115b95945050505050565b6060826119d0576119cb82611a17565b611200565b81511580156119e757506001600160a01b0384163b155b15611a1057604051639996b31560e01b81526001600160a01b0385166004820152602401610517565b5080611200565b805115611a275780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60008060208385031215611a5357600080fd5b823567ffffffffffffffff80821115611a6b57600080fd5b818501915085601f830112611a7f57600080fd5b813581811115611a8e57600080fd5b866020828501011115611aa057600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611aec57611aec611ab2565b60405290565b604051610100810167ffffffffffffffff81118282101715611aec57611aec611ab2565b6001600160a01b0381168114610a0257600080fd5b8035611b3681611b16565b919050565b60006101408284031215611b4e57600080fd5b611b56611ac8565b82358152611b6660208401611b2b565b6020820152611b7760408401611b2b565b6040820152611b8860608401611b2b565b6060820152611b9960808401611b2b565b6080820152611baa60a08401611b2b565b60a082015260c0838101359082015260e080840135908201526101008084013590820152610120928301359281019290925250919050565b600060208284031215611bf457600080fd5b813561120081611b16565b80518252602081015160018060a01b0380821660208501528060408401511660408501525050606081015160608301526080810151608083015260a081015160a08301525050565b8415158152602081018490526040810183905261012081016119b26060830184611bff565b600060208284031215611c7e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156117e0576117e0611c85565b60c081016117e08284611bff565b60005b83811015611cd7578181015183820152602001611cbf565b50506000910152565b60008151808452611cf8816020860160208601611cbc565b601f01601f19169290920160200192915050565b60018060a01b038716815285602082015261ffff8516604082015283606082015263ffffffff8316608082015260c060a08201526000611d4f60c0830184611ce0565b98975050505050505050565b600060208284031215611d6d57600080fd5b815167ffffffffffffffff8116811461120057600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600082601f830112611dc557600080fd5b815167ffffffffffffffff80821115611de057611de0611ab2565b604051601f8301601f19908116603f01168101908282118183101715611e0857611e08611ab2565b81604052838152866020858801011115611e2157600080fd5b611909846020830160208901611cbc565b600060208284031215611e4457600080fd5b815167ffffffffffffffff811115611e5b57600080fd5b611e6784828501611db4565b949350505050565b6020815260006112006020830184611ce0565b805160ff81168114611b3657600080fd5b805161ffff81168114611b3657600080fd5b600060208284031215611eb757600080fd5b815167ffffffffffffffff80821115611ecf57600080fd5b908301906101008286031215611ee457600080fd5b611eec611af2565b611ef583611e82565b81526020830151602082015260408301516040820152611f1760608401611e93565b606082015260808301516080820152611f3260a08401611e93565b60a082015260c083015160c082015260e083015182811115611f5357600080fd5b611f5f87828601611db4565b60e08301525095945050505050565b600060c08284031215611f8057600080fd5b60405160c0810181811067ffffffffffffffff82111715611fa357611fa3611ab2565b604052825181526020830151611fb881611b16565b60208201526040830151611fcb81611b16565b80604083015250606083015160608201526080830151608082015260a083015160a08201528091505092915050565b60006020828403121561200c57600080fd5b815161120081611b16565b60006020828403121561202957600080fd5b61120082611e82565b60ff82811682821603908111156117e0576117e0611c85565b600181815b8085111561208657816000190482111561206c5761206c611c85565b8085161561207957918102915b93841c9390800290612050565b509250929050565b60008261209d575060016117e0565b816120aa575060006117e0565b81600181146120c057600281146120ca576120e6565b60019150506117e0565b60ff8411156120db576120db611c85565b50506001821b6117e0565b5060208310610133831016604e8410600b8410161715612109575081810a6117e0565b612113838361204b565b806000190482111561212757612127611c85565b029392505050565b600061120060ff84168361208e565b80820281158282048414176117e0576117e0611c85565b60006020828403121561216757600080fd5b8151801515811461120057600080fd5b81516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c092830151169181019190915260e00190565b818103818111156117e0576117e0611c85565b600082516121fa818460208701611cbc565b919091019291505056fea2646970667358221220f3bd59e6cb6a3eb18a2cdad6abde82fa285014e470f0d2d7b8ccbad0f6fba6c664736f6c6343000814003300000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc450000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106100c65760003560e01c806384acd1bb1161007f578063ad5c464811610059578063ad5c464814610288578063e74b981b146102bc578063ebd09054146102dc578063f2fde38b146102fc57600080fd5b806384acd1bb146101f15780638da5cb5b146102255780639a4896fe1461024357600080fd5b806315a3d8f5146100d25780633d528f351461012357806354fd4d50146101455780635e3caf6914610161578063715018a614610195578063793e64e3146101aa57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506101067f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa58581565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012f57600080fd5b5061014361013e366004611a40565b61031c565b005b34801561015157600080fd5b506040516001815260200161011a565b34801561016d57600080fd5b506101067f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4581565b3480156101a157600080fd5b506101436103cd565b3480156101b657600080fd5b506101de7f000000000000000000000000000000000000000000000000000000000000000281565b60405161ffff909116815260200161011a565b3480156101fd57600080fd5b506101067f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b81565b34801561023157600080fd5b506000546001600160a01b0316610106565b610256610251366004611b3b565b6103e1565b604080516001600160a01b03909416845261ffff909216602084015267ffffffffffffffff169082015260600161011a565b34801561029457600080fd5b506101067f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b3480156102c857600080fd5b506101436102d7366004611be2565b61099d565b3480156102e857600080fd5b50600254610106906001600160a01b031681565b34801561030857600080fd5b50610143610317366004611be2565b6109c7565b610324610a05565b6000806103318484610a2f565b9150915081604001516001600160a01b031661034a3390565b6001600160a01b031614610362578160a00151610365565b60005b60408201526000806103778484610dfc565b915091507fc2addcb063016f6dc1647fc8cd7206c3436cc4293c4acffe4feac288459ca7fc82828560400151876040516103b49493929190611c47565b60405180910390a1505050506103c960018055565b5050565b6103d5610f5b565b6103df6000610f88565b565b60008060006103ee610a05565b6000807f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561044f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104739190611c6c565b905060003490507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031687602001516001600160a01b03161480156104c25750865160011615155b1561062857818760c001516104d79190611c9b565b81146105205760405162461bcd60e51b81526020600482015260136024820152721b5cd9cb9d985b1d59481a5b98dbdc9c9958dd606a1b60448201526064015b60405180910390fd5b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db08860c001516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561057f57600080fd5b505af1158015610593573d6000803e3d6000fd5b50506040516370a0823160e01b81523060048201527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031693506370a0823192506024019050602060405180830381865afa1580156105fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106219190611c6c565b92506106fe565b81811461066d5760405162461bcd60e51b81526020600482015260136024820152721b5cd9cb9d985b1d59481a5b98dbdc9c9958dd606a1b6044820152606401610517565b61068d3360c089015160208a01516001600160a01b031691903090610fd8565b60208701516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156106d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fb9190611c6c565b92505b8660c0015183101561074a5760405162461bcd60e51b81526020600482015260156024820152741d1c985b9cd9995c881a5b9cdd59999a58da595b9d605a1b6044820152606401610517565b86604001516001600160a01b031687602001516001600160a01b031614610778576107758784611045565b92505b6107a77f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585886040015185611207565b60006040518060c001604052808960000151815260200189606001516001600160a01b0316815260200189608001516001600160a01b03168152602001858152602001896101000151815260200189610120015181525090507f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa5856001600160a01b031663c5a5ebda848a60400151876108508d60000151600081901a60019190911a60081b0190565b60a08e01516001600160a01b03168e51600281901a600382901a60081b01600482901a60101b0160059190911a60181b01886040516020016108929190611cae565b6040516020818303038152906040526040518863ffffffff1660e01b81526004016108c296959493929190611d0c565b60206040518083038185885af11580156108e0573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109059190611d5b565b94507f000000000000000000000000000000000000000000000000000000000000000295507f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa58596508561ffff168567ffffffffffffffff167f29bbdeaf59aab4b88cf0ec8a729f885d1b957311a49de002e7db6620e390467060405160405180910390a35050505061099660018055565b9193909250565b6109a5610f5b565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6109cf610f5b565b6001600160a01b0381166109f957604051631e4fbdf760e01b815260006004820152602401610517565b610a0281610f88565b50565b600260015403610a2857604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519081018552828152908101829052928301529060405163c3f511c160e01b81526000906001600160a01b037f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585169063c3f511c190610ac89088908890600401611d85565b6000604051808303816000875af1158015610ae7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b0f9190810190611e32565b905060007f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa5856001600160a01b031663ea63738d836040518263ffffffff1660e01b8152600401610b5f9190611e6f565b600060405180830381865afa158015610b7c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ba49190810190611ea5565b9050306001600160a01b0316610bbd82608001516112b1565b6001600160a01b0316148015610bfe57507f000000000000000000000000000000000000000000000000000000000000000261ffff168160a0015161ffff16145b610c4a5760405162461bcd60e51b815260206004820152601e60248201527f546f6b656e206e6f742073656e7420746f2074686973206164647265737300006044820152606401610517565b8060e00151806020019051810190610c629190611f6e565b93507f000000000000000000000000000000000000000000000000000000000000000261ffff16816060015161ffff1614610d385760608101516040808301519051630ff8f14360e11b815261ffff909216600483015260248201527f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa5856001600160a01b031690631ff1e28690604401602060405180830381865afa158015610d0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d339190611ffa565b610d45565b610d4581604001516112b1565b6001600160a01b0316808452602080830151818601526040805163313ce56760e01b815290516000939263313ce56792600480820193918290030181865afa158015610d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db99190612017565b905060088160ff161115610df257610dd2600882612032565b610ddd90600a61212f565b84602001818151610dee919061213e565b9052505b5050509250929050565b6000806000610e118560000151600216151590565b8015610e5257507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031685602001516001600160a01b0316145b905083600001516001600160a01b031685602001516001600160a01b031603610e9957610e8d818660200151876040015187604001516112f8565b91506000925050610f54565b610ea385856114fd565b925082610f385783516040868101516020870151915163a9059cbb60e01b81526001600160a01b03918216600482015260248101929092529091169063a9059cbb906044016020604051808303816000875af1158015610f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2b9190612155565b5050506020820151610f54565b610f50818660200151876040015187604001516112f8565b9150505b9250929050565b6000546001600160a01b031633146103df5760405163118cdaa760e01b8152336004820152602401610517565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b03848116602483015283811660448301526064820183905261103f9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061165d565b50505050565b60006110767f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45846020015184611207565b7f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc456001600160a01b03166304e45aaf6040518060e0016040528086602001516001600160a01b0316815260200186604001516001600160a01b031681526020016110fb876000015160008160081a60101b8260071a60081b8360061a01019050919050565b62ffffff168152602001306001600160a01b031681526020018581526020018660e00151815260200160006001600160a01b03168152506040518263ffffffff1660e01b815260040161114e9190612177565b6020604051808303816000875af115801561116d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111919190611c6c565b5060408084015190516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190611c6c565b9392505050565b604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301526000919084169063dd62ed3e90604401602060405180830381865afa158015611257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061127b9190611c6c565b90508181101561103f5761103f84611294836001611c9b565b6112a0906000196121d5565b6001600160a01b03861691906116c5565b600060a082901c156112f45760405162461bcd60e51b815260206004820152600c60248201526b2737ba1022ab269020b2323960a11b6044820152606401610517565b5090565b6040516370a0823160e01b815230600482015260009081906001600160a01b038616906370a0823190602401602060405180830381865afa158015611341573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113659190611c6c565b90508083111561137b5760009150809250611388565b61138583826121d5565b91505b6002546000906001600160a01b0316156113ad576002546001600160a01b03166113af565b335b905086156114bf576040516370a0823160e01b81523060048201527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d9082906370a0823190602401602060405180830381865afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114479190611c6c565b6040518263ffffffff1660e01b815260040161146591815260200190565b600060405180830381600087803b15801561147f57600080fd5b505af1158015611493573d6000803e3d6000fd5b5050505060008311156114aa576114aa858461174f565b83156114ba576114ba818561174f565b6114f3565b82156114d9576114d96001600160a01b03871686856117a1565b83156114f3576114f36001600160a01b03871682866117a1565b5050949350505050565b6000806040518060e0016040528084600001516001600160a01b0316815260200185602001516001600160a01b031681526020016115548660000151600981901a600a82901a60081b01600b9190911a60101b0190565b62ffffff168152602001306001600160a01b03168152602001846020015181526020018560800151815260200160006001600160a01b031681525090506115c47f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4584600001518560200151611207565b6040516304e45aaf60e01b81526001600160a01b037f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4516906304e45aaf90611610908490600401612177565b6020604051808303816000875af192505050801561164b575060408051601f3d908101601f1916820190925261164891810190611c6c565b60015b156116565750600191505b5092915050565b60006116726001600160a01b038416836117d2565b905080516000141580156116975750808060200190518101906116959190612155565b155b156116c057604051635274afe760e01b81526001600160a01b0384166004820152602401610517565b505050565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015611715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117399190611c6c565b905061103f848461174a8585611c9b565b6117e6565b600080600080600085875af19050806116c05760405162461bcd60e51b81526020600482015260146024820152733330b4b632b2103a379039b2b7321032ba3432b960611b6044820152606401610517565b6040516001600160a01b038381166024830152604482018390526116c091859182169063a9059cbb9060640161100d565b606061120083836000611876565b92915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526118378482611913565b61103f576040516001600160a01b0384811660248301526000604483015261186c91869182169063095ea7b39060640161100d565b61103f848261165d565b60608147101561189b5760405163cd78605960e01b8152306004820152602401610517565b600080856001600160a01b031684866040516118b791906121e8565b60006040518083038185875af1925050503d80600081146118f4576040519150601f19603f3d011682016040523d82523d6000602084013e6118f9565b606091505b50915091506119098683836119bb565b9695505050505050565b6000806000846001600160a01b03168460405161193091906121e8565b6000604051808303816000865af19150503d806000811461196d576040519150601f19603f3d011682016040523d82523d6000602084013e611972565b606091505b509150915081801561199c57508051158061199c57508080602001905181019061199c9190612155565b80156119b257506000856001600160a01b03163b115b95945050505050565b6060826119d0576119cb82611a17565b611200565b81511580156119e757506001600160a01b0384163b155b15611a1057604051639996b31560e01b81526001600160a01b0385166004820152602401610517565b5080611200565b805115611a275780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60008060208385031215611a5357600080fd5b823567ffffffffffffffff80821115611a6b57600080fd5b818501915085601f830112611a7f57600080fd5b813581811115611a8e57600080fd5b866020828501011115611aa057600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715611aec57611aec611ab2565b60405290565b604051610100810167ffffffffffffffff81118282101715611aec57611aec611ab2565b6001600160a01b0381168114610a0257600080fd5b8035611b3681611b16565b919050565b60006101408284031215611b4e57600080fd5b611b56611ac8565b82358152611b6660208401611b2b565b6020820152611b7760408401611b2b565b6040820152611b8860608401611b2b565b6060820152611b9960808401611b2b565b6080820152611baa60a08401611b2b565b60a082015260c0838101359082015260e080840135908201526101008084013590820152610120928301359281019290925250919050565b600060208284031215611bf457600080fd5b813561120081611b16565b80518252602081015160018060a01b0380821660208501528060408401511660408501525050606081015160608301526080810151608083015260a081015160a08301525050565b8415158152602081018490526040810183905261012081016119b26060830184611bff565b600060208284031215611c7e57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156117e0576117e0611c85565b60c081016117e08284611bff565b60005b83811015611cd7578181015183820152602001611cbf565b50506000910152565b60008151808452611cf8816020860160208601611cbc565b601f01601f19169290920160200192915050565b60018060a01b038716815285602082015261ffff8516604082015283606082015263ffffffff8316608082015260c060a08201526000611d4f60c0830184611ce0565b98975050505050505050565b600060208284031215611d6d57600080fd5b815167ffffffffffffffff8116811461120057600080fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600082601f830112611dc557600080fd5b815167ffffffffffffffff80821115611de057611de0611ab2565b604051601f8301601f19908116603f01168101908282118183101715611e0857611e08611ab2565b81604052838152866020858801011115611e2157600080fd5b611909846020830160208901611cbc565b600060208284031215611e4457600080fd5b815167ffffffffffffffff811115611e5b57600080fd5b611e6784828501611db4565b949350505050565b6020815260006112006020830184611ce0565b805160ff81168114611b3657600080fd5b805161ffff81168114611b3657600080fd5b600060208284031215611eb757600080fd5b815167ffffffffffffffff80821115611ecf57600080fd5b908301906101008286031215611ee457600080fd5b611eec611af2565b611ef583611e82565b81526020830151602082015260408301516040820152611f1760608401611e93565b606082015260808301516080820152611f3260a08401611e93565b60a082015260c083015160c082015260e083015182811115611f5357600080fd5b611f5f87828601611db4565b60e08301525095945050505050565b600060c08284031215611f8057600080fd5b60405160c0810181811067ffffffffffffffff82111715611fa357611fa3611ab2565b604052825181526020830151611fb881611b16565b60208201526040830151611fcb81611b16565b80604083015250606083015160608201526080830151608082015260a083015160a08201528091505092915050565b60006020828403121561200c57600080fd5b815161120081611b16565b60006020828403121561202957600080fd5b61120082611e82565b60ff82811682821603908111156117e0576117e0611c85565b600181815b8085111561208657816000190482111561206c5761206c611c85565b8085161561207957918102915b93841c9390800290612050565b509250929050565b60008261209d575060016117e0565b816120aa575060006117e0565b81600181146120c057600281146120ca576120e6565b60019150506117e0565b60ff8411156120db576120db611c85565b50506001821b6117e0565b5060208310610133831016604e8410600b8410161715612109575081810a6117e0565b612113838361204b565b806000190482111561212757612127611c85565b029392505050565b600061120060ff84168361208e565b80820281158282048414176117e0576117e0611c85565b60006020828403121561216757600080fd5b8151801515811461120057600080fd5b81516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c092830151169181019190915260e00190565b818103818111156117e0576117e0611c85565b600082516121fa818460208701611cbc565b919091019291505056fea2646970667358221220f3bd59e6cb6a3eb18a2cdad6abde82fa285014e470f0d2d7b8ccbad0f6fba6c664736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc450000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _routerV3 (address): 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
Arg [1] : _bridge (address): 0x3ee18B2214AFF97000D974cf647E7C347E8fa585
Arg [2] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [3] : _feeRecipient (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45
Arg [1] : 0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
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.