Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
20.258631074743486489 ETH
Eth Value
$66,388.90 (@ $3,277.07/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 110,070 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unlock Batch | 21463533 | 23 mins ago | IN | 0 ETH | 0.00086972 | ||||
Fulfill Order | 21463520 | 26 mins ago | IN | 0.73245313 ETH | 0.00102359 | ||||
Fulfill Order | 21463499 | 30 mins ago | IN | 0 ETH | 0.00128908 | ||||
Unlock Batch | 21463493 | 31 mins ago | IN | 0 ETH | 0.00139916 | ||||
Refund Order | 21463457 | 38 mins ago | IN | 0 ETH | 0.00166987 | ||||
Unlock Batch | 21463391 | 51 mins ago | IN | 0 ETH | 0.00150585 | ||||
Fulfill Order | 21463315 | 1 hr ago | IN | 1.44326469 ETH | 0.00123024 | ||||
Fulfill Order | 21463303 | 1 hr ago | IN | 0 ETH | 0.00139908 | ||||
Unlock Batch | 21463290 | 1 hr ago | IN | 0 ETH | 0.00148874 | ||||
Refund Order | 21463274 | 1 hr ago | IN | 0 ETH | 0.00139966 | ||||
Fulfill Order | 21463249 | 1 hr ago | IN | 0.00622925 ETH | 0.00127882 | ||||
Unlock Batch | 21463169 | 1 hr ago | IN | 0 ETH | 0.0015058 | ||||
Unlock Batch | 21463118 | 1 hr ago | IN | 0 ETH | 0.00152489 | ||||
Fulfill Order | 21463108 | 1 hr ago | IN | 0.01488971 ETH | 0.00118148 | ||||
Fulfill Order | 21463004 | 2 hrs ago | IN | 0 ETH | 0.00134513 | ||||
Fulfill Order | 21462995 | 2 hrs ago | IN | 0.00170334 ETH | 0.00120342 | ||||
Fulfill Order | 21462991 | 2 hrs ago | IN | 0.01518344 ETH | 0.00132837 | ||||
Fulfill Order | 21462988 | 2 hrs ago | IN | 0.00620768 ETH | 0.0013226 | ||||
Fulfill Order | 21462985 | 2 hrs ago | IN | 0.39357452 ETH | 0.00126845 | ||||
Fulfill Order | 21462985 | 2 hrs ago | IN | 0.05909284 ETH | 0.00126954 | ||||
Fulfill Order | 21462982 | 2 hrs ago | IN | 2.34978999 ETH | 0.00126764 | ||||
Fulfill Order | 21462970 | 2 hrs ago | IN | 0.00535038 ETH | 0.00146718 | ||||
Fulfill Order | 21462964 | 2 hrs ago | IN | 0.00479944 ETH | 0.00138975 | ||||
Unlock Batch | 21462961 | 2 hrs ago | IN | 0 ETH | 0.00172668 | ||||
Fulfill Order | 21462951 | 2 hrs ago | IN | 0.00481324 ETH | 0.00129156 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21463583 | 13 mins ago | 0.131 ETH | ||||
21463577 | 14 mins ago | 0.5 ETH | ||||
21463570 | 16 mins ago | 0.00699999 ETH | ||||
21463568 | 16 mins ago | 0.56 ETH | ||||
21463551 | 19 mins ago | 0.5 ETH | ||||
21463533 | 23 mins ago | 0.0033 ETH | ||||
21463533 | 23 mins ago | 12.4 ETH | ||||
21463526 | 24 mins ago | 12.4 ETH | ||||
21463525 | 25 mins ago | 0.0032769 ETH | ||||
21463520 | 26 mins ago | 0.7322334 ETH | ||||
21463520 | 26 mins ago | 0.00021973 ETH | ||||
21463493 | 31 mins ago | 0.00606798 ETH | ||||
21463493 | 31 mins ago | 0.0999 ETH | ||||
21463493 | 31 mins ago | 1.44438408 ETH | ||||
21463493 | 31 mins ago | 6.5 ETH | ||||
21463493 | 31 mins ago | 9.915 ETH | ||||
21463488 | 32 mins ago | 0.0033 ETH | ||||
21463487 | 32 mins ago | 9.915 ETH | ||||
21463484 | 33 mins ago | 3.42171388 ETH | ||||
21463468 | 36 mins ago | 1.44438408 ETH | ||||
21463435 | 43 mins ago | 6.5 ETH | ||||
21463427 | 44 mins ago | 0.0999 ETH | ||||
21463401 | 49 mins ago | 0.00606798 ETH | ||||
21463391 | 51 mins ago | 0.0299 ETH | ||||
21463391 | 51 mins ago | 0.0109065 ETH |
Loading...
Loading
This contract contains unverified libraries: SignatureVerifier
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
MayanSwift
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./interfaces/IWormhole.sol"; import "./interfaces/IFeeManager.sol"; import "./libs/BytesLib.sol"; import "./libs/SignatureVerifier.sol"; contract MayanSwift is ReentrancyGuard { event OrderCreated(bytes32 key); event OrderFulfilled(bytes32 key, uint64 sequence, uint256 netAmount); event OrderUnlocked(bytes32 key); event OrderCanceled(bytes32 key, uint64 sequence); event OrderRefunded(bytes32 key, uint256 netAmount); using SafeERC20 for IERC20; using BytesLib for bytes; using SignatureVerifier for bytes; uint16 constant SOLANA_CHAIN_ID = 1; uint8 constant BPS_FEE_LIMIT = 50; uint8 constant NATIVE_DECIMALS = 18; IWormhole public immutable wormhole; uint16 public immutable auctionChainId; bytes32 public immutable auctionAddr; bytes32 public immutable solanaEmitter; IFeeManager public feeManager; uint8 public consistencyLevel; address public guardian; address public nextGuardian; bool public paused; bytes32 private domainSeparator; mapping(bytes32 => Order) public orders; mapping(bytes32 => UnlockMsg) public unlockMsgs; error Paused(); error Unauthorized(); error InvalidAction(); error InvalidBpsFee(); error InvalidOrderStatus(); error InvalidOrderHash(); error InvalidEmitterChain(); error InvalidEmitterAddress(); error InvalidSrcChain(); error OrderNotExists(); error SmallAmountIn(); error FeesTooHigh(); error InvalidGasDrop(); error InvalidDestChain(); error DuplicateOrder(); error InvalidAmount(); error DeadlineViolation(); error InvalidWormholeFee(); error InvalidAuctionMode(); error InvalidEvmAddr(); struct Order { Status status; uint64 amountIn; uint16 destChainId; } struct OrderParams { bytes32 trader; bytes32 tokenOut; uint64 minAmountOut; uint64 gasDrop; uint64 cancelFee; uint64 refundFee; uint64 deadline; bytes32 destAddr; uint16 destChainId; bytes32 referrerAddr; uint8 referrerBps; uint8 auctionMode; bytes32 random; } struct PermitParams { uint256 value; uint256 deadline; uint8 v; bytes32 r; bytes32 s; } struct Key { bytes32 trader; uint16 srcChainId; bytes32 tokenIn; bytes32 destAddr; uint16 destChainId; bytes32 tokenOut; uint64 minAmountOut; uint64 gasDrop; uint64 cancelFee; uint64 refundFee; uint64 deadline; bytes32 referrerAddr; uint8 referrerBps; uint8 protocolBps; uint8 auctionMode; bytes32 random; } struct PaymentParams { address destAddr; address tokenOut; uint64 promisedAmount; uint64 gasDrop; address referrerAddr; uint8 referrerBps; uint8 protocolBps; bool batch; } enum Status { CREATED, FULFILLED, UNLOCKED, CANCELED, REFUNDED } enum Action { NONE, FULFILL, UNLOCK, REFUND, BATCH_UNLOCK } enum AuctionMode { NONE, BYPASS, ENGLISH } struct UnlockMsg { uint8 action; bytes32 orderHash; uint16 srcChainId; bytes32 tokenIn; bytes32 recipient; } struct RefundMsg { uint8 action; bytes32 orderHash; uint16 srcChainId; bytes32 tokenIn; bytes32 recipient; bytes32 canceler; uint64 cancelFee; uint64 refundFee; } struct FulfillMsg { uint8 action; bytes32 orderHash; uint16 destChainId; bytes32 destAddr; bytes32 driver; bytes32 tokenOut; uint64 promisedAmount; uint64 gasDrop; uint64 deadline; bytes32 referrerAddr; uint8 referrerBps; uint8 protocolBps; uint16 srcChainId; bytes32 tokenIn; } struct TransferParams { address from; uint256 validAfter; uint256 validBefore; } constructor( address _wormhole, address _feeManager, uint16 _auctionChainId, bytes32 _auctionAddr, bytes32 _solanaEmitter, uint8 _consistencyLevel ) { guardian = msg.sender; wormhole = IWormhole(_wormhole); feeManager = IFeeManager(_feeManager); auctionChainId = _auctionChainId; auctionAddr = _auctionAddr; solanaEmitter = _solanaEmitter; consistencyLevel = _consistencyLevel; domainSeparator = keccak256(abi.encode( keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"), keccak256("Mayan Swift"), uint256(block.chainid), address(this) )); } function createOrderWithEth(OrderParams memory params) nonReentrant external payable returns (bytes32 orderHash) { if (paused) { revert Paused(); } uint64 normlizedAmountIn = uint64(normalizeAmount(msg.value, NATIVE_DECIMALS)); if (normlizedAmountIn == 0) { revert SmallAmountIn(); } if (params.cancelFee + params.refundFee >= normlizedAmountIn) { revert FeesTooHigh(); } if (params.tokenOut == bytes32(0) && params.gasDrop != 0) { revert InvalidGasDrop(); } uint8 protocolBps = feeManager.calcProtocolBps(normlizedAmountIn, address(0), params.tokenOut, params.destChainId, params.referrerBps); if (params.referrerBps > BPS_FEE_LIMIT || protocolBps > BPS_FEE_LIMIT) { revert InvalidBpsFee(); } Key memory key = buildKey(params, bytes32(0), wormhole.chainId(), protocolBps); orderHash = keccak256(encodeKey(key)); if (params.destChainId == 0 || params.destChainId == wormhole.chainId()) { revert InvalidDestChain(); } if (orders[orderHash].destChainId != 0) { revert DuplicateOrder(); } orders[orderHash] = Order({ status: Status.CREATED, amountIn: normlizedAmountIn, destChainId: params.destChainId }); emit OrderCreated(orderHash); } function createOrderWithToken( address tokenIn, uint256 amountIn, OrderParams memory params ) nonReentrant external returns (bytes32 orderHash) { if (paused) { revert Paused(); } amountIn = pullTokensFrom(tokenIn, amountIn, msg.sender); uint64 normlizedAmountIn = uint64(normalizeAmount(amountIn, decimalsOf(tokenIn))); if (normlizedAmountIn == 0) { revert SmallAmountIn(); } if (params.cancelFee + params.refundFee >= normlizedAmountIn) { revert FeesTooHigh(); } if (params.tokenOut == bytes32(0) && params.gasDrop != 0) { revert InvalidGasDrop(); } uint8 protocolBps = feeManager.calcProtocolBps(normlizedAmountIn, tokenIn, params.tokenOut, params.destChainId, params.referrerBps); if (params.referrerBps > BPS_FEE_LIMIT || protocolBps > BPS_FEE_LIMIT) { revert InvalidBpsFee(); } Key memory key = buildKey(params, bytes32(uint256(uint160(tokenIn))), wormhole.chainId(), protocolBps); orderHash = keccak256(encodeKey(key)); if (params.destChainId == 0 || params.destChainId == wormhole.chainId()) { revert InvalidDestChain(); } if (orders[orderHash].destChainId != 0) { revert DuplicateOrder(); } orders[orderHash] = Order({ status: Status.CREATED, amountIn: normlizedAmountIn, destChainId: params.destChainId }); emit OrderCreated(orderHash); } function createOrderWithSig( address tokenIn, uint256 amountIn, OrderParams memory params, uint256 submissionFee, bytes calldata signedOrderHash, PermitParams calldata permitParams ) nonReentrant external returns (bytes32 orderHash) { if (paused) { revert Paused(); } address trader = truncateAddress(params.trader); uint256 allowance = IERC20(tokenIn).allowance(trader, address(this)); if (allowance < amountIn + submissionFee) { execPermit(tokenIn, trader, permitParams); } amountIn = pullTokensFrom(tokenIn, amountIn, trader); if (submissionFee > 0) { IERC20(tokenIn).safeTransferFrom(trader, msg.sender, submissionFee); } uint64 normlizedAmountIn = uint64(normalizeAmount(amountIn, decimalsOf(tokenIn))); if (normlizedAmountIn == 0) { revert SmallAmountIn(); } if (params.cancelFee + params.refundFee >= normlizedAmountIn) { revert FeesTooHigh(); } if (params.tokenOut == bytes32(0) && params.gasDrop != 0) { revert InvalidGasDrop(); } uint8 protocolBps = feeManager.calcProtocolBps(normlizedAmountIn, tokenIn, params.tokenOut, params.destChainId, params.referrerBps); if (params.referrerBps > BPS_FEE_LIMIT || protocolBps > BPS_FEE_LIMIT) { revert InvalidBpsFee(); } orderHash = keccak256(encodeKey(buildKey(params, bytes32(uint256(uint160(tokenIn))), wormhole.chainId(), protocolBps))); signedOrderHash.verify(hashTypedData(orderHash, amountIn, submissionFee), trader); if (params.destChainId == 0 || params.destChainId == wormhole.chainId()) { revert InvalidDestChain(); } if (orders[orderHash].destChainId != 0) { revert DuplicateOrder(); } orders[orderHash] = Order({ status: Status.CREATED, amountIn: normlizedAmountIn, destChainId: params.destChainId }); emit OrderCreated(orderHash); } function fulfillOrder( uint256 fulfillAmount, bytes memory encodedVm, bytes32 recepient, bool batch ) nonReentrant public payable returns (uint64 sequence) { (IWormhole.VM memory vm, bool valid, string memory reason) = wormhole.parseAndVerifyVM(encodedVm); require(valid, reason); if (vm.emitterChainId != auctionChainId) { revert InvalidEmitterChain(); } if (vm.emitterAddress != auctionAddr) { revert InvalidEmitterAddress(); } FulfillMsg memory fulfillMsg = parseFulfillPayload(vm.payload); address tokenOut = truncateAddress(fulfillMsg.tokenOut); if (tokenOut != address(0)) { fulfillAmount = pullTokensFrom(tokenOut, fulfillAmount, msg.sender); } if (fulfillMsg.destChainId != wormhole.chainId()) { revert InvalidDestChain(); } if (truncateAddress(fulfillMsg.driver) != tx.origin) { revert Unauthorized(); } if (block.timestamp > fulfillMsg.deadline) { revert DeadlineViolation(); } if (orders[fulfillMsg.orderHash].status != Status.CREATED) { revert InvalidOrderStatus(); } orders[fulfillMsg.orderHash].status = Status.FULFILLED; PaymentParams memory paymentParams = PaymentParams({ destAddr: truncateAddress(fulfillMsg.destAddr), tokenOut: tokenOut, promisedAmount: fulfillMsg.promisedAmount, gasDrop: fulfillMsg.gasDrop, referrerAddr: truncateAddress(fulfillMsg.referrerAddr), referrerBps: fulfillMsg.referrerBps, protocolBps: fulfillMsg.protocolBps, batch: batch }); uint256 netAmount = makePayments(fulfillAmount, paymentParams); UnlockMsg memory unlockMsg = UnlockMsg({ action: uint8(Action.UNLOCK), orderHash: fulfillMsg.orderHash, srcChainId: fulfillMsg.srcChainId, tokenIn: fulfillMsg.tokenIn, recipient: recepient }); if (batch) { unlockMsgs[fulfillMsg.orderHash] = unlockMsg; } else { bytes memory encoded = encodeUnlockMsg(unlockMsg); sequence = wormhole.publishMessage{ value : wormhole.messageFee() }(0, encoded, consistencyLevel); } emit OrderFulfilled(fulfillMsg.orderHash, sequence, netAmount); } function fulfillSimple( uint256 fulfillAmount, bytes32 orderHash, uint16 srcChainId, bytes32 tokenIn, uint8 protocolBps, OrderParams memory params, bytes32 recepient, bool batch ) public nonReentrant payable returns (uint64 sequence) { if (params.auctionMode != uint8(AuctionMode.BYPASS)) { revert InvalidAuctionMode(); } address tokenOut = truncateAddress(params.tokenOut); if (tokenOut != address(0)) { fulfillAmount = pullTokensFrom(tokenOut, fulfillAmount, msg.sender); } params.destChainId = wormhole.chainId(); Key memory key = buildKey(params, tokenIn, srcChainId, protocolBps); bytes32 computedOrderHash = keccak256(encodeKey(key)); if (computedOrderHash != orderHash) { revert InvalidOrderHash(); } if (block.timestamp > key.deadline) { revert DeadlineViolation(); } if (orders[computedOrderHash].status != Status.CREATED) { revert InvalidOrderStatus(); } orders[computedOrderHash].status = Status.FULFILLED; PaymentParams memory paymentParams = PaymentParams({ destAddr: truncateAddress(key.destAddr), tokenOut: tokenOut, promisedAmount: key.minAmountOut, gasDrop: key.gasDrop, referrerAddr: truncateAddress(key.referrerAddr), referrerBps: key.referrerBps, protocolBps: protocolBps, batch: batch }); uint256 netAmount = makePayments(fulfillAmount, paymentParams); UnlockMsg memory unlockMsg = UnlockMsg({ action: uint8(Action.UNLOCK), orderHash: computedOrderHash, srcChainId: key.srcChainId, tokenIn: key.tokenIn, recipient: recepient }); if (batch) { unlockMsgs[computedOrderHash] = unlockMsg; } else { bytes memory encoded = encodeUnlockMsg(unlockMsg); sequence = wormhole.publishMessage{ value : wormhole.messageFee() }(0, encoded, consistencyLevel); } emit OrderFulfilled(computedOrderHash, sequence, netAmount); } function unlockOrder(UnlockMsg memory unlockMsg, Order memory order) internal { if (unlockMsg.srcChainId != wormhole.chainId()) { revert InvalidSrcChain(); } if (order.destChainId == 0) { revert OrderNotExists(); } if (order.status != Status.CREATED) { revert InvalidOrderStatus(); } orders[unlockMsg.orderHash].status = Status.UNLOCKED; address recipient = truncateAddress(unlockMsg.recipient); address tokenIn = truncateAddress(unlockMsg.tokenIn); uint8 decimals; if (tokenIn == address(0)) { decimals = NATIVE_DECIMALS; } else { decimals = decimalsOf(tokenIn); } uint256 amountIn = deNormalizeAmount(order.amountIn, decimals); if (tokenIn == address(0)) { payViaCall(recipient, amountIn); } else { IERC20(tokenIn).safeTransfer(recipient, amountIn); } emit OrderUnlocked(unlockMsg.orderHash); } function cancelOrder( bytes32 tokenIn, OrderParams memory params, uint16 srcChainId, uint8 protocolBps, bytes32 canceler ) public nonReentrant payable returns (uint64 sequence) { params.destChainId = wormhole.chainId(); Key memory key = buildKey(params, tokenIn, srcChainId, protocolBps); bytes32 orderHash = keccak256(encodeKey(key)); Order memory order = orders[orderHash]; if (block.timestamp <= key.deadline) { revert DeadlineViolation(); } if (order.status != Status.CREATED) { revert InvalidOrderStatus(); } orders[orderHash].status = Status.CANCELED; RefundMsg memory refundMsg = RefundMsg({ action: uint8(Action.REFUND), orderHash: orderHash, srcChainId: key.srcChainId, tokenIn: key.tokenIn, recipient: key.trader, canceler: canceler, cancelFee: key.cancelFee, refundFee: key.refundFee }); bytes memory encoded = encodeRefundMsg(refundMsg); sequence = wormhole.publishMessage{ value : msg.value }(0, encoded, consistencyLevel); emit OrderCanceled(orderHash, sequence); } function refundOrder(bytes memory encodedVm) nonReentrant() public { (IWormhole.VM memory vm, bool valid, string memory reason) = wormhole.parseAndVerifyVM(encodedVm); require(valid, reason); RefundMsg memory refundMsg = parseRefundPayload(vm.payload); Order memory order = orders[refundMsg.orderHash]; if (refundMsg.srcChainId != wormhole.chainId()) { revert InvalidSrcChain(); } if (order.destChainId == 0) { revert OrderNotExists(); } if (order.status != Status.CREATED) { revert InvalidOrderStatus(); } orders[refundMsg.orderHash].status = Status.REFUNDED; if (vm.emitterChainId != order.destChainId) { revert InvalidEmitterChain(); } if (vm.emitterAddress != solanaEmitter && truncateAddress(vm.emitterAddress) != address(this)) { revert InvalidEmitterAddress(); } address recipient = truncateAddress(refundMsg.recipient); // no error if canceler is invalid address canceler = address(uint160(uint256(refundMsg.canceler))); address tokenIn = truncateAddress(refundMsg.tokenIn); uint8 decimals; if (tokenIn == address(0)) { decimals = NATIVE_DECIMALS; } else { decimals = decimalsOf(tokenIn); } uint256 cancelFee = deNormalizeAmount(refundMsg.cancelFee, decimals); uint256 refundFee = deNormalizeAmount(refundMsg.refundFee, decimals); uint256 amountIn = deNormalizeAmount(order.amountIn, decimals); uint256 netAmount = amountIn - cancelFee - refundFee; if (tokenIn == address(0)) { payViaCall(canceler, cancelFee); payViaCall(msg.sender, refundFee); payViaCall(recipient, netAmount); } else { IERC20(tokenIn).safeTransfer(canceler, cancelFee); IERC20(tokenIn).safeTransfer(msg.sender, refundFee); IERC20(tokenIn).safeTransfer(recipient, netAmount); } emit OrderRefunded(refundMsg.orderHash, netAmount); } function unlockSingle(bytes memory encodedVm) nonReentrant public { (IWormhole.VM memory vm, bool valid, string memory reason) = wormhole.parseAndVerifyVM(encodedVm); require(valid, reason); UnlockMsg memory unlockMsg = parseUnlockPayload(vm.payload); Order memory order = orders[unlockMsg.orderHash]; if (vm.emitterChainId != order.destChainId) { revert InvalidEmitterChain(); } if (vm.emitterAddress != solanaEmitter && truncateAddress(vm.emitterAddress) != address(this)) { revert InvalidEmitterAddress(); } unlockOrder(unlockMsg, order); } function unlockBatch(bytes memory encodedVm) nonReentrant public { (IWormhole.VM memory vm, bool valid, string memory reason) = wormhole.parseAndVerifyVM(encodedVm); require(valid, reason); uint8 action = vm.payload.toUint8(0); uint index = 1; if (action != uint8(Action.BATCH_UNLOCK)) { revert InvalidAction(); } uint16 count = vm.payload.toUint16(index); index += 2; for (uint i=0; i<count; i++) { UnlockMsg memory unlockMsg = UnlockMsg({ action: uint8(Action.UNLOCK), orderHash: vm.payload.toBytes32(index), srcChainId: vm.payload.toUint16(index + 32), tokenIn: vm.payload.toBytes32(index + 34), recipient: vm.payload.toBytes32(index + 66) }); index += 98; Order memory order = orders[unlockMsg.orderHash]; if (order.status != Status.CREATED) { continue; } if (vm.emitterChainId != order.destChainId) { revert InvalidEmitterChain(); } if (vm.emitterAddress != solanaEmitter && truncateAddress(vm.emitterAddress) != address(this)) { revert InvalidEmitterAddress(); } unlockOrder(unlockMsg, order); } } function postBatch(bytes32[] memory orderHashes) public payable returns (uint64 sequence) { bytes memory encoded = abi.encodePacked(uint8(Action.BATCH_UNLOCK), uint16(orderHashes.length)); for(uint i=0; i<orderHashes.length; i++) { UnlockMsg memory unlockMsg = unlockMsgs[orderHashes[i]]; if (unlockMsg.action != uint8(Action.UNLOCK)) { revert InvalidAction(); } bytes memory encodedUnlock = abi.encodePacked( unlockMsg.orderHash, unlockMsg.srcChainId, unlockMsg.tokenIn, unlockMsg.recipient ); encoded = abi.encodePacked(encoded, encodedUnlock); } sequence = wormhole.publishMessage{ value : msg.value }(0, encoded, consistencyLevel); } function makePayments( uint256 fulfillAmount, PaymentParams memory params ) internal returns (uint256 netAmount) { uint8 decimals; if (params.tokenOut == address(0)) { decimals = NATIVE_DECIMALS; } else { decimals = decimalsOf(params.tokenOut); } uint256 referrerAmount = 0; if (params.referrerAddr != address(0) && params.referrerBps != 0) { referrerAmount = fulfillAmount * params.referrerBps / 10000; } uint256 protocolAmount = 0; if (params.protocolBps != 0) { protocolAmount = fulfillAmount * params.protocolBps / 10000; } netAmount = fulfillAmount - referrerAmount - protocolAmount; uint256 promisedAmount = deNormalizeAmount(params.promisedAmount, decimals); if (netAmount < promisedAmount) { revert InvalidAmount(); } if (params.tokenOut == address(0)) { if ( (params.batch && msg.value != fulfillAmount) || (!params.batch && msg.value != fulfillAmount + wormhole.messageFee()) ) { revert InvalidWormholeFee(); } if (referrerAmount > 0) { payViaCall(params.referrerAddr, referrerAmount); } if (protocolAmount > 0) { payViaCall(feeManager.feeCollector(), protocolAmount); } payViaCall(params.destAddr, netAmount); } else { if (params.gasDrop > 0) { uint256 gasDrop = deNormalizeAmount(params.gasDrop, NATIVE_DECIMALS); if ( (params.batch && msg.value != gasDrop) || (!params.batch && msg.value != gasDrop + wormhole.messageFee()) ) { revert InvalidGasDrop(); } payViaCall(params.destAddr, gasDrop); } else if ( (params.batch && msg.value != 0) || (!params.batch && msg.value != wormhole.messageFee()) ) { revert InvalidWormholeFee(); } if (referrerAmount > 0) { IERC20(params.tokenOut).safeTransfer(params.referrerAddr, referrerAmount); } if (protocolAmount > 0) { IERC20(params.tokenOut).safeTransfer(feeManager.feeCollector(), protocolAmount); } IERC20(params.tokenOut).safeTransfer(params.destAddr, netAmount); } } function buildKey(OrderParams memory params, bytes32 tokenIn, uint16 srcChainId, uint8 protocolBps) internal pure returns (Key memory) { return Key({ trader: params.trader, srcChainId: srcChainId, tokenIn: tokenIn, tokenOut: params.tokenOut, minAmountOut: params.minAmountOut, gasDrop: params.gasDrop, cancelFee: params.cancelFee, refundFee: params.refundFee, deadline: params.deadline, destAddr: params.destAddr, destChainId: params.destChainId, referrerAddr: params.referrerAddr, referrerBps: params.referrerBps, protocolBps: protocolBps, auctionMode: params.auctionMode, random: params.random }); } function parseFulfillPayload(bytes memory encoded) public pure returns (FulfillMsg memory fulfillMsg) { uint index = 0; fulfillMsg.action = encoded.toUint8(index); index += 1; if (fulfillMsg.action != uint8(Action.FULFILL)) { revert InvalidAction(); } fulfillMsg.orderHash = encoded.toBytes32(index); index += 32; fulfillMsg.srcChainId = encoded.toUint16(index); index += 2; fulfillMsg.tokenIn = encoded.toBytes32(index); index += 32; fulfillMsg.destAddr = encoded.toBytes32(index); index += 32; fulfillMsg.destChainId = encoded.toUint16(index); index += 2; fulfillMsg.tokenOut = encoded.toBytes32(index); index += 32; fulfillMsg.promisedAmount = encoded.toUint64(index); index += 8; fulfillMsg.gasDrop = encoded.toUint64(index); index += 8; fulfillMsg.deadline = encoded.toUint64(index); index += 8; fulfillMsg.referrerAddr = encoded.toBytes32(index); index += 32; fulfillMsg.referrerBps = encoded.toUint8(index); index += 1; fulfillMsg.protocolBps = encoded.toUint8(index); index += 1; fulfillMsg.driver = encoded.toBytes32(index); index += 32; } function parseUnlockPayload(bytes memory encoded) public pure returns (UnlockMsg memory unlockMsg) { uint index = 0; unlockMsg.action = encoded.toUint8(index); index += 1; if (unlockMsg.action != uint8(Action.UNLOCK)) { revert InvalidAction(); } unlockMsg.orderHash = encoded.toBytes32(index); index += 32; unlockMsg.srcChainId = encoded.toUint16(index); index += 2; unlockMsg.tokenIn = encoded.toBytes32(index); index += 32; unlockMsg.recipient = encoded.toBytes32(index); index += 32; } function parseRefundPayload(bytes memory encoded) public pure returns (RefundMsg memory refundMsg) { uint index = 0; refundMsg.action = encoded.toUint8(index); index += 1; if (refundMsg.action != uint8(Action.REFUND)) { revert InvalidAction(); } refundMsg.orderHash = encoded.toBytes32(index); index += 32; refundMsg.srcChainId = encoded.toUint16(index); index += 2; refundMsg.tokenIn = encoded.toBytes32(index); index += 32; refundMsg.recipient = encoded.toBytes32(index); index += 32; refundMsg.canceler = encoded.toBytes32(index); index += 32; refundMsg.cancelFee = encoded.toUint64(index); index += 8; refundMsg.refundFee = encoded.toUint64(index); index += 8; } function encodeKey(Key memory key) internal pure returns (bytes memory encoded) { encoded = abi.encodePacked( key.trader, key.srcChainId, key.tokenIn, key.destAddr, key.destChainId, key.tokenOut, key.minAmountOut, key.gasDrop, key.cancelFee, key.refundFee, key.deadline, key.referrerAddr, key.referrerBps ); encoded = encoded.concat(abi.encodePacked(key.protocolBps, key.auctionMode, key.random)); } function encodeUnlockMsg(UnlockMsg memory unlockMsg) internal pure returns (bytes memory encoded) { encoded = abi.encodePacked( unlockMsg.action, unlockMsg.orderHash, unlockMsg.srcChainId, unlockMsg.tokenIn, unlockMsg.recipient ); } function encodeRefundMsg(RefundMsg memory refundMsg) internal pure returns (bytes memory encoded) { encoded = abi.encodePacked( refundMsg.action, refundMsg.orderHash, refundMsg.srcChainId, refundMsg.tokenIn, refundMsg.recipient, refundMsg.canceler, refundMsg.cancelFee, refundMsg.refundFee ); } function payViaCall(address to, uint256 amount) internal { (bool success, ) = payable(to).call{value: amount}(''); require(success, 'payment failed'); } function truncateAddress(bytes32 b) internal pure returns (address) { if (bytes12(b) != 0) { revert InvalidEvmAddr(); } return address(uint160(uint256(b))); } function decimalsOf(address token) internal view returns(uint8) { (,bytes memory queriedDecimals) = token.staticcall(abi.encodeWithSignature('decimals()')); return abi.decode(queriedDecimals, (uint8)); } function normalizeAmount(uint256 amount, uint8 decimals) internal pure returns(uint256) { if (decimals > 8) { amount /= 10 ** (decimals - 8); } return amount; } function deNormalizeAmount(uint256 amount, uint8 decimals) internal pure returns(uint256) { if (decimals > 8) { amount *= 10 ** (decimals - 8); } return amount; } function hashTypedData(bytes32 orderHash, uint256 amountIn, uint256 submissionFee) internal view returns (bytes32) { bytes memory encoded = abi.encode(keccak256("CreateOrder(bytes32 OrderId,uint256 InputAmount,uint256 SubmissionFee)"), orderHash, amountIn, submissionFee); return toTypedDataHash(domainSeparator, keccak256(encoded)); } function toTypedDataHash(bytes32 _domainSeparator, bytes32 _structHash) internal pure returns (bytes32 digest) { assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), _domainSeparator) mstore(add(ptr, 0x22), _structHash) digest := keccak256(ptr, 0x42) } } function pullTokensFrom(address tokenIn, uint256 amount, address from) internal returns (uint256) { uint256 balance = IERC20(tokenIn).balanceOf(address(this)); IERC20(tokenIn).safeTransferFrom(from, address(this), amount); return IERC20(tokenIn).balanceOf(address(this)) - balance; } function execPermit( address token, address owner, PermitParams calldata permitParams ) internal { IERC20Permit(token).permit( owner, address(this), permitParams.value, permitParams.deadline, permitParams.v, permitParams.r, permitParams.s ); } function setPause(bool _pause) public { if (msg.sender != guardian) { revert Unauthorized(); } paused = _pause; } function setFeeManager(address _feeManager) public { if (msg.sender != guardian) { revert Unauthorized(); } feeManager = IFeeManager(_feeManager); } function setConsistencyLevel(uint8 _consistencyLevel) public { if (msg.sender != guardian) { revert Unauthorized(); } consistencyLevel = _consistencyLevel; } function changeGuardian(address newGuardian) public { if (msg.sender != guardian) { revert Unauthorized(); } nextGuardian = newGuardian; } function claimGuardian() public { if (msg.sender != nextGuardian) { revert Unauthorized(); } guardian = nextGuardian; } function getOrders(bytes32[] memory orderHashes) public view returns (Order[] memory) { Order[] memory result = new Order[](orderHashes.length); for (uint i=0; i<orderHashes.length; i++) { result[i] = orders[orderHashes[i]]; } return result; } receive() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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; 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 require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // 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 v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ 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]. */ 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 v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev 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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 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); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @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.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @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.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC1271 { /// @dev Should return whether the signature provided is valid for the provided data /// @param hash Hash of the data to be signed /// @param signature Signature byte array associated with _data /// @return magicValue The bytes4 magic value 0x1626ba7e function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IFeeManager { function calcProtocolBps( uint64 amountIn, address tokenIn, bytes32 tokenOut, uint16 destChain, uint8 referrerBps ) external view returns (uint8); function feeCollector() external view returns (address); }
// SPDX-License-Identifier: Apache 2 pragma solidity ^0.8.0; interface IWormhole { struct GuardianSet { address[] keys; uint32 expirationTime; } struct Signature { bytes32 r; bytes32 s; uint8 v; uint8 guardianIndex; } 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 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: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC1271} from "../interfaces/IERC1271.sol"; library SignatureVerifier { /// @notice Thrown when the passed in signature is not a valid length error InvalidSignatureLength(); /// @notice Thrown when the recovered signer is equal to the zero address error InvalidSignature(); /// @notice Thrown when the recovered signer does not equal the claimedSigner error InvalidSigner(); /// @notice Thrown when the recovered contract signature is incorrect error InvalidContractSignature(); bytes32 constant UPPER_BIT_MASK = (0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); function verify(bytes calldata signature, bytes32 hash, address claimedSigner) external view { bytes32 r; bytes32 s; uint8 v; if (claimedSigner.code.length == 0) { if (signature.length == 65) { (r, s) = abi.decode(signature, (bytes32, bytes32)); v = uint8(signature[64]); } else if (signature.length == 64) { // EIP-2098 bytes32 vs; (r, vs) = abi.decode(signature, (bytes32, bytes32)); s = vs & UPPER_BIT_MASK; v = uint8(uint256(vs >> 255)) + 27; } else { revert InvalidSignatureLength(); } address signer = ecrecover(hash, v, r, s); if (signer == address(0)) revert InvalidSignature(); if (signer != claimedSigner) revert InvalidSigner(); } else { bytes4 magicValue = IERC1271(claimedSigner).isValidSignature(hash, signature); if (magicValue != IERC1271.isValidSignature.selector) revert InvalidContractSignature(); } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "src/libs/SignatureVerifier.sol": { "SignatureVerifier": "0x3ca829b74971035fe0b733cd6297ca7a8a39e7c0" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_wormhole","type":"address"},{"internalType":"address","name":"_feeManager","type":"address"},{"internalType":"uint16","name":"_auctionChainId","type":"uint16"},{"internalType":"bytes32","name":"_auctionAddr","type":"bytes32"},{"internalType":"bytes32","name":"_solanaEmitter","type":"bytes32"},{"internalType":"uint8","name":"_consistencyLevel","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DeadlineViolation","type":"error"},{"inputs":[],"name":"DuplicateOrder","type":"error"},{"inputs":[],"name":"FeesTooHigh","type":"error"},{"inputs":[],"name":"InvalidAction","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidAuctionMode","type":"error"},{"inputs":[],"name":"InvalidBpsFee","type":"error"},{"inputs":[],"name":"InvalidDestChain","type":"error"},{"inputs":[],"name":"InvalidEmitterAddress","type":"error"},{"inputs":[],"name":"InvalidEmitterChain","type":"error"},{"inputs":[],"name":"InvalidEvmAddr","type":"error"},{"inputs":[],"name":"InvalidGasDrop","type":"error"},{"inputs":[],"name":"InvalidOrderHash","type":"error"},{"inputs":[],"name":"InvalidOrderStatus","type":"error"},{"inputs":[],"name":"InvalidSrcChain","type":"error"},{"inputs":[],"name":"InvalidWormholeFee","type":"error"},{"inputs":[],"name":"OrderNotExists","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"SmallAmountIn","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"}],"name":"OrderCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"OrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"sequence","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"netAmount","type":"uint256"}],"name":"OrderFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"netAmount","type":"uint256"}],"name":"OrderRefunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"OrderUnlocked","type":"event"},{"inputs":[],"name":"auctionAddr","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct MayanSwift.OrderParams","name":"params","type":"tuple"},{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"internalType":"bytes32","name":"canceler","type":"bytes32"}],"name":"cancelOrder","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newGuardian","type":"address"}],"name":"changeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"consistencyLevel","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct MayanSwift.OrderParams","name":"params","type":"tuple"}],"name":"createOrderWithEth","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct MayanSwift.OrderParams","name":"params","type":"tuple"},{"internalType":"uint256","name":"submissionFee","type":"uint256"},{"internalType":"bytes","name":"signedOrderHash","type":"bytes"},{"components":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct MayanSwift.PermitParams","name":"permitParams","type":"tuple"}],"name":"createOrderWithSig","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct MayanSwift.OrderParams","name":"params","type":"tuple"}],"name":"createOrderWithToken","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"contract IFeeManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fulfillAmount","type":"uint256"},{"internalType":"bytes","name":"encodedVm","type":"bytes"},{"internalType":"bytes32","name":"recepient","type":"bytes32"},{"internalType":"bool","name":"batch","type":"bool"}],"name":"fulfillOrder","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fulfillAmount","type":"uint256"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"components":[{"internalType":"bytes32","name":"trader","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"minAmountOut","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"auctionMode","type":"uint8"},{"internalType":"bytes32","name":"random","type":"bytes32"}],"internalType":"struct MayanSwift.OrderParams","name":"params","type":"tuple"},{"internalType":"bytes32","name":"recepient","type":"bytes32"},{"internalType":"bool","name":"batch","type":"bool"}],"name":"fulfillSimple","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"getOrders","outputs":[{"components":[{"internalType":"enum MayanSwift.Status","name":"status","type":"uint8"},{"internalType":"uint64","name":"amountIn","type":"uint64"},{"internalType":"uint16","name":"destChainId","type":"uint16"}],"internalType":"struct MayanSwift.Order[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"orders","outputs":[{"internalType":"enum MayanSwift.Status","name":"status","type":"uint8"},{"internalType":"uint64","name":"amountIn","type":"uint64"},{"internalType":"uint16","name":"destChainId","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseFulfillPayload","outputs":[{"components":[{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bytes32","name":"destAddr","type":"bytes32"},{"internalType":"bytes32","name":"driver","type":"bytes32"},{"internalType":"bytes32","name":"tokenOut","type":"bytes32"},{"internalType":"uint64","name":"promisedAmount","type":"uint64"},{"internalType":"uint64","name":"gasDrop","type":"uint64"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"bytes32","name":"referrerAddr","type":"bytes32"},{"internalType":"uint8","name":"referrerBps","type":"uint8"},{"internalType":"uint8","name":"protocolBps","type":"uint8"},{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"}],"internalType":"struct MayanSwift.FulfillMsg","name":"fulfillMsg","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseRefundPayload","outputs":[{"components":[{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"bytes32","name":"canceler","type":"bytes32"},{"internalType":"uint64","name":"cancelFee","type":"uint64"},{"internalType":"uint64","name":"refundFee","type":"uint64"}],"internalType":"struct MayanSwift.RefundMsg","name":"refundMsg","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseUnlockPayload","outputs":[{"components":[{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"}],"internalType":"struct MayanSwift.UnlockMsg","name":"unlockMsg","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"orderHashes","type":"bytes32[]"}],"name":"postBatch","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVm","type":"bytes"}],"name":"refundOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_consistencyLevel","type":"uint8"}],"name":"setConsistencyLevel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_pause","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"solanaEmitter","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVm","type":"bytes"}],"name":"unlockBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"unlockMsgs","outputs":[{"internalType":"uint8","name":"action","type":"uint8"},{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"bytes32","name":"tokenIn","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVm","type":"bytes"}],"name":"unlockSingle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wormhole","outputs":[{"internalType":"contract IWormhole","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101006040523480156200001257600080fd5b5060405162005f5d38038062005f5d83398101604081905262000035916200015e565b60016000819055600280546001600160a01b031916331790556001600160601b0319606088901b1660805280546001600160f01b031960f087901b1660a05260c085905260e084905260ff8316600160a01b026001600160a81b03199091166001600160a01b0388161717905560405162000119907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866907f31470924aa18e932d2ed4194a9334695b7301e5a1f1225acc3e6f40db2647de79046903090602001938452602084019290925260408301526001600160a01b0316606082015260800190565b60405160208183030381529060405280519060200120600481905550505050505050620001dd565b80516001600160a01b03811681146200015957600080fd5b919050565b60008060008060008060c0878903121562000177578182fd5b620001828762000141565b9550620001926020880162000141565b9450604087015161ffff81168114620001a9578283fd5b80945050606087015192506080870151915060a087015160ff81168114620001cf578182fd5b809150509295509295509295565b60805160601c60a05160f01c60c05160e051615c75620002e8600039600081816106c80152818161094f01528181612c29015261375301526000818161075c01526114f901526000818161052a01526114ad0152600081816104f6015281816107ad01528181610e5401528181610fba015281816113e60152818161157c01528181611899015281816118c801528181611be201528181611c9501528181611ede01528181612086015281816123700152818161239f015281816126ff0152818161277f0152818161297901528181612f7401528181612ff40152818161346e015281816135ed015281816139c70152818161445f0152818161461e01526147100152615c756000f3fe6080604052600436106101d15760003560e01c806381b152c0116100f7578063b866e17311610095578063e8dfd50811610064578063e8dfd508146106ea578063f1d3ac4f1461071d578063fa6a6d361461074a578063feea83f11461077e57600080fd5b8063b866e17314610663578063bedb86fb14610676578063d0fb020314610696578063d96427ff146106b657600080fd5b80638e8d142b116100d15780638e8d142b1461055f57806397b6e0031461057f5780639c3f1e901461059f578063a5e1ea7d146105fa57600080fd5b806381b152c01461045c57806384acd1bb146104e45780638a261c671461051857600080fd5b8063472d35b91161016f578063526bb8651161013e578063526bb865146103e5578063538ee295146103f85780635c975abb146104185780637226f4e01461044957600080fd5b8063472d35b9146103675780634818e84d14610387578063488c3591146103a75780634a85d788146103d257600080fd5b80633a30b37f116101ab5780633a30b37f146102bf5780633d474866146102ed578063452a93201461031a578063459656ee1461035257600080fd5b8063119abf67146101dd5780632fcb4f04146101ff57806339f3fbd91461021f57600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506101fd6101f8366004615233565b61079e565b005b34801561020b57600080fd5b506101fd61021a366004614fc3565b6109d9565b34801561022b57600080fd5b5061023f61023a366004615233565b610a25565b6040516102b6919060006101008201905060ff83511682526020830151602083015261ffff6040840151166040830152606083015160608301526080830151608083015260a083015160a083015260c08301516001600160401b0380821660c08501528060e08601511660e0850152505092915050565b60405180910390f35b3480156102cb57600080fd5b506102df6102da36600461503a565b610b8b565b6040519081526020016102b6565b3480156102f957600080fd5b5061030d6103083660046150f4565b6111b1565b6040516102b691906156b9565b34801561032657600080fd5b5060025461033a906001600160a01b031681565b6040516001600160a01b0390911681526020016102b6565b34801561035e57600080fd5b506101fd61133b565b34801561037357600080fd5b506101fd610382366004614fc3565b611389565b34801561039357600080fd5b5060035461033a906001600160a01b031681565b6103ba6103b536600461548b565b6113d5565b6040516001600160401b0390911681526020016102b6565b6103ba6103e03660046150f4565b611a4b565b6103ba6103f33660046151d6565b611c89565b34801561040457600080fd5b506101fd610413366004615507565b611fd9565b34801561042457600080fd5b5060035461043990600160a01b900460ff1681565b60405190151581526020016102b6565b6103ba610457366004615406565b612023565b34801561046857600080fd5b506104af6104773660046151be565b6006602052600090815260409020805460018201546002830154600384015460049094015460ff90931693919261ffff909116919085565b6040805160ff9096168652602086019490945261ffff909216928401929092526060830191909152608082015260a0016102b6565b3480156104f057600080fd5b5061033a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561052457600080fd5b5061054c7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff90911681526020016102b6565b34801561056b57600080fd5b506102df61057a366004614ffb565b61251c565b34801561058b57600080fd5b506101fd61059a366004615233565b61296a565b3480156105ab57600080fd5b506105eb6105ba3660046151be565b60056020526000908152604090205460ff81169061010081046001600160401b031690600160481b900461ffff1683565b6040516102b69392919061576c565b34801561060657600080fd5b5061061a610615366004615233565b612cc7565b6040516102b69190600060a08201905060ff83511682526020830151602083015261ffff6040840151166040830152606083015160608301526080830151608083015292915050565b6102df610671366004615265565b612da9565b34801561068257600080fd5b506101fd610691366004615186565b6131e4565b3480156106a257600080fd5b5060015461033a906001600160a01b031681565b3480156106c257600080fd5b506102df7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106f657600080fd5b5060015461070b90600160a01b900460ff1681565b60405160ff90911681526020016102b6565b34801561072957600080fd5b5061073d610738366004615233565b61322c565b6040516102b691906157cd565b34801561075657600080fd5b506102df7f000000000000000000000000000000000000000000000000000000000000000081565b34801561078a57600080fd5b506101fd610799366004615233565b61345f565b6107a661393c565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016107f79190615726565b60006040518083038186803b15801561080f57600080fd5b505afa158015610823573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261084b9190810190615281565b92509250925081819061087a5760405162461bcd60e51b81526004016108719190615726565b60405180910390fd5b50600061088a8460e00151612cc7565b60208082015160009081526005909152604080822081516060810190925280549394509192909190829060ff1660048111156108d657634e487b7160e01b600052602160045260246000fd5b60048111156108f557634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b03166020830152600160481b900461ffff908116604092830152908201516060880151929350811691161461094d576040516327e8d62960e11b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000085608001511415801561099f5750306001600160a01b03166109938660800151613996565b6001600160a01b031614155b156109bd5760405163d08bf9e160e01b815260040160405180910390fd5b6109c782826139c5565b50505050506109d66001600055565b50565b6002546001600160a01b03163314610a03576040516282b42960e81b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905290610a708382613bdd565b60ff168252610a806001826159d4565b825190915060ff16600314610aa857604051634a7f394f60e01b815260040160405180910390fd5b610ab28382613c3f565b602080840191909152610ac590826159d4565b9050610ad18382613c9d565b61ffff166040830152610ae56002826159d4565b9050610af18382613c3f565b6060830152610b016020826159d4565b9050610b0d8382613c3f565b6080830152610b1d6020826159d4565b9050610b298382613c3f565b60a0830152610b396020826159d4565b9050610b458382613cfa565b6001600160401b031660c0830152610b5e6008826159d4565b9050610b6a8382613cfa565b6001600160401b031660e0830152610b836008826159d4565b905050919050565b6000610b9561393c565b600354600160a01b900460ff1615610bc0576040516313d0ff5960e31b815260040160405180910390fd5b6000610bcf8760000151613996565b604051636eb1769f60e11b81526001600160a01b0380831660048301523060248301529192506000918b169063dd62ed3e9060440160206040518083038186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5491906153ee565b9050610c60878a6159d4565b811015610c7257610c728a8386613d57565b610c7d8a8a84613e0f565b98508615610c9a57610c9a6001600160a01b038b1683338a613f25565b6000610cae8a610ca98d613f96565b614031565b90506001600160401b038116610cd7576040516356fdd81f60e11b815260040160405180910390fd5b806001600160401b03168960a001518a60800151610cf591906159ec565b6001600160401b031610610d1c5760405163192069c360e31b815260040160405180910390fd5b6020890151158015610d3a575060608901516001600160401b031615155b15610d5857604051636e51edcd60e11b815260040160405180910390fd5b6000600160009054906101000a90046001600160a01b03166001600160a01b03166302fb1eec838e8d602001518e61010001518f61014001516040518663ffffffff1660e01b8152600401610db19594939291906158ae565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190615523565b9050603260ff168a610140015160ff161180610e205750603260ff8216115b15610e3e57604051633f6e8d0d60e21b815260040160405180910390fd5b610eee610ee98b8e6001600160a01b031660001b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015610eab57600080fd5b505afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee391906153d2565b85614069565b6141d5565b80519060200120945087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250733ca829b74971035fe0b733cd6297ca7a8a39e7c093638048608093509150610f569050888f8e6142a0565b876040518463ffffffff1660e01b8152600401610f7593929190615739565b60006040518083038186803b158015610f8d57600080fd5b505af4158015610fa1573d6000803e3d6000fd5b5050505089610100015161ffff166000148061105957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b15801561101157600080fd5b505afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104991906153d2565b61ffff168a610100015161ffff16145b15611077576040516355ef7a1d60e11b815260040160405180910390fd5b600085815260056020526040902054600160481b900461ffff16156110af5760405163015b9d8b60e41b815260040160405180910390fd5b6040805160608101825260008082526001600160401b0385166020808401919091526101008e015161ffff1683850152888252600590529190912081518154829060ff1916600183600481111561111657634e487b7160e01b600052602160045260246000fd5b02179055506020820151815460409384015161ffff16600160481b0261ffff60481b196001600160401b0390931661010002929092166affffffffffffffffffff001990911617179055517f918554b6bd6e2895ce6553de5de0e1a69db5289aa0e4fe193a0dcd1f14347477906111909087815260200190565b60405180910390a1505050506111a66001600055565b979650505050505050565b6060600082516001600160401b038111156111dc57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561122757816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816111fa5790505b50905060005b8351811015611334576005600085838151811061125a57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206040518060600160405290816000820160009054906101000a900460ff1660048111156112ad57634e487b7160e01b600052602160045260246000fd5b60048111156112cc57634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b03166020830152600160481b900461ffff16604090910152825183908390811061131657634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061132c90615ba1565b91505061122d565b5092915050565b6003546001600160a01b03163314611365576040516282b42960e81b815260040160405180910390fd5b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b6002546001600160a01b031633146113b3576040516282b42960e81b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006113df61393c565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde886040518263ffffffff1660e01b81526004016114309190615726565b60006040518083038186803b15801561144857600080fd5b505afa15801561145c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114849190810190615281565b9250925092508181906114aa5760405162461bcd60e51b81526004016108719190615726565b507f000000000000000000000000000000000000000000000000000000000000000061ffff16836060015161ffff16146114f7576040516327e8d62960e11b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000083608001511461153b5760405163d08bf9e160e01b815260040160405180910390fd5b600061154a8460e0015161322c565b9050600061155b8260a00151613996565b90506001600160a01b0381161561157a57611577818b33613e0f565b99505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b1580156115d357600080fd5b505afa1580156115e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160b91906153d2565b61ffff16826040015161ffff1614611636576040516355ef7a1d60e11b815260040160405180910390fd5b326001600160a01b031661164d8360800151613996565b6001600160a01b031614611673576040516282b42960e81b815260040160405180910390fd5b8161010001516001600160401b03164211156116a2576040516354a36da760e11b815260040160405180910390fd5b60208281015160009081526005909152604081205460ff1660048111156116d957634e487b7160e01b600052602160045260246000fd5b146116f757604051632916ae3360e01b815260040160405180910390fd5b602082810151600090815260059091526040808220805460ff19166001179055805161010081019091526060840151819061173190613996565b6001600160a01b03168152602001836001600160a01b031681526020018460c001516001600160401b031681526020018460e001516001600160401b03168152602001611782856101200151613996565b6001600160a01b0316815260200184610140015160ff16815260200184610160015160ff168152602001891515815250905060006117c08c83614324565b905060006040518060a00160405280600260048111156117f057634e487b7160e01b600052602160045260246000fd5b60ff1681526020018660200151815260200186610180015161ffff168152602001866101a0015181526020018c8152509050891561188a576020858101516000908152600682526040908190208351815460ff191660ff90911617815591830151600183015582015160028201805461ffff191661ffff9092169190911790556060820151600382015560808201516004909101556119e0565b6000611895826148ad565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b19a437e7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b15801561191f57600080fd5b505afa158015611933573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195791906153ee565b60015460405160e084901b6001600160e01b031916815261198a916000918791600160a01b900460ff169060040161579b565b6020604051808303818588803b1580156119a357600080fd5b505af11580156119b7573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906119dc91906154eb565b9950505b602080860151604080519182526001600160401b038c16928201929092529081018390527f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b9060600160405180910390a15050505050505050611a436001600055565b949350505050565b8051604051600160fa1b602082015260f09190911b6001600160f01b03191660218201526000908190602301604051602081830303815290604052905060005b8351811015611bcf57600060066000868481518110611aba57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252818101929092526040908101600020815160a081018352815460ff1680825260018301549482019490945260028083015461ffff1693820193909352600382015460608201526004909101546080820152925014611b3957604051634a7f394f60e01b815260040160405180910390fd5b60008160200151826040015183606001518460800151604051602001611b85949392919093845260f09290921b6001600160f01b03191660208401526022830152604282015260620190565b60405160208183030381529060405290508381604051602001611ba992919061568a565b604051602081830303815290604052935050508080611bc790615ba1565b915050611a8b565b506001546040516358cd21bf60e11b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163b19a437e913491611c30916000918791600160a01b90910460ff169060040161579b565b6020604051808303818588803b158015611c4957600080fd5b505af1158015611c5d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611c8291906154eb565b9392505050565b6000611c9361393c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015611cec57600080fd5b505afa158015611d00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2491906153d2565b61ffff166101008601526000611d3c86888787614069565b90506000611d49826141d5565b805160209182012060008181526005909252604080832081516060810190925280549294509091829060ff166004811115611d9457634e487b7160e01b600052602160045260246000fd5b6004811115611db357634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b039081166020840152600160481b90910461ffff16604090920191909152610140850151919250164211611e0a576040516354a36da760e11b815260040160405180910390fd5b600081516004811115611e2d57634e487b7160e01b600052602160045260246000fd5b14611e4b57604051632916ae3360e01b815260040160405180910390fd5b6000828152600560209081526040808320805460ff19166003908117909155815161010080820184529181528084018790529287015161ffff16838301529086015160608301528551608083015260a082018890528501516001600160401b0390811660c08301526101208601511660e082015290611ec98261492c565b6001546040516358cd21bf60e11b81529192507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163b19a437e913491611f2b916000918791600160a01b900460ff169060040161579b565b6020604051808303818588803b158015611f4457600080fd5b505af1158015611f58573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611f7d91906154eb565b604080518681526001600160401b03831660208201529197507f45a58de39e77dfc9cd1d63970a706575668048121d822749d2298eb75125123e910160405180910390a15050505050611fd06001600055565b95945050505050565b6002546001600160a01b03163314612003576040516282b42960e81b815260040160405180910390fd5b6001805460ff909216600160a01b0260ff60a01b19909216919091179055565b600061202d61393c565b61016084015160ff1660011461205657604051631fa84deb60e31b815260040160405180910390fd5b60006120658560200151613996565b90506001600160a01b0381161561208457612081818b33613e0f565b99505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b1580156120dd57600080fd5b505afa1580156120f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211591906153d2565b61ffff16610100860152600061212d86898b8a614069565b9050600061213a826141d5565b8051906020012090508a81146121635760405163561a411d60e11b815260040160405180910390fd5b8161014001516001600160401b0316421115612192576040516354a36da760e11b815260040160405180910390fd5b60008181526005602052604081205460ff1660048111156121c357634e487b7160e01b600052602160045260246000fd5b146121e157604051632916ae3360e01b815260040160405180910390fd5b600081815260056020526040808220805460ff19166001179055805161010081019091526060840151819061221590613996565b6001600160a01b03168152602001856001600160a01b031681526020018460c001516001600160401b031681526020018460e001516001600160401b03168152602001612266856101600151613996565b6001600160a01b0316815260200184610180015160ff1681526020018a60ff1681526020018715158152509050600061229f8e83614324565b905060006040518060a00160405280600260048111156122cf57634e487b7160e01b600052602160045260246000fd5b60ff168152602001858152602001866020015161ffff168152602001866040015181526020018a81525090508715612361576000848152600660209081526040918290208351815460ff191660ff9091161781559083015160018201559082015160028201805461ffff191661ffff9092169190911790556060820151600382015560808201516004909101556124b7565b600061236c826148ad565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b19a437e7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b1580156123f657600080fd5b505afa15801561240a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242e91906153ee565b60015460405160e084901b6001600160e01b0319168152612461916000918791600160a01b900460ff169060040161579b565b6020604051808303818588803b15801561247a57600080fd5b505af115801561248e573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906124b391906154eb565b9750505b604080518581526001600160401b03891660208201529081018390527f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b9060600160405180910390a15050505050506125106001600055565b98975050505050505050565b600061252661393c565b600354600160a01b900460ff1615612551576040516313d0ff5960e31b815260040160405180910390fd5b61255c848433613e0f565b9250600061256d84610ca987613f96565b90506001600160401b038116612596576040516356fdd81f60e11b815260040160405180910390fd5b806001600160401b03168360a0015184608001516125b491906159ec565b6001600160401b0316106125db5760405163192069c360e31b815260040160405180910390fd5b60208301511580156125f9575060608301516001600160401b031615155b1561261757604051636e51edcd60e11b815260040160405180910390fd5b600154602084015161010085015161014086015160405162bec7bb60e21b81526000946001600160a01b0316936302fb1eec9361265d9388938d939291906004016158ae565b60206040518083038186803b15801561267557600080fd5b505afa158015612689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ad9190615523565b9050603260ff1684610140015160ff1611806126cc5750603260ff8216115b156126ea57604051633f6e8d0d60e21b815260040160405180910390fd5b600061275685886001600160a01b031660001b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015610eab57600080fd5b9050612761816141d5565b80519060200120935084610100015161ffff166000148061281e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b1580156127d657600080fd5b505afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e91906153d2565b61ffff1685610100015161ffff16145b1561283c576040516355ef7a1d60e11b815260040160405180910390fd5b600084815260056020526040902054600160481b900461ffff16156128745760405163015b9d8b60e41b815260040160405180910390fd5b6040805160608101825260008082526001600160401b03861660208084019190915261010089015161ffff1683850152878252600590529190912081518154829060ff191660018360048111156128db57634e487b7160e01b600052602160045260246000fd5b02179055506020820151815460409384015161ffff16600160481b0261ffff60481b196001600160401b0390931661010002929092166affffffffffffffffffff001990911617179055517f918554b6bd6e2895ce6553de5de0e1a69db5289aa0e4fe193a0dcd1f14347477906129559086815260200190565b60405180910390a1505050611c826001600055565b61297261393c565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016129c39190615726565b60006040518083038186803b1580156129db57600080fd5b505afa1580156129ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a179190810190615281565b925092509250818190612a3d5760405162461bcd60e51b81526004016108719190615726565b5060e0830151600090612a509082613bdd565b9050600160ff8216600414612a7857604051634a7f394f60e01b815260040160405180910390fd5b60e0850151600090612a8a9083613c9d565b9050612a976002836159d4565b915060005b8161ffff16811015612cb6576040805160a081019091526002815260e0880151600091906020820190612acf9087613c3f565b8152602001612aef866020612ae491906159d4565b60e08c015190613c9d565b61ffff168152602001612b11612b068760226159d4565b60e08c015190613c3f565b8152602001612b24612b068760426159d4565b90529050612b336062856159d4565b60208083015160009081526005909152604080822081516060810190925280549397509192909190829060ff166004811115612b7f57634e487b7160e01b600052602160045260246000fd5b6004811115612b9e57634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b03166020830152600160481b900461ffff166040909101529050600081516004811115612beb57634e487b7160e01b600052602160045260246000fd5b14612bf7575050612ca4565b806040015161ffff16896060015161ffff1614612c27576040516327e8d62960e11b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000896080015114158015612c795750306001600160a01b0316612c6d8a60800151613996565b6001600160a01b031614155b15612c975760405163d08bf9e160e01b815260040160405180910390fd5b612ca182826139c5565b50505b80612cae81615ba1565b915050612a9c565b505050505050506109d66001600055565b6040805160a081018252600080825260208201819052918101829052606081018290526080810182905290612cfc8382613bdd565b60ff168252612d0c6001826159d4565b825190915060ff16600214612d3457604051634a7f394f60e01b815260040160405180910390fd5b612d3e8382613c3f565b602080840191909152612d5190826159d4565b9050612d5d8382613c9d565b61ffff166040830152612d716002826159d4565b9050612d7d8382613c3f565b6060830152612d8d6020826159d4565b9050612d998382613c3f565b6080830152610b836020826159d4565b6000612db361393c565b600354600160a01b900460ff1615612dde576040516313d0ff5960e31b815260040160405180910390fd5b6000612deb346012614031565b90506001600160401b038116612e14576040516356fdd81f60e11b815260040160405180910390fd5b806001600160401b03168360a001518460800151612e3291906159ec565b6001600160401b031610612e595760405163192069c360e31b815260040160405180910390fd5b6020830151158015612e77575060608301516001600160401b031615155b15612e9557604051636e51edcd60e11b815260040160405180910390fd5b600154602084015161010085015161014086015160405162bec7bb60e21b81526000946001600160a01b0316936302fb1eec93612edb93889388939291906004016158ae565b60206040518083038186803b158015612ef357600080fd5b505afa158015612f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2b9190615523565b9050603260ff1684610140015160ff161180612f4a5750603260ff8216115b15612f6857604051633f6e8d0d60e21b815260040160405180910390fd5b6000612fcb856000801b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015610eab57600080fd5b9050612fd6816141d5565b80519060200120935084610100015161ffff166000148061309357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b15801561304b57600080fd5b505afa15801561305f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308391906153d2565b61ffff1685610100015161ffff16145b156130b1576040516355ef7a1d60e11b815260040160405180910390fd5b600084815260056020526040902054600160481b900461ffff16156130e95760405163015b9d8b60e41b815260040160405180910390fd5b6040805160608101825260008082526001600160401b03861660208084019190915261010089015161ffff1683850152878252600590529190912081518154829060ff1916600183600481111561315057634e487b7160e01b600052602160045260246000fd5b02179055506020820151815460409384015161ffff16600160481b0261ffff60481b196001600160401b0390931661010002929092166affffffffffffffffffff001990911617179055517f918554b6bd6e2895ce6553de5de0e1a69db5289aa0e4fe193a0dcd1f14347477906131ca9086815260200190565b60405180910390a15050506131df6001600055565b919050565b6002546001600160a01b0316331461320e576040516282b42960e81b815260040160405180910390fd5b60038054911515600160a01b0260ff60a01b19909216919091179055565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052906132a78382613bdd565b60ff1682526132b76001826159d4565b825190915060ff166001146132df57604051634a7f394f60e01b815260040160405180910390fd5b6132e98382613c3f565b6020808401919091526132fc90826159d4565b90506133088382613c9d565b61ffff1661018083015261331d6002826159d4565b90506133298382613c3f565b6101a083015261333a6020826159d4565b90506133468382613c3f565b60608301526133566020826159d4565b90506133628382613c9d565b61ffff1660408301526133766002826159d4565b90506133828382613c3f565b60a08301526133926020826159d4565b905061339e8382613cfa565b6001600160401b031660c08301526133b76008826159d4565b90506133c38382613cfa565b6001600160401b031660e08301526133dc6008826159d4565b90506133e88382613cfa565b6001600160401b03166101008301526134026008826159d4565b905061340e8382613c3f565b61012083015261341f6020826159d4565b905061342b8382613bdd565b60ff1661014083015261343f6001826159d4565b905061344b8382613bdd565b60ff16610160830152612d8d6001826159d4565b61346761393c565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016134b89190615726565b60006040518083038186803b1580156134d057600080fd5b505afa1580156134e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261350c9190810190615281565b9250925092508181906135325760405162461bcd60e51b81526004016108719190615726565b5060006135428460e00151610a25565b60208082015160009081526005909152604080822081516060810190925280549394509192909190829060ff16600481111561358e57634e487b7160e01b600052602160045260246000fd5b60048111156135ad57634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b0316602080840191909152600160481b90910461ffff166040928301528151634d4502c960e11b815291519293507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692639a8a0592926004808201939291829003018186803b15801561363857600080fd5b505afa15801561364c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061367091906153d2565b61ffff16826040015161ffff161461369b57604051633bec3b7d60e11b815260040160405180910390fd5b604081015161ffff166136c1576040516302a74e7560e21b815260040160405180910390fd5b6000815160048111156136e457634e487b7160e01b600052602160045260246000fd5b1461370257604051632916ae3360e01b815260040160405180910390fd5b60208281015160009081526005909152604090819020805460ff19166004179055810151606086015161ffff908116911614613751576040516327e8d62960e11b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008560800151141580156137a35750306001600160a01b03166137978660800151613996565b6001600160a01b031614155b156137c15760405163d08bf9e160e01b815260040160405180910390fd5b60006137d08360800151613996565b60a08401516060850151919250906000906137ea90613996565b905060006001600160a01b03821661380457506012613810565b61380d82613f96565b90505b60006138298760c001516001600160401b0316836149ce565b905060006138448860e001516001600160401b0316846149ce565b9050600061385f88602001516001600160401b0316856149ce565b905060008261386e8584615b3b565b6138789190615b3b565b90506001600160a01b0386166138ab5761389287856149fc565b61389c33846149fc565b6138a688826149fc565b6138e7565b6138bf6001600160a01b0387168886614a95565b6138d36001600160a01b0387163385614a95565b6138e76001600160a01b0387168983614a95565b6020808b0151604080519182529181018390527fbff5487f6422ba4acbcde6bd5e0ccb83124c240b9deb6a72e7b5eb8c7b71d6fc910160405180910390a1505050505050505050505050506109d66001600055565b6002600054141561398f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610871565b6002600055565b60006001600160a01b03198216156139c157604051633d94b76f60e21b815260040160405180910390fd5b5090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015613a1e57600080fd5b505afa158015613a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a5691906153d2565b61ffff16826040015161ffff1614613a8157604051633bec3b7d60e11b815260040160405180910390fd5b604081015161ffff16613aa7576040516302a74e7560e21b815260040160405180910390fd5b600081516004811115613aca57634e487b7160e01b600052602160045260246000fd5b14613ae857604051632916ae3360e01b815260040160405180910390fd5b6020828101516000908152600590915260408120805460ff191660021790556080830151613b1590613996565b90506000613b268460600151613996565b905060006001600160a01b038216613b4057506012613b4c565b613b4982613f96565b90505b6000613b6585602001516001600160401b0316836149ce565b90506001600160a01b038316613b8457613b7f84826149fc565b613b98565b613b986001600160a01b0384168583614a95565b7f4bdcff348c4d11383c487afb95f732f243d93fbfc478aa736a4981cf6a6409118660200151604051613bcd91815260200190565b60405180910390a1505050505050565b6000613bea8260016159d4565b83511015613c305760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b6044820152606401610871565b50818101600101515b92915050565b6000613c4c8260206159d4565b83511015613c945760405162461bcd60e51b8152602060048201526015602482015274746f427974657333325f6f75744f66426f756e647360581b6044820152606401610871565b50016020015190565b6000613caa8260026159d4565b83511015613cf15760405162461bcd60e51b8152602060048201526014602482015273746f55696e7431365f6f75744f66426f756e647360601b6044820152606401610871565b50016002015190565b6000613d078260086159d4565b83511015613d4e5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b6044820152606401610871565b50016008015190565b6001600160a01b03831663d505accf833084356020860135613d7f6060880160408901615507565b6040516001600160e01b031960e088901b1681526001600160a01b0395861660048201529490931660248501526044840191909152606483015260ff166084820152606084013560a4820152608084013560c482015260e401600060405180830381600087803b158015613df257600080fd5b505af1158015613e06573d6000803e3d6000fd5b50505050505050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038616906370a082319060240160206040518083038186803b158015613e5357600080fd5b505afa158015613e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e8b91906153ee565b9050613ea26001600160a01b038616843087613f25565b6040516370a0823160e01b815230600482015281906001600160a01b038716906370a082319060240160206040518083038186803b158015613ee357600080fd5b505afa158015613ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1b91906153ee565b611fd09190615b3b565b6040516001600160a01b0380851660248301528316604482015260648101829052613f909085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614ac5565b50505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b179052905160009182916001600160a01b03851691613fd99161566e565b600060405180830381855afa9150503d8060008114614014576040519150601f19603f3d011682016040523d82523d6000602084013e614019565b606091505b5091505080806020019051810190611c829190615523565b600060088260ff1611156140625761404a600883615b52565b61405590600a615a71565b61405f9084615a0e565b92505b5090919050565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810191909152604051806102000160405280866000015181526020018461ffff1681526020018581526020018660e00151815260200186610100015161ffff1681526020018660200151815260200186604001516001600160401b0316815260200186606001516001600160401b0316815260200186608001516001600160401b031681526020018660a001516001600160401b031681526020018660c001516001600160401b03168152602001866101200151815260200186610140015160ff1681526020018360ff16815260200186610160015160ff1681526020018661018001518152509050949350505050565b6060816000015182602001518360400151846060015185608001518660a001518760c001518860e001518961010001518a61012001518b61014001518c61016001518d61018001516040516020016142399d9c9b9a9998979695949392919061558d565b60408051601f19818403018152908290526101a08401516101c08501516101e08601516001600160f81b031960f893841b811660208701529190921b16602184015260228301529150613c399060420160408051601f198184030181529190528290614b9a565b604080517fc1e8426d70a8367e3d86a5f2e0bdec2344bd6a74f82bfdf50cdfdc08a36500f160208201529081018490526060810183905260808101829052600090819060a0016040516020818303038152906040529050611fd0600454828051906020012060405161190160f01b8152600281019290925260228201526042902090565b602081015160009081906001600160a01b031661434357506012614353565b6143508360200151613f96565b90505b60808301516000906001600160a01b031615801590614378575060a084015160ff1615155b156143a0576127108460a0015160ff16866143939190615b1c565b61439d9190615a0e565b90505b60008460c0015160ff166000146143d4576127108560c0015160ff16876143c79190615b1c565b6143d19190615a0e565b90505b806143df8388615b3b565b6143e99190615b3b565b9350600061440486604001516001600160401b0316856149ce565b9050808510156144275760405163162908e360e11b815260040160405180910390fd5b60208601516001600160a01b03166145c9578560e00151801561444a5750863414155b806144fc57508560e001511580156144fc57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b1580156144b657600080fd5b505afa1580156144ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144ee91906153ee565b6144f890886159d4565b3414155b1561451a576040516317dfbee160e01b815260040160405180910390fd5b821561452e5761452e8660800151846149fc565b81156145b857600154604080516331056e5760e21b815290516145b8926001600160a01b03169163c415b95c916004808301926020929190829003018186803b15801561457a57600080fd5b505afa15801561458e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145b29190614fdf565b836149fc565b85516145c490866149fc565b6148a3565b60608601516001600160401b0316156146eb5760006145f687606001516001600160401b031660126149ce565b90508660e0015180156146095750803414155b806146bb57508660e001511580156146bb57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b15801561467557600080fd5b505afa158015614689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146ad91906153ee565b6146b790826159d4565b3414155b156146d957604051636e51edcd60e11b815260040160405180910390fd5b86516146e590826149fc565b506147c1565b8560e0015180156146fb57503415155b806147a357508560e001511580156147a357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b15801561476757600080fd5b505afa15801561477b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061479f91906153ee565b3414155b156147c1576040516317dfbee160e01b815260040160405180910390fd5b82156147ed576147ed86608001518488602001516001600160a01b0316614a959092919063ffffffff16565b811561488657600154604080516331056e5760e21b81529051614886926001600160a01b03169163c415b95c916004808301926020929190829003018186803b15801561483957600080fd5b505afa15801561484d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148719190614fdf565b60208801516001600160a01b03169084614a95565b855160208701516148a3916001600160a01b039091169087614a95565b5050505092915050565b60608160000151826020015183604001518460600151856080015160405160200161491695949392919060f89590951b6001600160f81b0319168552600185019390935260f09190911b6001600160f01b03191660218401526023830152604382015260630190565b6040516020818303038152906040529050919050565b6060816000015182602001518360400151846060015185608001518660a001518760c001518860e0015160405160200161491698979695949392919060f89890981b6001600160f81b0319168852600188019690965260f09490941b6001600160f01b031916602187015260238601929092526043850152606384015260c090811b6001600160c01b0319908116608385015291901b16608b82015260930190565b600060088260ff161115614062576149e7600883615b52565b6149f290600a615a71565b61405f9084615b1c565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114614a49576040519150601f19603f3d011682016040523d82523d6000602084013e614a4e565b606091505b5050905080614a905760405162461bcd60e51b815260206004820152600e60248201526d1c185e5b595b9d0819985a5b195960921b6044820152606401610871565b505050565b6040516001600160a01b038316602482015260448101829052614a9090849063a9059cbb60e01b90606401613f59565b6000614b1a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614c179092919063ffffffff16565b9050805160001480614b3b575080806020019051810190614b3b91906151a2565b614a905760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610871565b6060806040519050835180825260208201818101602087015b81831015614bcb578051835260209283019201614bb3565b50855184518101855292509050808201602086015b81831015614bf8578051835260209283019201614be0565b508651929092011591909101601f01601f191660405250905092915050565b6060611a43848460008585600080866001600160a01b03168587604051614c3e919061566e565b60006040518083038185875af1925050503d8060008114614c7b576040519150601f19603f3d011682016040523d82523d6000602084013e614c80565b606091505b50915091506111a68783838760608315614cf8578251614cf1576001600160a01b0385163b614cf15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610871565b5081611a43565b611a438383815115614d0d5781518083602001fd5b8060405162461bcd60e51b81526004016108719190615726565b600082601f830112614d37578081fd5b81516020614d4c614d478361598a565b61595a565b80838252828201915082860187848660071b8901011115614d6b578586fd5b855b85811015614dd257608080838b031215614d85578788fd5b614d8d6158ec565b835181528684015187820152604080850151614da881615c30565b90820152606084810151614dbb81615c30565b908201528552938501939190910190600101614d6d565b5090979650505050505050565b80516131df81615bfd565b600082601f830112614dfa578081fd5b8135614e08614d47826159ad565b818152846020838601011115614e1c578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112614e46578081fd5b8151614e54614d47826159ad565b818152846020838601011115614e68578283fd5b611a43826020830160208701615b75565b60006101a08284031215614e8b578081fd5b614e93615914565b90508135815260208201356020820152614eaf60408301614f97565b6040820152614ec060608301614f97565b6060820152614ed160808301614f97565b6080820152614ee260a08301614f97565b60a0820152614ef360c08301614f97565b60c082015260e082013560e0820152610100614f10818401614f6d565b908201526101208281013590820152610140614f2d818401614fad565b90820152610160614f3f838201614fad565b818301525061018080830135818301525092915050565b600060a08284031215614f67578081fd5b50919050565b80356131df81615c0b565b80516131df81615c0b565b805163ffffffff811681146131df57600080fd5b80356131df81615c1b565b80516131df81615c1b565b80356131df81615c30565b80516131df81615c30565b600060208284031215614fd4578081fd5b8135611c8281615be8565b600060208284031215614ff0578081fd5b8151611c8281615be8565b60008060006101e08486031215615010578182fd5b833561501b81615be8565b9250602084013591506150318560408601614e79565b90509250925092565b60008060008060008060006102c0888a031215615055578485fd5b873561506081615be8565b9650602088013595506150768960408a01614e79565b94506101e088013593506102008801356001600160401b038082111561509a578485fd5b818a0191508a601f8301126150ad578485fd5b8135818111156150bb578586fd5b8b60208285010111156150cc578586fd5b6020830195508094505050506150e6896102208a01614f56565b905092959891949750929550565b60006020808385031215615106578182fd5b82356001600160401b0381111561511b578283fd5b8301601f8101851361512b578283fd5b8035615139614d478261598a565b80828252848201915084840188868560051b8701011115615158578687fd5b8694505b8385101561517a57803583526001949094019391850191850161515c565b50979650505050505050565b600060208284031215615197578081fd5b8135611c8281615bfd565b6000602082840312156151b3578081fd5b8151611c8281615bfd565b6000602082840312156151cf578081fd5b5035919050565b600080600080600061022086880312156151ee578283fd5b853594506151ff8760208801614e79565b93506101c086013561521081615c0b565b92506101e086013561522181615c30565b94979396509194610200013592915050565b600060208284031215615244578081fd5b81356001600160401b03811115615259578182fd5b611a4384828501614dea565b60006101a08284031215615277578081fd5b611c828383614e79565b600080600060608486031215615295578081fd5b83516001600160401b03808211156152ab578283fd5b9085019061016082880312156152bf578283fd5b6152c7615937565b6152d083614fb8565b81526152de60208401614f83565b60208201526152ef60408401614f83565b604082015261530060608401614f78565b60608201526080830151608082015261531b60a08401614fa2565b60a082015261532c60c08401614fb8565b60c082015260e083015182811115615342578485fd5b61534e89828601614e36565b60e083015250610100615362818501614f83565b908201526101208381015183811115615379578586fd5b6153858a828701614d27565b9183019190915250610140838101519082015294506153a660208701614ddf565b935060408601519150808211156153bb578283fd5b506153c886828701614e36565b9150509250925092565b6000602082840312156153e3578081fd5b8151611c8281615c0b565b6000602082840312156153ff578081fd5b5051919050565b600080600080600080600080610280898b031215615422578182fd5b8835975060208901359650604089013561543b81615c0b565b955060608901359450608089013561545281615c30565b93506154618a60a08b01614e79565b9250610240890135915061026089013561547a81615bfd565b809150509295985092959890939650565b600080600080608085870312156154a0578182fd5b8435935060208501356001600160401b038111156154bc578283fd5b6154c887828801614dea565b9350506040850135915060608501356154e081615bfd565b939692955090935050565b6000602082840312156154fc578081fd5b8151611c8281615c1b565b600060208284031215615518578081fd5b8135611c8281615c30565b600060208284031215615534578081fd5b8151611c8281615c30565b60008151808452615557816020860160208601615b75565b601f01601f19169290920160200192915050565b6005811061558957634e487b7160e01b600052602160045260246000fd5b9052565b8d8152600061ffff60f01b808f60f01b1660208401528d60228401528c6042840152808c60f01b166062840152508960648301526001600160401b0360c01b8960c01b1660848301526155ef608c83018960c01b6001600160c01b0319169052565b615608609483018860c01b6001600160c01b0319169052565b615621609c83018760c01b6001600160c01b0319169052565b61563a60a483018660c01b6001600160c01b0319169052565b8360ac83015261565960cc83018460f81b6001600160f81b0319169052565b5060cd019d9c50505050505050505050505050565b60008251615680818460208701615b75565b9190910192915050565b6000835161569c818460208801615b75565b8351908301906156b0818360208801615b75565b01949350505050565b602080825282518282018190526000919060409081850190868401855b828110156157195781516156eb85825161556b565b808701516001600160401b03168588015285015161ffff1685850152606090930192908501906001016156d6565b5091979650505050505050565b602081526000611c82602083018461553f565b60608152600061574c606083018661553f565b6020830194909452506001600160a01b0391909116604090910152919050565b6060810161577a828661556b565b6001600160401b038416602083015261ffff83166040830152949350505050565b63ffffffff841681526060602082015260006157ba606083018561553f565b905060ff83166040830152949350505050565b815160ff1681526101c081016020830151602083015260408301516157f8604084018261ffff169052565b50606083015160608301526080830151608083015260a083015160a083015260c083015161583160c08401826001600160401b03169052565b5060e083015161584c60e08401826001600160401b03169052565b50610100838101516001600160401b03169083015261012080840151908301526101408084015160ff9081169184019190915261016080850151909116908301526101808084015161ffff16908301526101a092830151929091019190915290565b6001600160401b039590951685526001600160a01b03939093166020850152604084019190915261ffff16606083015260ff16608082015260a00190565b604051608081016001600160401b038111828210171561590e5761590e615bd2565b60405290565b6040516101a081016001600160401b038111828210171561590e5761590e615bd2565b60405161016081016001600160401b038111828210171561590e5761590e615bd2565b604051601f8201601f191681016001600160401b038111828210171561598257615982615bd2565b604052919050565b60006001600160401b038211156159a3576159a3615bd2565b5060051b60200190565b60006001600160401b038211156159c6576159c6615bd2565b50601f01601f191660200190565b600082198211156159e7576159e7615bbc565b500190565b60006001600160401b038083168185168083038211156156b0576156b0615bbc565b600082615a2957634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115615a69578160001904821115615a4f57615a4f615bbc565b80851615615a5c57918102915b93841c9390800290615a33565b509250929050565b6000611c8260ff841683600082615a8a57506001613c39565b81615a9757506000613c39565b8160018114615aad5760028114615ab757615ad3565b6001915050613c39565b60ff841115615ac857615ac8615bbc565b50506001821b613c39565b5060208310610133831016604e8410600b8410161715615af6575081810a613c39565b615b008383615a2e565b8060001904821115615b1457615b14615bbc565b029392505050565b6000816000190483118215151615615b3657615b36615bbc565b500290565b600082821015615b4d57615b4d615bbc565b500390565b600060ff821660ff841680821015615b6c57615b6c615bbc565b90039392505050565b60005b83811015615b90578181015183820152602001615b78565b83811115613f905750506000910152565b6000600019821415615bb557615bb5615bbc565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146109d657600080fd5b80151581146109d657600080fd5b61ffff811681146109d657600080fd5b6001600160401b03811681146109d657600080fd5b60ff811681146109d657600080fdfea2646970667358221220df2c4fbf3c3344be40e083946a8a8f429e6dd694c3b7b5c77d1fa2fbd798904864736f6c6343000804003300000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b000000000000000000000000f93191d350117723dbeda5484a3b0996d285cecf000000000000000000000000000000000000000000000000000000000000000134cdc6b2623f36d60ae820e95b60f764e81ec2cd3b57b77e3f8e25ddd43ac37323b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc0690000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x6080604052600436106101d15760003560e01c806381b152c0116100f7578063b866e17311610095578063e8dfd50811610064578063e8dfd508146106ea578063f1d3ac4f1461071d578063fa6a6d361461074a578063feea83f11461077e57600080fd5b8063b866e17314610663578063bedb86fb14610676578063d0fb020314610696578063d96427ff146106b657600080fd5b80638e8d142b116100d15780638e8d142b1461055f57806397b6e0031461057f5780639c3f1e901461059f578063a5e1ea7d146105fa57600080fd5b806381b152c01461045c57806384acd1bb146104e45780638a261c671461051857600080fd5b8063472d35b91161016f578063526bb8651161013e578063526bb865146103e5578063538ee295146103f85780635c975abb146104185780637226f4e01461044957600080fd5b8063472d35b9146103675780634818e84d14610387578063488c3591146103a75780634a85d788146103d257600080fd5b80633a30b37f116101ab5780633a30b37f146102bf5780633d474866146102ed578063452a93201461031a578063459656ee1461035257600080fd5b8063119abf67146101dd5780632fcb4f04146101ff57806339f3fbd91461021f57600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506101fd6101f8366004615233565b61079e565b005b34801561020b57600080fd5b506101fd61021a366004614fc3565b6109d9565b34801561022b57600080fd5b5061023f61023a366004615233565b610a25565b6040516102b6919060006101008201905060ff83511682526020830151602083015261ffff6040840151166040830152606083015160608301526080830151608083015260a083015160a083015260c08301516001600160401b0380821660c08501528060e08601511660e0850152505092915050565b60405180910390f35b3480156102cb57600080fd5b506102df6102da36600461503a565b610b8b565b6040519081526020016102b6565b3480156102f957600080fd5b5061030d6103083660046150f4565b6111b1565b6040516102b691906156b9565b34801561032657600080fd5b5060025461033a906001600160a01b031681565b6040516001600160a01b0390911681526020016102b6565b34801561035e57600080fd5b506101fd61133b565b34801561037357600080fd5b506101fd610382366004614fc3565b611389565b34801561039357600080fd5b5060035461033a906001600160a01b031681565b6103ba6103b536600461548b565b6113d5565b6040516001600160401b0390911681526020016102b6565b6103ba6103e03660046150f4565b611a4b565b6103ba6103f33660046151d6565b611c89565b34801561040457600080fd5b506101fd610413366004615507565b611fd9565b34801561042457600080fd5b5060035461043990600160a01b900460ff1681565b60405190151581526020016102b6565b6103ba610457366004615406565b612023565b34801561046857600080fd5b506104af6104773660046151be565b6006602052600090815260409020805460018201546002830154600384015460049094015460ff90931693919261ffff909116919085565b6040805160ff9096168652602086019490945261ffff909216928401929092526060830191909152608082015260a0016102b6565b3480156104f057600080fd5b5061033a7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b81565b34801561052457600080fd5b5061054c7f000000000000000000000000000000000000000000000000000000000000000181565b60405161ffff90911681526020016102b6565b34801561056b57600080fd5b506102df61057a366004614ffb565b61251c565b34801561058b57600080fd5b506101fd61059a366004615233565b61296a565b3480156105ab57600080fd5b506105eb6105ba3660046151be565b60056020526000908152604090205460ff81169061010081046001600160401b031690600160481b900461ffff1683565b6040516102b69392919061576c565b34801561060657600080fd5b5061061a610615366004615233565b612cc7565b6040516102b69190600060a08201905060ff83511682526020830151602083015261ffff6040840151166040830152606083015160608301526080830151608083015292915050565b6102df610671366004615265565b612da9565b34801561068257600080fd5b506101fd610691366004615186565b6131e4565b3480156106a257600080fd5b5060015461033a906001600160a01b031681565b3480156106c257600080fd5b506102df7f23b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc06981565b3480156106f657600080fd5b5060015461070b90600160a01b900460ff1681565b60405160ff90911681526020016102b6565b34801561072957600080fd5b5061073d610738366004615233565b61322c565b6040516102b691906157cd565b34801561075657600080fd5b506102df7f34cdc6b2623f36d60ae820e95b60f764e81ec2cd3b57b77e3f8e25ddd43ac37381565b34801561078a57600080fd5b506101fd610799366004615233565b61345f565b6107a661393c565b60008060007f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016107f79190615726565b60006040518083038186803b15801561080f57600080fd5b505afa158015610823573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261084b9190810190615281565b92509250925081819061087a5760405162461bcd60e51b81526004016108719190615726565b60405180910390fd5b50600061088a8460e00151612cc7565b60208082015160009081526005909152604080822081516060810190925280549394509192909190829060ff1660048111156108d657634e487b7160e01b600052602160045260246000fd5b60048111156108f557634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b03166020830152600160481b900461ffff908116604092830152908201516060880151929350811691161461094d576040516327e8d62960e11b815260040160405180910390fd5b7f23b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc06985608001511415801561099f5750306001600160a01b03166109938660800151613996565b6001600160a01b031614155b156109bd5760405163d08bf9e160e01b815260040160405180910390fd5b6109c782826139c5565b50505050506109d66001600055565b50565b6002546001600160a01b03163314610a03576040516282b42960e81b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905290610a708382613bdd565b60ff168252610a806001826159d4565b825190915060ff16600314610aa857604051634a7f394f60e01b815260040160405180910390fd5b610ab28382613c3f565b602080840191909152610ac590826159d4565b9050610ad18382613c9d565b61ffff166040830152610ae56002826159d4565b9050610af18382613c3f565b6060830152610b016020826159d4565b9050610b0d8382613c3f565b6080830152610b1d6020826159d4565b9050610b298382613c3f565b60a0830152610b396020826159d4565b9050610b458382613cfa565b6001600160401b031660c0830152610b5e6008826159d4565b9050610b6a8382613cfa565b6001600160401b031660e0830152610b836008826159d4565b905050919050565b6000610b9561393c565b600354600160a01b900460ff1615610bc0576040516313d0ff5960e31b815260040160405180910390fd5b6000610bcf8760000151613996565b604051636eb1769f60e11b81526001600160a01b0380831660048301523060248301529192506000918b169063dd62ed3e9060440160206040518083038186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5491906153ee565b9050610c60878a6159d4565b811015610c7257610c728a8386613d57565b610c7d8a8a84613e0f565b98508615610c9a57610c9a6001600160a01b038b1683338a613f25565b6000610cae8a610ca98d613f96565b614031565b90506001600160401b038116610cd7576040516356fdd81f60e11b815260040160405180910390fd5b806001600160401b03168960a001518a60800151610cf591906159ec565b6001600160401b031610610d1c5760405163192069c360e31b815260040160405180910390fd5b6020890151158015610d3a575060608901516001600160401b031615155b15610d5857604051636e51edcd60e11b815260040160405180910390fd5b6000600160009054906101000a90046001600160a01b03166001600160a01b03166302fb1eec838e8d602001518e61010001518f61014001516040518663ffffffff1660e01b8152600401610db19594939291906158ae565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190615523565b9050603260ff168a610140015160ff161180610e205750603260ff8216115b15610e3e57604051633f6e8d0d60e21b815260040160405180910390fd5b610eee610ee98b8e6001600160a01b031660001b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015610eab57600080fd5b505afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee391906153d2565b85614069565b6141d5565b80519060200120945087878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250733ca829b74971035fe0b733cd6297ca7a8a39e7c093638048608093509150610f569050888f8e6142a0565b876040518463ffffffff1660e01b8152600401610f7593929190615739565b60006040518083038186803b158015610f8d57600080fd5b505af4158015610fa1573d6000803e3d6000fd5b5050505089610100015161ffff166000148061105957507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b15801561101157600080fd5b505afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104991906153d2565b61ffff168a610100015161ffff16145b15611077576040516355ef7a1d60e11b815260040160405180910390fd5b600085815260056020526040902054600160481b900461ffff16156110af5760405163015b9d8b60e41b815260040160405180910390fd5b6040805160608101825260008082526001600160401b0385166020808401919091526101008e015161ffff1683850152888252600590529190912081518154829060ff1916600183600481111561111657634e487b7160e01b600052602160045260246000fd5b02179055506020820151815460409384015161ffff16600160481b0261ffff60481b196001600160401b0390931661010002929092166affffffffffffffffffff001990911617179055517f918554b6bd6e2895ce6553de5de0e1a69db5289aa0e4fe193a0dcd1f14347477906111909087815260200190565b60405180910390a1505050506111a66001600055565b979650505050505050565b6060600082516001600160401b038111156111dc57634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561122757816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816111fa5790505b50905060005b8351811015611334576005600085838151811061125a57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206040518060600160405290816000820160009054906101000a900460ff1660048111156112ad57634e487b7160e01b600052602160045260246000fd5b60048111156112cc57634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b03166020830152600160481b900461ffff16604090910152825183908390811061131657634e487b7160e01b600052603260045260246000fd5b6020026020010181905250808061132c90615ba1565b91505061122d565b5092915050565b6003546001600160a01b03163314611365576040516282b42960e81b815260040160405180910390fd5b600354600280546001600160a01b0319166001600160a01b03909216919091179055565b6002546001600160a01b031633146113b3576040516282b42960e81b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006113df61393c565b60008060007f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663c0fd8bde886040518263ffffffff1660e01b81526004016114309190615726565b60006040518083038186803b15801561144857600080fd5b505afa15801561145c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114849190810190615281565b9250925092508181906114aa5760405162461bcd60e51b81526004016108719190615726565b507f000000000000000000000000000000000000000000000000000000000000000161ffff16836060015161ffff16146114f7576040516327e8d62960e11b815260040160405180910390fd5b7f34cdc6b2623f36d60ae820e95b60f764e81ec2cd3b57b77e3f8e25ddd43ac37383608001511461153b5760405163d08bf9e160e01b815260040160405180910390fd5b600061154a8460e0015161322c565b9050600061155b8260a00151613996565b90506001600160a01b0381161561157a57611577818b33613e0f565b99505b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b1580156115d357600080fd5b505afa1580156115e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160b91906153d2565b61ffff16826040015161ffff1614611636576040516355ef7a1d60e11b815260040160405180910390fd5b326001600160a01b031661164d8360800151613996565b6001600160a01b031614611673576040516282b42960e81b815260040160405180910390fd5b8161010001516001600160401b03164211156116a2576040516354a36da760e11b815260040160405180910390fd5b60208281015160009081526005909152604081205460ff1660048111156116d957634e487b7160e01b600052602160045260246000fd5b146116f757604051632916ae3360e01b815260040160405180910390fd5b602082810151600090815260059091526040808220805460ff19166001179055805161010081019091526060840151819061173190613996565b6001600160a01b03168152602001836001600160a01b031681526020018460c001516001600160401b031681526020018460e001516001600160401b03168152602001611782856101200151613996565b6001600160a01b0316815260200184610140015160ff16815260200184610160015160ff168152602001891515815250905060006117c08c83614324565b905060006040518060a00160405280600260048111156117f057634e487b7160e01b600052602160045260246000fd5b60ff1681526020018660200151815260200186610180015161ffff168152602001866101a0015181526020018c8152509050891561188a576020858101516000908152600682526040908190208351815460ff191660ff90911617815591830151600183015582015160028201805461ffff191661ffff9092169190911790556060820151600382015560808201516004909101556119e0565b6000611895826148ad565b90507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663b19a437e7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b15801561191f57600080fd5b505afa158015611933573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195791906153ee565b60015460405160e084901b6001600160e01b031916815261198a916000918791600160a01b900460ff169060040161579b565b6020604051808303818588803b1580156119a357600080fd5b505af11580156119b7573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906119dc91906154eb565b9950505b602080860151604080519182526001600160401b038c16928201929092529081018390527f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b9060600160405180910390a15050505050505050611a436001600055565b949350505050565b8051604051600160fa1b602082015260f09190911b6001600160f01b03191660218201526000908190602301604051602081830303815290604052905060005b8351811015611bcf57600060066000868481518110611aba57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252818101929092526040908101600020815160a081018352815460ff1680825260018301549482019490945260028083015461ffff1693820193909352600382015460608201526004909101546080820152925014611b3957604051634a7f394f60e01b815260040160405180910390fd5b60008160200151826040015183606001518460800151604051602001611b85949392919093845260f09290921b6001600160f01b03191660208401526022830152604282015260620190565b60405160208183030381529060405290508381604051602001611ba992919061568a565b604051602081830303815290604052935050508080611bc790615ba1565b915050611a8b565b506001546040516358cd21bf60e11b81527f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b03169163b19a437e913491611c30916000918791600160a01b90910460ff169060040161579b565b6020604051808303818588803b158015611c4957600080fd5b505af1158015611c5d573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611c8291906154eb565b9392505050565b6000611c9361393c565b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015611cec57600080fd5b505afa158015611d00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2491906153d2565b61ffff166101008601526000611d3c86888787614069565b90506000611d49826141d5565b805160209182012060008181526005909252604080832081516060810190925280549294509091829060ff166004811115611d9457634e487b7160e01b600052602160045260246000fd5b6004811115611db357634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b039081166020840152600160481b90910461ffff16604090920191909152610140850151919250164211611e0a576040516354a36da760e11b815260040160405180910390fd5b600081516004811115611e2d57634e487b7160e01b600052602160045260246000fd5b14611e4b57604051632916ae3360e01b815260040160405180910390fd5b6000828152600560209081526040808320805460ff19166003908117909155815161010080820184529181528084018790529287015161ffff16838301529086015160608301528551608083015260a082018890528501516001600160401b0390811660c08301526101208601511660e082015290611ec98261492c565b6001546040516358cd21bf60e11b81529192507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b03169163b19a437e913491611f2b916000918791600160a01b900460ff169060040161579b565b6020604051808303818588803b158015611f4457600080fd5b505af1158015611f58573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611f7d91906154eb565b604080518681526001600160401b03831660208201529197507f45a58de39e77dfc9cd1d63970a706575668048121d822749d2298eb75125123e910160405180910390a15050505050611fd06001600055565b95945050505050565b6002546001600160a01b03163314612003576040516282b42960e81b815260040160405180910390fd5b6001805460ff909216600160a01b0260ff60a01b19909216919091179055565b600061202d61393c565b61016084015160ff1660011461205657604051631fa84deb60e31b815260040160405180910390fd5b60006120658560200151613996565b90506001600160a01b0381161561208457612081818b33613e0f565b99505b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b1580156120dd57600080fd5b505afa1580156120f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061211591906153d2565b61ffff16610100860152600061212d86898b8a614069565b9050600061213a826141d5565b8051906020012090508a81146121635760405163561a411d60e11b815260040160405180910390fd5b8161014001516001600160401b0316421115612192576040516354a36da760e11b815260040160405180910390fd5b60008181526005602052604081205460ff1660048111156121c357634e487b7160e01b600052602160045260246000fd5b146121e157604051632916ae3360e01b815260040160405180910390fd5b600081815260056020526040808220805460ff19166001179055805161010081019091526060840151819061221590613996565b6001600160a01b03168152602001856001600160a01b031681526020018460c001516001600160401b031681526020018460e001516001600160401b03168152602001612266856101600151613996565b6001600160a01b0316815260200184610180015160ff1681526020018a60ff1681526020018715158152509050600061229f8e83614324565b905060006040518060a00160405280600260048111156122cf57634e487b7160e01b600052602160045260246000fd5b60ff168152602001858152602001866020015161ffff168152602001866040015181526020018a81525090508715612361576000848152600660209081526040918290208351815460ff191660ff9091161781559083015160018201559082015160028201805461ffff191661ffff9092169190911790556060820151600382015560808201516004909101556124b7565b600061236c826148ad565b90507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663b19a437e7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b1580156123f657600080fd5b505afa15801561240a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242e91906153ee565b60015460405160e084901b6001600160e01b0319168152612461916000918791600160a01b900460ff169060040161579b565b6020604051808303818588803b15801561247a57600080fd5b505af115801561248e573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906124b391906154eb565b9750505b604080518581526001600160401b03891660208201529081018390527f6ec9b1b5a9f54d929394f18dac4ba1b1cc79823f2266c2d09cab8a3b4700b40b9060600160405180910390a15050505050506125106001600055565b98975050505050505050565b600061252661393c565b600354600160a01b900460ff1615612551576040516313d0ff5960e31b815260040160405180910390fd5b61255c848433613e0f565b9250600061256d84610ca987613f96565b90506001600160401b038116612596576040516356fdd81f60e11b815260040160405180910390fd5b806001600160401b03168360a0015184608001516125b491906159ec565b6001600160401b0316106125db5760405163192069c360e31b815260040160405180910390fd5b60208301511580156125f9575060608301516001600160401b031615155b1561261757604051636e51edcd60e11b815260040160405180910390fd5b600154602084015161010085015161014086015160405162bec7bb60e21b81526000946001600160a01b0316936302fb1eec9361265d9388938d939291906004016158ae565b60206040518083038186803b15801561267557600080fd5b505afa158015612689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ad9190615523565b9050603260ff1684610140015160ff1611806126cc5750603260ff8216115b156126ea57604051633f6e8d0d60e21b815260040160405180910390fd5b600061275685886001600160a01b031660001b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015610eab57600080fd5b9050612761816141d5565b80519060200120935084610100015161ffff166000148061281e57507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b1580156127d657600080fd5b505afa1580156127ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280e91906153d2565b61ffff1685610100015161ffff16145b1561283c576040516355ef7a1d60e11b815260040160405180910390fd5b600084815260056020526040902054600160481b900461ffff16156128745760405163015b9d8b60e41b815260040160405180910390fd5b6040805160608101825260008082526001600160401b03861660208084019190915261010089015161ffff1683850152878252600590529190912081518154829060ff191660018360048111156128db57634e487b7160e01b600052602160045260246000fd5b02179055506020820151815460409384015161ffff16600160481b0261ffff60481b196001600160401b0390931661010002929092166affffffffffffffffffff001990911617179055517f918554b6bd6e2895ce6553de5de0e1a69db5289aa0e4fe193a0dcd1f14347477906129559086815260200190565b60405180910390a1505050611c826001600055565b61297261393c565b60008060007f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016129c39190615726565b60006040518083038186803b1580156129db57600080fd5b505afa1580156129ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a179190810190615281565b925092509250818190612a3d5760405162461bcd60e51b81526004016108719190615726565b5060e0830151600090612a509082613bdd565b9050600160ff8216600414612a7857604051634a7f394f60e01b815260040160405180910390fd5b60e0850151600090612a8a9083613c9d565b9050612a976002836159d4565b915060005b8161ffff16811015612cb6576040805160a081019091526002815260e0880151600091906020820190612acf9087613c3f565b8152602001612aef866020612ae491906159d4565b60e08c015190613c9d565b61ffff168152602001612b11612b068760226159d4565b60e08c015190613c3f565b8152602001612b24612b068760426159d4565b90529050612b336062856159d4565b60208083015160009081526005909152604080822081516060810190925280549397509192909190829060ff166004811115612b7f57634e487b7160e01b600052602160045260246000fd5b6004811115612b9e57634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b03166020830152600160481b900461ffff166040909101529050600081516004811115612beb57634e487b7160e01b600052602160045260246000fd5b14612bf7575050612ca4565b806040015161ffff16896060015161ffff1614612c27576040516327e8d62960e11b815260040160405180910390fd5b7f23b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc069896080015114158015612c795750306001600160a01b0316612c6d8a60800151613996565b6001600160a01b031614155b15612c975760405163d08bf9e160e01b815260040160405180910390fd5b612ca182826139c5565b50505b80612cae81615ba1565b915050612a9c565b505050505050506109d66001600055565b6040805160a081018252600080825260208201819052918101829052606081018290526080810182905290612cfc8382613bdd565b60ff168252612d0c6001826159d4565b825190915060ff16600214612d3457604051634a7f394f60e01b815260040160405180910390fd5b612d3e8382613c3f565b602080840191909152612d5190826159d4565b9050612d5d8382613c9d565b61ffff166040830152612d716002826159d4565b9050612d7d8382613c3f565b6060830152612d8d6020826159d4565b9050612d998382613c3f565b6080830152610b836020826159d4565b6000612db361393c565b600354600160a01b900460ff1615612dde576040516313d0ff5960e31b815260040160405180910390fd5b6000612deb346012614031565b90506001600160401b038116612e14576040516356fdd81f60e11b815260040160405180910390fd5b806001600160401b03168360a001518460800151612e3291906159ec565b6001600160401b031610612e595760405163192069c360e31b815260040160405180910390fd5b6020830151158015612e77575060608301516001600160401b031615155b15612e9557604051636e51edcd60e11b815260040160405180910390fd5b600154602084015161010085015161014086015160405162bec7bb60e21b81526000946001600160a01b0316936302fb1eec93612edb93889388939291906004016158ae565b60206040518083038186803b158015612ef357600080fd5b505afa158015612f07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2b9190615523565b9050603260ff1684610140015160ff161180612f4a5750603260ff8216115b15612f6857604051633f6e8d0d60e21b815260040160405180910390fd5b6000612fcb856000801b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015610eab57600080fd5b9050612fd6816141d5565b80519060200120935084610100015161ffff166000148061309357507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b15801561304b57600080fd5b505afa15801561305f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308391906153d2565b61ffff1685610100015161ffff16145b156130b1576040516355ef7a1d60e11b815260040160405180910390fd5b600084815260056020526040902054600160481b900461ffff16156130e95760405163015b9d8b60e41b815260040160405180910390fd5b6040805160608101825260008082526001600160401b03861660208084019190915261010089015161ffff1683850152878252600590529190912081518154829060ff1916600183600481111561315057634e487b7160e01b600052602160045260246000fd5b02179055506020820151815460409384015161ffff16600160481b0261ffff60481b196001600160401b0390931661010002929092166affffffffffffffffffff001990911617179055517f918554b6bd6e2895ce6553de5de0e1a69db5289aa0e4fe193a0dcd1f14347477906131ca9086815260200190565b60405180910390a15050506131df6001600055565b919050565b6002546001600160a01b0316331461320e576040516282b42960e81b815260040160405180910390fd5b60038054911515600160a01b0260ff60a01b19909216919091179055565b604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a08101829052906132a78382613bdd565b60ff1682526132b76001826159d4565b825190915060ff166001146132df57604051634a7f394f60e01b815260040160405180910390fd5b6132e98382613c3f565b6020808401919091526132fc90826159d4565b90506133088382613c9d565b61ffff1661018083015261331d6002826159d4565b90506133298382613c3f565b6101a083015261333a6020826159d4565b90506133468382613c3f565b60608301526133566020826159d4565b90506133628382613c9d565b61ffff1660408301526133766002826159d4565b90506133828382613c3f565b60a08301526133926020826159d4565b905061339e8382613cfa565b6001600160401b031660c08301526133b76008826159d4565b90506133c38382613cfa565b6001600160401b031660e08301526133dc6008826159d4565b90506133e88382613cfa565b6001600160401b03166101008301526134026008826159d4565b905061340e8382613c3f565b61012083015261341f6020826159d4565b905061342b8382613bdd565b60ff1661014083015261343f6001826159d4565b905061344b8382613bdd565b60ff16610160830152612d8d6001826159d4565b61346761393c565b60008060007f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016134b89190615726565b60006040518083038186803b1580156134d057600080fd5b505afa1580156134e4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261350c9190810190615281565b9250925092508181906135325760405162461bcd60e51b81526004016108719190615726565b5060006135428460e00151610a25565b60208082015160009081526005909152604080822081516060810190925280549394509192909190829060ff16600481111561358e57634e487b7160e01b600052602160045260246000fd5b60048111156135ad57634e487b7160e01b600052602160045260246000fd5b8152905461010081046001600160401b0316602080840191909152600160481b90910461ffff166040928301528151634d4502c960e11b815291519293507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b031692639a8a0592926004808201939291829003018186803b15801561363857600080fd5b505afa15801561364c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061367091906153d2565b61ffff16826040015161ffff161461369b57604051633bec3b7d60e11b815260040160405180910390fd5b604081015161ffff166136c1576040516302a74e7560e21b815260040160405180910390fd5b6000815160048111156136e457634e487b7160e01b600052602160045260246000fd5b1461370257604051632916ae3360e01b815260040160405180910390fd5b60208281015160009081526005909152604090819020805460ff19166004179055810151606086015161ffff908116911614613751576040516327e8d62960e11b815260040160405180910390fd5b7f23b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc0698560800151141580156137a35750306001600160a01b03166137978660800151613996565b6001600160a01b031614155b156137c15760405163d08bf9e160e01b815260040160405180910390fd5b60006137d08360800151613996565b60a08401516060850151919250906000906137ea90613996565b905060006001600160a01b03821661380457506012613810565b61380d82613f96565b90505b60006138298760c001516001600160401b0316836149ce565b905060006138448860e001516001600160401b0316846149ce565b9050600061385f88602001516001600160401b0316856149ce565b905060008261386e8584615b3b565b6138789190615b3b565b90506001600160a01b0386166138ab5761389287856149fc565b61389c33846149fc565b6138a688826149fc565b6138e7565b6138bf6001600160a01b0387168886614a95565b6138d36001600160a01b0387163385614a95565b6138e76001600160a01b0387168983614a95565b6020808b0151604080519182529181018390527fbff5487f6422ba4acbcde6bd5e0ccb83124c240b9deb6a72e7b5eb8c7b71d6fc910160405180910390a1505050505050505050505050506109d66001600055565b6002600054141561398f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610871565b6002600055565b60006001600160a01b03198216156139c157604051633d94b76f60e21b815260040160405180910390fd5b5090565b7f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316639a8a05926040518163ffffffff1660e01b815260040160206040518083038186803b158015613a1e57600080fd5b505afa158015613a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a5691906153d2565b61ffff16826040015161ffff1614613a8157604051633bec3b7d60e11b815260040160405180910390fd5b604081015161ffff16613aa7576040516302a74e7560e21b815260040160405180910390fd5b600081516004811115613aca57634e487b7160e01b600052602160045260246000fd5b14613ae857604051632916ae3360e01b815260040160405180910390fd5b6020828101516000908152600590915260408120805460ff191660021790556080830151613b1590613996565b90506000613b268460600151613996565b905060006001600160a01b038216613b4057506012613b4c565b613b4982613f96565b90505b6000613b6585602001516001600160401b0316836149ce565b90506001600160a01b038316613b8457613b7f84826149fc565b613b98565b613b986001600160a01b0384168583614a95565b7f4bdcff348c4d11383c487afb95f732f243d93fbfc478aa736a4981cf6a6409118660200151604051613bcd91815260200190565b60405180910390a1505050505050565b6000613bea8260016159d4565b83511015613c305760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b6044820152606401610871565b50818101600101515b92915050565b6000613c4c8260206159d4565b83511015613c945760405162461bcd60e51b8152602060048201526015602482015274746f427974657333325f6f75744f66426f756e647360581b6044820152606401610871565b50016020015190565b6000613caa8260026159d4565b83511015613cf15760405162461bcd60e51b8152602060048201526014602482015273746f55696e7431365f6f75744f66426f756e647360601b6044820152606401610871565b50016002015190565b6000613d078260086159d4565b83511015613d4e5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b6044820152606401610871565b50016008015190565b6001600160a01b03831663d505accf833084356020860135613d7f6060880160408901615507565b6040516001600160e01b031960e088901b1681526001600160a01b0395861660048201529490931660248501526044840191909152606483015260ff166084820152606084013560a4820152608084013560c482015260e401600060405180830381600087803b158015613df257600080fd5b505af1158015613e06573d6000803e3d6000fd5b50505050505050565b6040516370a0823160e01b815230600482015260009081906001600160a01b038616906370a082319060240160206040518083038186803b158015613e5357600080fd5b505afa158015613e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e8b91906153ee565b9050613ea26001600160a01b038616843087613f25565b6040516370a0823160e01b815230600482015281906001600160a01b038716906370a082319060240160206040518083038186803b158015613ee357600080fd5b505afa158015613ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1b91906153ee565b611fd09190615b3b565b6040516001600160a01b0380851660248301528316604482015260648101829052613f909085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614ac5565b50505050565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b179052905160009182916001600160a01b03851691613fd99161566e565b600060405180830381855afa9150503d8060008114614014576040519150601f19603f3d011682016040523d82523d6000602084013e614019565b606091505b5091505080806020019051810190611c829190615523565b600060088260ff1611156140625761404a600883615b52565b61405590600a615a71565b61405f9084615a0e565b92505b5090919050565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810191909152604051806102000160405280866000015181526020018461ffff1681526020018581526020018660e00151815260200186610100015161ffff1681526020018660200151815260200186604001516001600160401b0316815260200186606001516001600160401b0316815260200186608001516001600160401b031681526020018660a001516001600160401b031681526020018660c001516001600160401b03168152602001866101200151815260200186610140015160ff1681526020018360ff16815260200186610160015160ff1681526020018661018001518152509050949350505050565b6060816000015182602001518360400151846060015185608001518660a001518760c001518860e001518961010001518a61012001518b61014001518c61016001518d61018001516040516020016142399d9c9b9a9998979695949392919061558d565b60408051601f19818403018152908290526101a08401516101c08501516101e08601516001600160f81b031960f893841b811660208701529190921b16602184015260228301529150613c399060420160408051601f198184030181529190528290614b9a565b604080517fc1e8426d70a8367e3d86a5f2e0bdec2344bd6a74f82bfdf50cdfdc08a36500f160208201529081018490526060810183905260808101829052600090819060a0016040516020818303038152906040529050611fd0600454828051906020012060405161190160f01b8152600281019290925260228201526042902090565b602081015160009081906001600160a01b031661434357506012614353565b6143508360200151613f96565b90505b60808301516000906001600160a01b031615801590614378575060a084015160ff1615155b156143a0576127108460a0015160ff16866143939190615b1c565b61439d9190615a0e565b90505b60008460c0015160ff166000146143d4576127108560c0015160ff16876143c79190615b1c565b6143d19190615a0e565b90505b806143df8388615b3b565b6143e99190615b3b565b9350600061440486604001516001600160401b0316856149ce565b9050808510156144275760405163162908e360e11b815260040160405180910390fd5b60208601516001600160a01b03166145c9578560e00151801561444a5750863414155b806144fc57508560e001511580156144fc57507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b1580156144b657600080fd5b505afa1580156144ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144ee91906153ee565b6144f890886159d4565b3414155b1561451a576040516317dfbee160e01b815260040160405180910390fd5b821561452e5761452e8660800151846149fc565b81156145b857600154604080516331056e5760e21b815290516145b8926001600160a01b03169163c415b95c916004808301926020929190829003018186803b15801561457a57600080fd5b505afa15801561458e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145b29190614fdf565b836149fc565b85516145c490866149fc565b6148a3565b60608601516001600160401b0316156146eb5760006145f687606001516001600160401b031660126149ce565b90508660e0015180156146095750803414155b806146bb57508660e001511580156146bb57507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b15801561467557600080fd5b505afa158015614689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146ad91906153ee565b6146b790826159d4565b3414155b156146d957604051636e51edcd60e11b815260040160405180910390fd5b86516146e590826149fc565b506147c1565b8560e0015180156146fb57503415155b806147a357508560e001511580156147a357507f00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b6001600160a01b0316631a90a2196040518163ffffffff1660e01b815260040160206040518083038186803b15801561476757600080fd5b505afa15801561477b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061479f91906153ee565b3414155b156147c1576040516317dfbee160e01b815260040160405180910390fd5b82156147ed576147ed86608001518488602001516001600160a01b0316614a959092919063ffffffff16565b811561488657600154604080516331056e5760e21b81529051614886926001600160a01b03169163c415b95c916004808301926020929190829003018186803b15801561483957600080fd5b505afa15801561484d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148719190614fdf565b60208801516001600160a01b03169084614a95565b855160208701516148a3916001600160a01b039091169087614a95565b5050505092915050565b60608160000151826020015183604001518460600151856080015160405160200161491695949392919060f89590951b6001600160f81b0319168552600185019390935260f09190911b6001600160f01b03191660218401526023830152604382015260630190565b6040516020818303038152906040529050919050565b6060816000015182602001518360400151846060015185608001518660a001518760c001518860e0015160405160200161491698979695949392919060f89890981b6001600160f81b0319168852600188019690965260f09490941b6001600160f01b031916602187015260238601929092526043850152606384015260c090811b6001600160c01b0319908116608385015291901b16608b82015260930190565b600060088260ff161115614062576149e7600883615b52565b6149f290600a615a71565b61405f9084615b1c565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114614a49576040519150601f19603f3d011682016040523d82523d6000602084013e614a4e565b606091505b5050905080614a905760405162461bcd60e51b815260206004820152600e60248201526d1c185e5b595b9d0819985a5b195960921b6044820152606401610871565b505050565b6040516001600160a01b038316602482015260448101829052614a9090849063a9059cbb60e01b90606401613f59565b6000614b1a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614c179092919063ffffffff16565b9050805160001480614b3b575080806020019051810190614b3b91906151a2565b614a905760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610871565b6060806040519050835180825260208201818101602087015b81831015614bcb578051835260209283019201614bb3565b50855184518101855292509050808201602086015b81831015614bf8578051835260209283019201614be0565b508651929092011591909101601f01601f191660405250905092915050565b6060611a43848460008585600080866001600160a01b03168587604051614c3e919061566e565b60006040518083038185875af1925050503d8060008114614c7b576040519150601f19603f3d011682016040523d82523d6000602084013e614c80565b606091505b50915091506111a68783838760608315614cf8578251614cf1576001600160a01b0385163b614cf15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610871565b5081611a43565b611a438383815115614d0d5781518083602001fd5b8060405162461bcd60e51b81526004016108719190615726565b600082601f830112614d37578081fd5b81516020614d4c614d478361598a565b61595a565b80838252828201915082860187848660071b8901011115614d6b578586fd5b855b85811015614dd257608080838b031215614d85578788fd5b614d8d6158ec565b835181528684015187820152604080850151614da881615c30565b90820152606084810151614dbb81615c30565b908201528552938501939190910190600101614d6d565b5090979650505050505050565b80516131df81615bfd565b600082601f830112614dfa578081fd5b8135614e08614d47826159ad565b818152846020838601011115614e1c578283fd5b816020850160208301379081016020019190915292915050565b600082601f830112614e46578081fd5b8151614e54614d47826159ad565b818152846020838601011115614e68578283fd5b611a43826020830160208701615b75565b60006101a08284031215614e8b578081fd5b614e93615914565b90508135815260208201356020820152614eaf60408301614f97565b6040820152614ec060608301614f97565b6060820152614ed160808301614f97565b6080820152614ee260a08301614f97565b60a0820152614ef360c08301614f97565b60c082015260e082013560e0820152610100614f10818401614f6d565b908201526101208281013590820152610140614f2d818401614fad565b90820152610160614f3f838201614fad565b818301525061018080830135818301525092915050565b600060a08284031215614f67578081fd5b50919050565b80356131df81615c0b565b80516131df81615c0b565b805163ffffffff811681146131df57600080fd5b80356131df81615c1b565b80516131df81615c1b565b80356131df81615c30565b80516131df81615c30565b600060208284031215614fd4578081fd5b8135611c8281615be8565b600060208284031215614ff0578081fd5b8151611c8281615be8565b60008060006101e08486031215615010578182fd5b833561501b81615be8565b9250602084013591506150318560408601614e79565b90509250925092565b60008060008060008060006102c0888a031215615055578485fd5b873561506081615be8565b9650602088013595506150768960408a01614e79565b94506101e088013593506102008801356001600160401b038082111561509a578485fd5b818a0191508a601f8301126150ad578485fd5b8135818111156150bb578586fd5b8b60208285010111156150cc578586fd5b6020830195508094505050506150e6896102208a01614f56565b905092959891949750929550565b60006020808385031215615106578182fd5b82356001600160401b0381111561511b578283fd5b8301601f8101851361512b578283fd5b8035615139614d478261598a565b80828252848201915084840188868560051b8701011115615158578687fd5b8694505b8385101561517a57803583526001949094019391850191850161515c565b50979650505050505050565b600060208284031215615197578081fd5b8135611c8281615bfd565b6000602082840312156151b3578081fd5b8151611c8281615bfd565b6000602082840312156151cf578081fd5b5035919050565b600080600080600061022086880312156151ee578283fd5b853594506151ff8760208801614e79565b93506101c086013561521081615c0b565b92506101e086013561522181615c30565b94979396509194610200013592915050565b600060208284031215615244578081fd5b81356001600160401b03811115615259578182fd5b611a4384828501614dea565b60006101a08284031215615277578081fd5b611c828383614e79565b600080600060608486031215615295578081fd5b83516001600160401b03808211156152ab578283fd5b9085019061016082880312156152bf578283fd5b6152c7615937565b6152d083614fb8565b81526152de60208401614f83565b60208201526152ef60408401614f83565b604082015261530060608401614f78565b60608201526080830151608082015261531b60a08401614fa2565b60a082015261532c60c08401614fb8565b60c082015260e083015182811115615342578485fd5b61534e89828601614e36565b60e083015250610100615362818501614f83565b908201526101208381015183811115615379578586fd5b6153858a828701614d27565b9183019190915250610140838101519082015294506153a660208701614ddf565b935060408601519150808211156153bb578283fd5b506153c886828701614e36565b9150509250925092565b6000602082840312156153e3578081fd5b8151611c8281615c0b565b6000602082840312156153ff578081fd5b5051919050565b600080600080600080600080610280898b031215615422578182fd5b8835975060208901359650604089013561543b81615c0b565b955060608901359450608089013561545281615c30565b93506154618a60a08b01614e79565b9250610240890135915061026089013561547a81615bfd565b809150509295985092959890939650565b600080600080608085870312156154a0578182fd5b8435935060208501356001600160401b038111156154bc578283fd5b6154c887828801614dea565b9350506040850135915060608501356154e081615bfd565b939692955090935050565b6000602082840312156154fc578081fd5b8151611c8281615c1b565b600060208284031215615518578081fd5b8135611c8281615c30565b600060208284031215615534578081fd5b8151611c8281615c30565b60008151808452615557816020860160208601615b75565b601f01601f19169290920160200192915050565b6005811061558957634e487b7160e01b600052602160045260246000fd5b9052565b8d8152600061ffff60f01b808f60f01b1660208401528d60228401528c6042840152808c60f01b166062840152508960648301526001600160401b0360c01b8960c01b1660848301526155ef608c83018960c01b6001600160c01b0319169052565b615608609483018860c01b6001600160c01b0319169052565b615621609c83018760c01b6001600160c01b0319169052565b61563a60a483018660c01b6001600160c01b0319169052565b8360ac83015261565960cc83018460f81b6001600160f81b0319169052565b5060cd019d9c50505050505050505050505050565b60008251615680818460208701615b75565b9190910192915050565b6000835161569c818460208801615b75565b8351908301906156b0818360208801615b75565b01949350505050565b602080825282518282018190526000919060409081850190868401855b828110156157195781516156eb85825161556b565b808701516001600160401b03168588015285015161ffff1685850152606090930192908501906001016156d6565b5091979650505050505050565b602081526000611c82602083018461553f565b60608152600061574c606083018661553f565b6020830194909452506001600160a01b0391909116604090910152919050565b6060810161577a828661556b565b6001600160401b038416602083015261ffff83166040830152949350505050565b63ffffffff841681526060602082015260006157ba606083018561553f565b905060ff83166040830152949350505050565b815160ff1681526101c081016020830151602083015260408301516157f8604084018261ffff169052565b50606083015160608301526080830151608083015260a083015160a083015260c083015161583160c08401826001600160401b03169052565b5060e083015161584c60e08401826001600160401b03169052565b50610100838101516001600160401b03169083015261012080840151908301526101408084015160ff9081169184019190915261016080850151909116908301526101808084015161ffff16908301526101a092830151929091019190915290565b6001600160401b039590951685526001600160a01b03939093166020850152604084019190915261ffff16606083015260ff16608082015260a00190565b604051608081016001600160401b038111828210171561590e5761590e615bd2565b60405290565b6040516101a081016001600160401b038111828210171561590e5761590e615bd2565b60405161016081016001600160401b038111828210171561590e5761590e615bd2565b604051601f8201601f191681016001600160401b038111828210171561598257615982615bd2565b604052919050565b60006001600160401b038211156159a3576159a3615bd2565b5060051b60200190565b60006001600160401b038211156159c6576159c6615bd2565b50601f01601f191660200190565b600082198211156159e7576159e7615bbc565b500190565b60006001600160401b038083168185168083038211156156b0576156b0615bbc565b600082615a2957634e487b7160e01b81526012600452602481fd5b500490565b600181815b80851115615a69578160001904821115615a4f57615a4f615bbc565b80851615615a5c57918102915b93841c9390800290615a33565b509250929050565b6000611c8260ff841683600082615a8a57506001613c39565b81615a9757506000613c39565b8160018114615aad5760028114615ab757615ad3565b6001915050613c39565b60ff841115615ac857615ac8615bbc565b50506001821b613c39565b5060208310610133831016604e8410600b8410161715615af6575081810a613c39565b615b008383615a2e565b8060001904821115615b1457615b14615bbc565b029392505050565b6000816000190483118215151615615b3657615b36615bbc565b500290565b600082821015615b4d57615b4d615bbc565b500390565b600060ff821660ff841680821015615b6c57615b6c615bbc565b90039392505050565b60005b83811015615b90578181015183820152602001615b78565b83811115613f905750506000910152565b6000600019821415615bb557615bb5615bbc565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146109d657600080fd5b80151581146109d657600080fd5b61ffff811681146109d657600080fd5b6001600160401b03811681146109d657600080fd5b60ff811681146109d657600080fdfea2646970667358221220df2c4fbf3c3344be40e083946a8a8f429e6dd694c3b7b5c77d1fa2fbd798904864736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b000000000000000000000000f93191d350117723dbeda5484a3b0996d285cecf000000000000000000000000000000000000000000000000000000000000000134cdc6b2623f36d60ae820e95b60f764e81ec2cd3b57b77e3f8e25ddd43ac37323b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc0690000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _wormhole (address): 0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B
Arg [1] : _feeManager (address): 0xF93191d350117723DBEda5484a3b0996d285CECF
Arg [2] : _auctionChainId (uint16): 1
Arg [3] : _auctionAddr (bytes32): 0x34cdc6b2623f36d60ae820e95b60f764e81ec2cd3b57b77e3f8e25ddd43ac373
Arg [4] : _solanaEmitter (bytes32): 0x23b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc069
Arg [5] : _consistencyLevel (uint8): 1
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000098f3c9e6e3face36baad05fe09d375ef1464288b
Arg [1] : 000000000000000000000000f93191d350117723dbeda5484a3b0996d285cecf
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 34cdc6b2623f36d60ae820e95b60f764e81ec2cd3b57b77e3f8e25ddd43ac373
Arg [4] : 23b1261d67d23099d43d0ad07a71b81d1e3c8c1d95da4c609b543ce7143fc069
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 25.35% | $3,283.59 | 20.2586 | $66,520.96 |
ETH | 20.05% | $1 | 52,575.5714 | $52,628.15 | |
BASE | 11.91% | $1 | 31,234.8937 | $31,266.13 | |
BASE | 6.21% | $3,280.09 | 4.9689 | $16,298.57 | |
ARB | 15.86% | $1 | 41,583.6309 | $41,625.21 | |
ARB | 1.57% | $3,280.48 | 1.2564 | $4,121.67 | |
OP | 6.41% | $1 | 16,798.1245 | $16,814.92 | |
OP | 1.47% | $3,281.26 | 1.1755 | $3,857.23 | |
AVAX | 5.42% | $1 | 14,205.044 | $14,219.25 | |
POL | 5.16% | $1 | 13,524.9132 | $13,538.44 | |
BSC | 0.58% | $0.999776 | 1,525.3617 | $1,525.02 | |
BSC | 0.02% | $660.24 | 0.06 | $39.61 |
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.